2022年2月28日月曜日

Python の TypeGuard 超入門

Python の TypeGuard 超入門

概要

前回 は型ヒントを使って事前に型チェックする方法を紹介しました

今回は TypeGuard を紹介します
簡単に言えば型をチェックする関数を独自で定義することができる機能です

環境

  • macOS 11.6.4
  • Python 3.10.2

サンプルコード

from dataclasses import dataclass
from typing import TypeGuard


@dataclass
class User():
    name: str
    age: int


def is_user(user: User) -> TypeGuard[User]:
    if isinstance(user, User):
        return True
    return False


def print_user(user: User):
    if is_user(user):
        print(user.name)
        print(user.age)
    else:
        print("The argument type must be the User class.")


if __name__ == '__main__':
    user = User("hawk", 10)
    print_user(user)
    print_user("hawk")

解説

TypeGuard を使っているのは is_user 関数です
戻り値のアノテーションを TypeGuard[User] にし戻り値を boolean にすることで指定の引数が User クラスかどうかを判定する独自の TypeGuard 関数であることを明示しています

あとは型チェックしたい箇所 (print_user) で is_user を呼び出します

実際にこのコードを実行するとエラーなく終了してしまいますがこのあと紹介する型チェックツールを使うことで事前に型エラーを検知することができるようになります

型チェック

過去の記事では mypy というチェックツールを紹介しました
今回は pyright を使ってみました
mypy でも同じように型チェックは可能です

pyright というツールがあるのでこれを使って型チェックしてみます

  • pip install pyright
  • pyright app.py
No configuration file found.
No pyproject.toml file found.
stubPath /Users/hawk/Documents/work/try_python/typings is not a valid directory.
Assuming Python platform Darwin
Searching for source files
Found 1 source file
/Users/hawk/Documents/work/try_python/app.py
  /Users/hawk/Documents/work/try_python/app.py:28:16 - error: Argument of type "Literal['hawk']" cannot be assigned to parameter "user" of type "User" in function "print_user"
    "Literal['hawk']" is incompatible with "User" (reportGeneralTypeIssues)
1 error, 0 warnings, 0 informations 
Completed in 0.779sec

hawk という文字列は User クラスではないというエラーが表示されています
こんな感じで事前チェックでは型が違うよという警告がちゃんと表示されます

最後に

Typing を使うと事前に型チェックすることが可能になるので関数に意図しないオブジェクトを渡すことを防ぐことができます
便利な機能ではありますがアノテーションや NewType ヘルパーを使う必要が出てくるのでコードは増えがちです

そもそも型あり言語を使ったほうがいいような気もしますが動的型付けとハイブリットで使いたい場合にはいいのかもしれません

また実際に実行しただけだとエラーにはならないので Typing を使う場合には IDE や mypy のように CI などで事前チェックするような機構が必要になるかなと思います

参考サイト

2022年2月24日木曜日

emacs の completion-at-point のショートカットキー

emacs の completion-at-point のショートカットキー

いつも忘れるのでメモ

環境

  • macOS 11.6.3
  • emacs 27.2

ショートカット

Alt + TAB

or

Ctrl+Alt+i

2022年2月23日水曜日

Unable to process request - PLA Update available

Unable to process request - PLA Update available

概要

Xcode で実機ビルドしようとしたらタイトルのエラーが出ました
対処方法を紹介します

環境

  • macOS 11.6.2
  • Xcode 13.2.1

PLA に同意する

https://developer.apple.com/account/#!/overview/ から同意すれば OK

repair する

Xcode の「Signing & Capabilities」から repair すれば OK です

2022年2月22日火曜日

macOS の Audacity に ffmpeg ライブラリを追加する方法

macOS の Audacity に ffmpeg ライブラリを追加する方法

概要

mp4 や m4a を取り込む際に ffmpeg が必要になります
mac に ffmpeg ライブラリをインストールして Audacity に設定する方法を紹介します

環境

  • macOS 11.6.3
  • Audacity 3.1.3
  • ffmpeg 55

ffmpeg ライブラリのダウンロード

https://lame.buanzo.org/#lameosx64bitdl ここからダウンロードします
macOS 版の ffmpeg ライブラリをダウンロードしましょう
ファイル名は「ffmpeg_64bit_osx.pkg」になります

ffmpeg ライブラリのインストール

ダウンロードした dmg をクリックしてインストールすれば OK です
すべてデフォルトの設定のままインストールしましょう

Audacity の設定

環境設定 -> ライブラリ-> ffmpegライブラリ -> 場所を指定 -> はい

で自動で先程 ffmpeg ライブラリをインストールしたパスを設定してくれます

動作確認

あとは mp4 など取り込んで問題なければ OK です

最後に

Homebrew でインストールした ffmpeg でもいけるのだろうか、自分が調べた感じだと dylib が足りないからダメな気もするが

2022年2月21日月曜日

Gitlab CI の docker executor でタイムゾーンを設定する方法

Gitlab CI の docker executor でタイムゾーンを設定する方法

概要

基本は使用するイメージのタイムゾーンの設定方法に従えば OK です
今回は Python の公式イメージを使ったタイムゾーンの設定方法を紹介します

環境

  • Gitlab 14.3.3
  • Python 3.10.2

サンプル .gitlab-ci.yml

TZ 変数を variables で設定してあげます

image: python:3.10.2-buster

stages:
  - test

test:
  stage: test
  variables:
    TZ: Asia/Tokyo
  script:
    - python -c 'import datetime;print(datetime.datetime.now())'

これで結果を確認すると時刻がちゃんと JST で表示されるのが確認できると思います

2022年2月18日金曜日

Mac に VSCode をインストールして solargraph の設定をしてみた

Mac に VSCode をインストールして solargraph の設定をしてみた

概要

タイトルの通りです
まずは solargraph をインストールして Ruby の開発環境を構築しました

環境

  • macOS 11.6.3
  • vscode 1.64.2

インストール

  • brew install visual-studio-code --cask

初期設定

  • テーマの設定
  • 設定のクラウド同期の設定
  • ショートカットを有効にするかの設定
  • 言語の補完とシンタックスハイライトの設定

1つ目のプロジェクトを開いたあとでプロジェクトの製作者を信頼するかどうかのダイアログが出るので必要に応じて信頼してください

プロジェクトを開くと Welcome ページが表示されます
Welcome ページを毎回表示しない場合はチェックボックをオフにしてください

Solargraph の設定

Code -> Preferences -> Extensions

で「solargraph」と検索し Install します

プロジェクトを開いたらコマンドパレット (Cmd+Shift+p) で「Build new gem documentation」で gem の補完も有効にします

バックグラウンドで yard プロセスが動作し yardoc を生成しているのがわかります

solargraph 自体をインストールしていない場合は

  • gem install solargraph

Gemfile 配下で solargraph をインストールした場合は

同じことをプロジェクト配下で実施する感じです
プロジェクトごとにやらないとダメです

  • mkdir .vscode
  • vim .vscode/settings.json
{
  "solargraph.useBundler": true,
  "solargraph.bundlerPath": "/usr/local/lib/ruby/gems/3.0.0/bin/bundle"
}
  • bundle exec yard gems

solargraph.useBundler: true にして bundler コマンドが見つからないというエラーが出る場合は solargraph.bundlerPath を設定してください

最後に

bundler 配下が面倒という場合はグローバルな gem にインストールして yardoc を生成すれば OK です

参考サイト

2022年2月17日木曜日

pylsp で pipenv 配下にインストールしたモジュールの補完がされない場合の対処方法

pylsp で pipenv 配下にインストールしたモジュールの補完がされない場合の対処方法

概要

過去に emacs+pylsp の連携方法を紹介しました
今回は pipenv を使って pypi からインストールしたモジュールの補完を pylsp を使って行う方法を紹介します

環境

  • macOS 11.6.3
  • Python 3.9.10

pylsp を無理やり上書きする

グローバルにインストールした pylsp を pipenv 配下にインストールした pylsp で無理やり上書きします
具体的には以下のようにシンボリックリンクを貼れば OK です

  • cd /path/to/project
  • ln -sf $(pipenv --venv)/bin/pylsp /usr/local/bin/pylsp

ちなみに上記は pylsp のパスが上記の場合になります

$ which pylsp
/usr/local/bin/pylsp

ただこれの場合は1プロジェクトにしか対応できないのとプロジェクトを切り替えるたびにシンボリックリンクも切り替えなければいけないので大変です

pylsp 用に一つプロジェクトを作成してそこに補完してほしいモジュールをどんどんインストールするのもありかなと思います

pyenv 配下のプロジェクトの場合は別のファイルを上書きする

pyenv 配下のプロジェクトの場合 pylsp のスクリプトは一度別のスクリプトのスクリプトを経由するので which で表示されるスクリプトではなく実体のスクリプトを上書きしましょう

# which pylsp
/root/.pyenv/shims/pylsp

# pyenv version
3.10.1 (set by /root/.pyenv/version)

# ls /root/.pyenv/versions/3.10.1/bin/pylsp
/root/.pyenv/versions/3.10.1/bin/pylsp

# ln -sf $(pipenv --venv)/bin/pylsp /root/.pyenv/versions/3.10.1/bin/pylsp

グローバルな pip にインストールする

python-lsp-server が起動している pip 環境と同じ環境にモジュールをインストールします

これでも対応可能ですが補完が必要なモジュールがあるたびにグローバルな環境にモジュールをインストールする必要があります

また pipenv の環境間で同じモジュールのバージョン違いがある場合は補完候補が間違うことがあります

pyls_jsonrpc.endpoint - Received cancel notification for unknown message id

pylsp::stderr バッファーになぜかこれが出力されるケースがありました
これが出力されていると補完時に「No matches」と表示されて補完がうまく動作しません

原因は不明です

emacs の lsp-mode の対応に期待する

pylsp の設定で pipenv 配下の pylsp を実行するような設定が出てくるのを待ちましょう

もしくは自分で修正しましょう

最後に

emacs の lsp-mode の solargraph には bundler 配下にインストールした solargraph を使用するというオプションがあるのですが pylsp にはないので今回のような少しトリッキーな対応が必要になります

参考サイト

2022年2月16日水曜日

Python の marshmallow を使って JSON からオブジェクトにデシリアライズする方法

Python の marshmallow を使って JSON からオブジェクトにデシリアライズする方法

概要

例えば JSON としてレスポンスを取得してその結果を Python のオブジェクトとしてデシリアライズしたい場合があると思います

そんな場合は marshmallow を使うと簡単に実現できます

環境

  • macOS 11.6.3
  • Python 3.9.10
  • marshmallow

準備

  • pipenv install marshmallow

サンプルコード

ポイントを後述で紹介します
resp が変換対象の JSON ですがこの JSON の構造に合わせてスキーマクラスや変換用のクラスの定義も変換する必要があります

from dataclasses import dataclass
from marshmallow import Schema, fields, post_load


@dataclass
class User():

    name: str
    age: int


@dataclass
class Users():

    users: list


class UserSchema(Schema):

    name = fields.Str()
    age = fields.Int()

    @post_load
    def make_user(self, data, **kwargs):
        return User(**data)


class UsersSchema(Schema):

    users = fields.List(fields.Nested(UserSchema))

    @post_load
    def make_users(self, data, **kwargs):
        return Users(**data)


if __name__ == "__main__":
    resp = {
        "users": [
            {
                "name": "hawk",
                "age": 10
            },
            {
                "name": "snowlog",
                "age": 20
            }
        ]
    }
    schema = UsersSchema()
    users = schema.load(resp)
    for user in users.users:
        print(user.name)
        print(user.age)

ポイント

marshmallow の Schema クラスを継承したスキーマを作成します
スキーマは load や dump を使うことでシリアライズやデシリアライズができるようになります
今回はデシリアライズするので load を使って JSON -> Python オブジェクトの変換を行います

変換先の Python オブジェクトのクラスは普通に Python のクラスと定義します
今回は dataclass を使っていますが dataclass じゃなくて OK です

最大のポイントはスキーマ側で post_load を使ってデシリアライズ時に data を定義したクラスで変換してから return する点です
これをしないと JSON -> dict という感じで Python オブジェクトに変換されず dict として受け取れてしまうので注意が必要です
逆に dict にしたい場合は post_load は不要です

最後に

Python のシリアライズと言えば marshmallow なので覚えておきましょう
基本的な使い方さえわからばデータベースからの変換やRedisからの変換も簡単にできると思います

2022年2月15日火曜日

Swift でアプリのバージョン情報を取得する方法

Swift でアプリのバージョン情報を取得する方法

概要

アプリ自体にバージョンを記載したいときに使えます
Xcode で設定しているバージョンを取得します

環境

  • macOS 11.6.2
  • Xcode 13.2.1

サンプルコード

CFBundleShortVersionString を取得します

let appVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String

2022年2月14日月曜日

macOS クリーンインストールメモ

macOS クリーンインストールメモ

概要

macOS のクリーンインストールを行ったのでかかった時間などをメモしておきます

環境

  • macOS 11.6.2

かかった時間

5時間

  • ディスクの削除 -> 20分
  • macOS の再インストール -> 1時間
  • macOS 初回セットアップ -> 10分
  • 起動後の各種インストールやセットアップ -> 3時間30分

インストール後のセットアップ作業は人によるので最短は1時間ほどで完了します

手順

こちらを参考に進めました
ディスクのクリーンアップをするのを忘れないようにしましょう

ローカルにあるデータは退避するなりする

クラウドストレージなり git なりを使って退避しておきます
クラウドに置きたくないデータや大きいデータは外付けストレージなどに保存しておきましょう
クリーンアップ後はデータがすべて消えるので注意しましょう

ディスクにデータが残っている場合は再インストール後に削除すること

再インストール時にディスクをクリーンアップしてもなぜか OS 再インストール後に前のデータのが残っていることがあります

「 コンテナ内の他のボリューム」という領域がそれに当たります

ディスクユーティリティを開くと確かに同じボリュームが2つあります
前のボリュームは「disk1s1」という名前のボリュームになります
これを一度アンマウントしてから消去すれば O K です

削除が開始されるとどんどん容量が減っていくのが確認できると思います

VirtualBox をインストールしたらカーネルエクステンションを有効にして再起動する

最近の VirtualBox のインストーラを使っていると必然的にやることになるので大丈夫だと思います

homebrew でインストールした場合はパスワードが聞かれそのあとで以下のダイアログで許可する必要があります

無駄なバックグラウンドプロセスがなくなるのでファンが回りにくくなる

CPU をよく使うプロセスを起動してもファンがフル回転しなくなりました
これもクリーンインストールの嬉しい点かもしれません

参考サイト

2022年2月11日金曜日

(Python) macOS に cryptography をインストールする方法

(Python) macOS に cryptography をインストールする方法

概要

過去に似たような記事を紹介しました

cryptography 自体を先にインストールすることで解決するケースが多いのでそれだけインストールする方法を紹介します

環境

  • macOS 11.6.3
  • Python 3.10.2

インストール方法

  • brew install openssl@1.1 rust
  • env LDFLAGS="-L$(brew --prefix openssl@1.1)/lib" CFLAGS="-I$(brew --prefix openssl@1.1)/include" pipenv install cryptography

参考サイト

2022年2月10日木曜日

Mac で e-Tax を使って確定申告してみる

Mac で e-Tax を使って確定申告してみる

概要

会社の年末調整で申告できないものは自分で確定申告する必要があります
今回は FX の取引があったのでそれを iPhone を使って申告する方法を紹介します

ポイントは「確定申告書等作成コーナー」から全てはスタートする点とマイナポータルが必要な点かなと思います
あとは源泉徴収票や年間取引報告書、寄附金控除に関する証明書が実は提出不要な点もポイントかなと思います

環境、準備するもの

  • 源泉徴収票 (数字を確認するのに必須、ただし提出は不要)
  • 年間取引報告書 (数字を確認するのに必須、ただし提出は不要)
  • 寄附金控除に関する証明書 (任意)
    • ふるさと納税している場合は必須、ただし提出は不要
  • マイナンバーカード
  • iPhoneXR
    • マイナポータルインストール済み
  • macOS 11.6.3
    • Safari

事前準備

  • iPhone のデフォルトのブラウザをSafariにする

確定申告書等作成コーナー申告書を作成する

以下UIに沿って流れを紹介します
スクリーンショットはないので文章を頼りに進める感じです

  1. 作成コーナーをSafariで開く
  2. 作成開始
  3. マイナンバーカード方式 (2次元バーコード)
  4. 令和3年分の申告書等の作成 -> 所得税
  5. 連携しないで申告書等を作成する -> 次へ進む
  6. 利用規約に同意して次へ
  7. iPhone のマイナポータルアプリで2次元バーコードを読み取りマイナンバーカードを使ってログインする
  8. ログインに成功すると Mac の Safari に戻ってくる
  9. 「e-Taxのご利用のための事前準備が終了しました」が表示されたら -> 申告書を作成する
  10. 次へ進む (ここから古いUIになる)
  11. 申告される方の生年月日 -> 入力
  12. 作成する確定申告書の提出方法 -> e-Taxにより税務署に提出する。
  13. 給与以外に申告する収入はありますか? -> いいえ
  14. お持ちの源泉徴収票は1枚のみですか? -> はい
  15. 勤務先で年末調整が済んでいますか? -> はい
  16. 以下のいずれかの控除を受けますか? -> はい
  17. 以下の控除の他に、社会保険料控除や扶養控除などの控除を追加して確定申告書を作成したり、年末調整の内容を変更しますか? -> はい
  18. 税務署から予定納税額の通知を受けていますか? -> いいえ
  19. 次へ進む
  20. 給与所得 -> 入力する -> 書面で交付された年末調整済みの源泉徴収票の入力 -> 入力する -> 源泉徴収票を元に画面に沿って必要な数字を入力する
  21. 扶養控除の入力 -> 次へ進む
  22. 先物取引に係る雑所得等 -> 入力する
    • 所得区分 -> 雑所得用
    • 種類 -> 外国為替証拠金取引
    • 決済の方法 -> 差金決済
    • 差金等決済に係る利益又は損失の額 -> 年間取引報告書に記載の金額を入力
  23. 入力終了(次へ)
  24. 寄附金控除 -> 入力する (これはふるさと納税のワンストップ特例制度をした場合に入力)
    • ふるさと納税したサイトから寄附金控除に関する証明書を発行してもらうと XML データももらえてそれを取り込むだけなので証明書発行後にここは記入したほうがいいかも
  25. 入力終了(次へ)
  26. 税額控除・その他の項目の入力 -> 入力終了(次へ)
  27. 計算結果確認 -> 入力終了(次へ)
  28. 住民税・事業税に関する事項 -> 扶養家族がいる場合は記載
  29. 還付金額について -> あれば必要事項を入力
  30. 申告書を提出する税務署 -> 整理番号, 提出年月日は空欄
  31. このあたりで「入力データを一時保存する」をして .data ファイルをダウンロードしておく
  32. 次へ進む
  33. マイナンバーの入力 -> ある場合は入れる -> 次へ進む
  34. 送信前の申告内容確認 -> 帳票表示・印刷 -> 問題なければ次へ進む
  35. 送信準備 -> 基本全部いいえ
  36. マイナンバーカード認証方法の変更 -> 2次元バーコードリーダ
    • ここだけ認証が署名用電子証明書のパスワードなので注意
    • また2回2次元バーコードを読み込んでログインする
  37. 無事ログインできれば確定申告書データの送信 -> 送信する
  38. 送信結果の確認 -> 送信票等印刷へ進む
  39. 送信票兼送付書等印刷 -> 帳票表示・印刷
  40. 次へ進む
  41. 最後にまた申請データの .data ファイルがダウンロードできるのでダウンロードしておきます
  42. 思うことがあればアンケートに回答しましょう

これで以上です
長いです

申請内容確認は

受付システムという別システムがあるのでこれを使えば確認できます

利用者識別番号とパスワードで受付システムを使いたい場合は最後に記載している利用者識別番号取得までの流れを参考にパスワードを設定すればマイナンバーカードなしでログインできます

最後に

e-Tax という言葉に踊らされていろいろ調べましたが結局はシートを作成して提出する感じです
よく FX 関連の確定申告の記事を見ると紙を印刷して紙に書く方法が紹介されていますがそんなことはしなくても全部ネットからできます

今回は FX の取引報告だけでしたがそれ以外にも年末調整で申告できないものはこんな感じで申告します
源泉徴収票が基本あると思うのでそれは「給与所得」に入力しそれ以外を記入する感じになるかなと思います

なお流れは 2022/02/09 時点での作成コーナーのUIを元に記述しているのであとからUIが変わった場合などは文言などが違う可能性があるので注意してください

参考サイト

おまけ: 利用者識別番号取得までの流れ

よくわからないのですが e-Taxソフト(SP版) を使って利用者識別番号を取得する流れは以下のとおりです

  1. iPhone で Chrome を開いて「e-Taxソフト(SP版)のログイン画面」にアクセスする
  2. マイナンバーカードの読み取りへを選択
  3. マイナンバーカードを読み取ってログインする
    • Safariに戻る場合は必ず左上のディープリンクから戻ること
  4. 初めてe-Taxをご利用される方はこちら
  5. マイナンバーカード情報の確認へ
  6. マイナンバーカードから読み取る -> マイナンバーカードの読み取り
    • Safariに戻る場合は必ず左上のディープリンクから戻ること
  7. 次へ
  8. 利用者情報の入力
    • 基本は入力されているので足りないところだけを入力する
    • メールアドレスは登録してもいいかも
  9. 確認 -> 提出先の税務署を確認してOK
    • いろいろと読んでOK
  10. 送信結果の画面 -> 次へ
  11. 利用者識別番号を確認するためのメールが届くので記載のURLから一度ログインする
  12. 利用者識別番号の通知・確認
  13. 暗証番号の登録・更新へ
  14. 利用者識別番号とパスワードが設定できたらマイナポータルなしでログインできるようになる

2022年2月9日水曜日

Framework not found GoogleMobileAds

Framework not found GoogleMobileAds

概要

ビルド時にバイナリがないと言われてエラーになります
対処方法を紹介します

環境

  • macOS 11.6.2
  • Xcode 13.2.1

ライブラリの再インストール

プロジェクト配下に移動して以下を実行します

  • rm -rf Pods
  • pod install

発生する原因

考えられる原因としては間違ってバイナリを削除してしまった場合です
バイナリのファイルが結構大きくディスクの掃除をしているときに大きいファイルを自動的に削除するようにしていると誤って削除してしまうことがありそうです

2022年2月8日火曜日

Xcode13.2.1 dyld: Symbol not found: ___chkstk_darwin 対応

Xcode13.2.1 dyld: Symbol not found: ___chkstk_darwin 対応

概要

Xcode13.2.1 でビルドしたアプリをiOS12 の実機で動かそうとすると dyld: Symbol not found: ___chkstk_darwin というエラーが発生しアプリがクラッシュします
どうやら Xcode のバグで Xcode13.3 で直っているそうなので試してみました

https://forums.swift.org/t/swift-concurrency-back-deploy-issue/53917/27

環境

  • macOS 11.6.3 -> 12.0.0
  • Xcode 13.2.1

Beta版のダウンロード

https://developer.apple.com/download/ からダウンロードします
DeveloperProgram に入っていないとダウンロードできません

Xcode_13_3_beta.xip というファイルがダウンロードできました
ファイルサイズが 10GB あるので注意してください

Beta版のインストール

ダウンロードした xip ファイルをダブルクリックしましょう
「デジタル署名書を検証中」が長いですがしばらく待ちましょう
そのあとで展開中になりプログレスバーが追われてば完了です

Xcode-beta.app が作成されるので Applications 配下に移動します

ビルドして動作確認

あとはビルドして動作確認すれば OK です

ビルドオプションを付与すれば大丈夫?

公式にもあるようなのでビルドオプションでも回避できるかもしれません

https://developer.apple.com/documentation/xcode-release-notes/xcode-13_2-release-notes https://learn.apptentive.com/knowledge-base/xcode-project-setup-guide/

最後に

Xcode13.3 は macOS12 (Monterey) が必要になります
もし Monterey がない場合は Xcode12 をダウンロードして同じようにインストールしてビルドしましょう

参考サイト

2022年2月7日月曜日

StoryBoard で TableView にセクションを追加する方法

StoryBoard で TableView にセクションを追加する方法

概要

StoryBoard だけでテーブルビューにセクションを追加する方法を紹介します
追加されるセクションを固定セクションになるので動的に値を変更することは想定されていません

環境

  • macOS 11.6.2
  • Xcode 13.2.1

TableViewController を追加して StaticCells を設定する

  1. TableViewController を追加する
  2. TableView を選択し右ペインの三本線アイコンを選択
  3. Content を「Static Cells」に変更する
  4. Sections の数を変更する

これでビューのペインにセクションが追加されます

セクションのヘッダを変更

  1. 追加されたセクションを選択
  2. 三本線アイコンを選択
  3. Header を好きな文字列に変更

最後に

もし動的に値を変更したい場合はコード側でセクションを生成して TableView に追加するようなコードが必要になります

2022年2月4日金曜日

(Kingfisher) No exact matches in call to instance method 'setImage'

(Kingfisher) No exact matches in call to instance method 'setImage'

概要

Kingfisher が 6 -> 7 にバージョンアップしてみたら setImage の互換性がなくなりタイトルのエラーが出たので対応してみました

環境

  • macOS 11.6.2
  • Xcode 13.2.1
  • Kingfisher 7.1.2 (was 6.3.0)

元のコード

completionHandler の返り値を使ってエラーかどうかの判定などを行う感じでした

imageView.kf.setImage(with: url,
    completionHandler: {
        (image, error, cacheType, imageURL) in
        imageView.image = image
})

修正後のコード

completionHandler の帰り値は result のみになっておりこの結果を元に更に成功 or 失敗で分岐させて処理を書くような感じになっています

これまで使っていた image は value.image という感じで参照することができます

imageView.kf.setImage(with: url,
    completionHandler: {
        result in
    switch result {
    case .success(let value):
        imageView.image = value.image
    case .failure(_):
        print("failure")
    }
})

最後に

外部のライブラリを使っているとバージョンアップの際に非互換が発生することがあるのでこういった対応はどうしてもやらないといけなくなります

参考サイト

2022年2月3日木曜日

Python の dataclass 超入門

Python の dataclass 超入門

概要

Python の dataclass を使うと __init__.py を省略することができます
また typing と合わせて宣言ぽくクラスを定義できます
他にも便利な機能があるので軽く紹介します

環境

  • macOS 11.6.2
  • Python 3.10.2

これが

class User():

    def __init__(self, name, age=0):
        self.name = name
        self.age = age

    def show(self):
        print(self.name)
        print(self.age)

user1 = User("hawk")
user1.show()

こうなる

呼び出し方法などは同じように使えます

from dataclasses import dataclass

@dataclass
class User():
    name: str
    age: int = 0

    def show(self):
        print(self.name)
        print(self.age)

user1 = User("hawk")
user1.show()

ここがいいかも

  • __init__.py が省略できる
  • クラスの直後にフィールドの宣言が typing と一緒にあるのでクラスが管理しているフィールドがわかりやすい
  • dataclass アノテーションを付与するのをわすれがち

post_init

暗黙的にコールされる __init__.py の後に自動で呼び出してくれます
dataclass っぽい書き方かなと思います

from dataclasses import dataclass

@dataclass
class User():
    name: str
    age: int = 0

    def __post_init__(self):
        self.country = "Japan"

    def show(self):
        print(self.name)
        print(self.age)
        print(self.country)

user1 = User("hawk")
user1.show()

その他

継承やフィールドの初期化にメソッドをファクトリメソッドを呼び出したりすることもできます

他にもいろいろと機能があるので興味があれば参考使徒にある公式のドキュメントを御覧ください

最後に

Ruby とかも最近は typing やジェネリクスを使った書き方が主流っぽいので Python もこういった書き方主流になっていくのかもしれません

比較的新しめの Python でないと使えないので注意してください

参考サイト

2022年2月2日水曜日

リファクタポイント

リファクタポイント

概要

Ruby や Python などいろいろとリファクタをしていて感じたことをまとめておきます

言語の特性によってできないこともありますが考え方自体はどんな言語でも通用すると思います

とにかくクラスにする

管理する単位がしっかりするのでコードがすっきりする

DSL やデコレータと相性が悪いが可能な限りすべてのコンポーネントをクラス化したほうがいいと思う

重複を排除する

これも単純な話で同じコードを複数の箇所に書かないようにする
メンテナンス性も上がるしコード量も減るのでキレイなコードになる

理想はメソッド名や引数を直したときに一箇所だけ修正できるようなコードになっているのがベスト (なかなかそうはならないが)

IDE などを駆使すればそこまで大変にはならないが可能な限り減らすように意識する

親クラスを使って継承したりファクトリなどを使って同じ処理をまとめることで解消できる

1つのファイルに長いコードを書かない

一つのファイルには一つのクラスだけ定義するようにする

どうしても同じファイルに書きたい場合はそのファイル内でしか使わない内部クラスなどを書く

それ以外は基本的に1クラス1ファイルにしたほうが管理上よくなると思う
1つのファイルに複数のクラスを書くことを許してしまうとせっかくクラス化されているのに巨大なファイルができてしまいメンテナンス性が落ちる

モジュールのインポートなどは1つのファイルの方が楽ではあるがそれよりもいいことはおおいはず

コメントやインデント改行をちょっと工夫するだけでもいい

リファクタリングは端的に言えば第三者が見たときに見やすいコードだと思ってもらえればどんな修正でもリファクタリングになる

なのでコメントを入れて関数やその行の意味を説明してあげるだけでもOK

とにかく自分じゃなくて他人が見てどう思うかを考えてリファクタリングする

リファクタするタイミング

リファクタリングはいつでもできるがタイミングは決めたほうがいい
そうしないと機能開発とのコンフリクトが発生し大変なことになりがち

リファクタリングの粒度は大きめのほうがいいと思う
一気にやるイメージがいい

機能開発を最初にがーっとやってその後でリファクタリングだけ期間を設けてリファクタリングをがーっとやってという感じがいいと思う

意識を切り替えて集中してそれだけやったほうが効率がいいだろうと思う

循環参照を回避

特に Python の話になるがリファクタリング時に循環参照をしないように気をつける

ポイントは __init__.py を肥大化させないことを意識すると循環参照を避けられやすい

あとは Ruby のように循環参照しないような言語を使う

フレームワークの流儀に逆らわない

一番いいのは Rails などのようにディレクトリ構成も決まっている場合
役割ごとに書く場所がだいたい決まっているのでそこまで変なコードにはならない

大変なのは Sinatra や Flask のようにルーティングの部分だけ主に提供するフレームワークの場合
ディレクトリ構成なども柔軟に決められるのでその分ごちゃごちゃになる可能性が高い

このあたりは経験だが基本は MVC を守りつつサードパーティのライブラリやエコシステムなどアプリと切り離せる部分は切り離せるようにするのがいいと思う

設計手法を使う

最近は DDD などあるのでそういった設計手法を開発の前段で使うようにする

ただあくまでも設計手法で実装となると千差万別なので結局路線から外れることもある

ちなみに DDD は学習レベルも高くかなりの経験が問われるのであまりおすすめはしない

リファクタはお金にならない

これを言っては元も子もないがリファクタしたからと言ってサービスの売上にはつながらないのでそれを意識してやる必要がある

ただ開発コストの抑制にはなる

リファクタ自体マッチポンプな感じもするのでそもそもリファクタしなくても済むようなコードにすればいいのだがそうもいかないケースがほとんどだと思うのでやる場合は計画的にやるようにする

終わりはないので気をつけること

リファクタには終わりはないやろうと思えばどこまでもできてしまう

前にも述べたがリファクタはお金にはならないのである程度で区切りをつけて機能開発に切り替えるようにする

最終的には自己満足の世界なのでどこかで妥協しないとずっとリファクタリングだけしている人になってしまう (かもしれない)

2022年2月1日火曜日

Mac への Rust のインストール方法

Mac への Rust のインストール方法

概要

brew は使わないようにしましょうというお話です

環境

  • macOS 11.6.2
  • rustc 1.58.1

インストール方法

  • curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
  • source $HOME/.cargo/env

参考サイト