Upgrade to Pro — share decks privately, control downloads, hide ads and more …

【2020年新人研修資料】ナウでヤングなPython開発入門

 【2020年新人研修資料】ナウでヤングなPython開発入門

【2020年新人研修資料】
ナウでヤングなPython開発入門

Shinichi Takayanagi

January 18, 2021
Tweet

More Decks by Shinichi Takayanagi

Other Decks in Technology

Transcript

  1. 〜2020年 新人研修資料〜
    ナウでヤングなPython開発入門
    株式会社FORCAS 分析チーム
    1

    View full-size slide

  2. 簡単な経歴
    2000 ~ 2006
    2007 ~ 2020
    2020/03 ~ 現在
    ちゃんぽん屋時代の私 現在の私
    慶応大学理学部物理学科 → 名古屋工業大学大学院(情報工学修了)
    いろんなジョブをホッピング(広告/ちゃんぽん屋など)
    株式会社FORCAS(UZABASEグループ) よしなにおじさん‍
    ※寒ブリの里・金沢からフルリモート勤務中
    ※その他、博士(統計科学)・修士(経営工学)なども保有
    研修講師(論理)
    2

    View full-size slide

  3. 目次
    ● この研修は何なの?
    ● 開発の基盤を整えよう
    ○ poetryを使ってみよう
    ○ pytestで単体テストをしよう
    ○ black/autoflake8/isortでフォーマッティングしよう
    ○ mypyでType Hintsを徹底活用しよう
    ○ 退屈なことはGithub Actionsにやらせよう
    ● 開発を進めていこう!
    3

    View full-size slide

  4. この研修は何なの?
    4

    View full-size slide

  5. ● この研修はなんなの?
    ○ FORCAS Product Division Analysis Teamの“標準的”なPython開発を紹介するよ
    ○ 今回はCLI Applicationの開発が題材だよ
    ■ 法人番号を引数に実行すると会社名と住所を返却するような簡易ツール
    ● なんでCLI開発なの?
    ○ 我々の業務としてクローラを書くことが多数あるので
    Web ApplicationというよりもCLIに焦点を
    当てたかったからだよ
    ○ 機械学習モデル用のAPIサーバ開発(fastapi編かな?)はまた今度
    ○ 資料の大部分は”開発基盤をどう整えるか”がメインだからツール自体については深く考えなく
    てもいいよ
    ● 誰に向けて書いているの?
    ○ まだ見ぬ未来の我々の同僚のためだよ
    この研修は何なの?
    5

    View full-size slide

  6. この研修は何なの?
    ● なんで“標準的な”開発なんて定義するの?
    ○ UZABASEの7つのルール「自由主義で行こう」が行き過ぎることが多々あって、保守管
    理不可能なスクリプトが量産された歴史があるからだよ
    ○ 経験ではなく歴史から学んでいるので講師は賢者だよ‍♂
    ○ 不自由さがあってこそ自由が際立つんや!!!
    ● “標準的”ってどのくらい業界の標準なの?
    ○ 正直、よくわからない
    ■ Pythonは良い意味でOSS(Rの一強Tidyverse的概念がない)なので…
    ○ 「ググった感じモダンな奴のみ取り込んでるし大丈夫だろ、ワハハ!」のノリ
    6

    View full-size slide

  7. 開発の基盤を整えよう
    7

    View full-size slide

  8. poetryを使ってみよう
    8

    View full-size slide

  9. poetry
    ● コレはなんなの?
    ○ PythonのPackage Managerだよ
    ○ メリット
    ■ みんなのパッケージのバージョン/開発環境が揃って嬉しいよ
    ○ デメリット
    ■ 使い方を覚えるのが面倒(くらいかな?)
    ■ poetry installした時の依存性解決待ちが結構長い
    ● XXXでいいんじゃないの?
    ○ Dockerでいいんじゃないの?
    ■ Dockerfile内に pip install hoge==1.1.2 みたいなコード乱発はちょっと…
    ■ requirements.txt で管理するのもなくはないがどのみち外側にPackage Manager欲しい
    9

    View full-size slide

  10. poetry
    とりあえず
    - poetry new gbizinfo
    を実行してみよう。
    既に既存のディレクトリ位がある場合は
    - poetry init
    で適当にダイアログに出てくる質問に答えるといいよ
    README.rstはREADME.mdにrenameしてもよいかも
    10
    ※最終的なディレクトリ構造

    View full-size slide

  11. poetry
    ● 次に開発に必要となるライブラリをインストールしよう!
    ○ 実際は何が必要になるのかは開発初期段階で全て把握するのは無理なので都度都度実行
    ● とりあえず
    ○ 開発に絶対必要なもの(--dev)
    ○ 配布する際に必要となるもの(--devなし)
    をインストールしておこう(ライブラリの内容は後述)
    ● poetry add black isort autoflake mock mypy responses --dev
    ● poetry add click requests
    ● インストールされるライブラリのversionはpyproject.tomlで管理
    ○ バージョン指定方法は https://python-poetry.org/docs/versions/ を見ると良いよ!
    ■ Minorバージョンは変更しても良い、などの書き方が載っている
    11
    ※インストールの様子

    View full-size slide

  12. poetry
    ● 作成すると勝手に __version__ が定義されるよ
    ● しかし、pyproject.tomlにもversion番号があって二重管理しんどい…
    ● この管理のベストプラクティスについては諸説あってまだやりとりしてるみたいだよ
    ○ importlib.metadataで書いておくのが楽そうだよ
    ■ https://github.com/python-poetry/poetry/issues/144
    12

    View full-size slide

  13. poetry
    ● ローカルにあるライブラリをeditable/developなモードでインストールしたい場合は画像の用に書いてから
    poetry install すると良いよ!
    ○ editableモード:コードの変更が自動で反映されるようになり、いちいちpoetry remove/addして更新
    しなくてもよくなるモード
    ○ 1.1.0からこの仕様になっているよ!
    ○ https://python-poetry.org/blog/announcing-poetry-1-1-0.html
    ● 使いどころ
    ○ 例:社内ライブラリAの開発版を、他のレポジトリBで使いながらBの開発をしたい
    ■ Aの機能をBで使う際に整合的にしたいとか、BのためにAで機能開発するとか
    ● poetry add --editable でイケるためのPRが出ているけどまだMergeされていないみたいだよ!
    ○ https://github.com/python-poetry/poetry/pull/3250
    13

    View full-size slide

  14. ● 画像の2ファイルを作成してコードを書くと↓のように実行できるよ!
    ○ poetry run はpoetryの作成する仮想環境で実行するおまじないだよ!
    ○ 法人番号に対応した会社名と住所が返ってくる
    ❯ poetry run python -m gbizinfo.main --corporate_number 7010401075212
    ('株式会社ユーザベース', '東京都港区六本木7丁目7番7号')
    とりあえず動くコードを書く
    14
    ※写経が面倒な人は https://github.com/forcas/analysis-example-app-gbizinfo をCloneしてしまおう!

    View full-size slide

  15. ● ちょっとだけコードの解説をするよ
    とりあえず動くコードを書く
    15
    ・clickを使うと引数の処理がめっちゃらくになるよ!
    ・引数のValidationもできるよ!
    (桁数のみチェック、本当はCheckDigitとかもやる)
    ・ #type: ignore はmypyを無視するおまじない
    ・https://info.gbiz.go.jp/ が提供するAPIを呼ぶだけ
    ・SPARQLという言語が必要!(詳しくない)
    ・POST部分を切り出して書いておくと単体テストしやすくな
    るよ!(豆知識)
    ※写経が面倒な人は https://github.com/forcas/analysis-example-app-gbizinfo をCloneしてしまおう!

    View full-size slide

  16. pytestで単体テストをしよう
    16

    View full-size slide

  17. テストがない=プロの仕事ではない
    ● テストがないとそもそも動作として”何が正しいのか”が何もわからない…
    ○ ここでは「正しさ」について議論することはやめておくよ!皆それぞれの正義があるので…
    ● 機械学習だって統計学の知見があればテストが書ける!
    ○ 推定値のバラツキ(標準誤差とか)を考えるんや&ここではやらない
    17

    View full-size slide

  18. テストを書くよ!
    ● こんな感じ
    ● clickにはCliRunnerクラスがあっ
    て、実際にTerminalから呼び出した
    状態をテスト出来て便利だよ!
    ● test_main()は単体ではなく結合テ
    ストになっている(Mockなしに全モ
    ジュールを使用してCLIとして実際
    に実行してるので)
    18

    View full-size slide

  19. テストを書くよ!
    ● SPARQLが所望のものになっているか確認した
    り、POSTした結果がちゃんと捌けるか確認したり
    ● 実際にPOSTする代わりにPOST結果のMockを
    responses で作成して、結果が正しくParseされる
    かを確認
    19

    View full-size slide

  20. テストを動かすよ!
    poetry run pytest
    でおしまい。個別のテストは
    poetry run pytest tests/test_basic.py
    などで実行できるよ!
    20

    View full-size slide

  21. black/isort/autoflakeでフォーマッティングしよう
    21

    View full-size slide

  22. Codeフォーマットについて
    ● フォーマットに関する指摘がCodeレビューにしばしば出てきた
    ○ おじさんが若い頃には、ね。
    ○ e.g. 「フォーマットが崩れています、自戒を込めてUnapproveです」
    ○ でもこれ時間の無駄じゃね?(1円も売上にならない)
    ■ < そもそも高価な人間のやるべきことでもない
    ○ 我々のやるべきこと=売上を上げること
    ■ SaaSビジネス a.s. ≒ ユーザの期待に応え“続ける” ⇒ SaaS最高!
    ● 保存 / git commitするたびに自動的にフォーマッター書けたい!
    ○ 「git hook」や「保存時 整形」とかで検索するといいよ!
    ○ PyCon JP 2020のYuuki Nakajimaさんの「チーム開発時にやっておいたほうが良いこと」が大変良いです(このトピックだけでなく全体的に良い

    ■ https://gitpitch.com/darakudou/pyconjp_2020
    ○ 最後に弊チームでのやり方を紹介
    22

    View full-size slide

  23. 弊チームが採用しているコードフォーマッター
    poetry run black . --check
    ● --checkを外すとファイルを修正するよ
    ● https://github.com/psf/black
    ● フォーマットの形式は pyproject.toml で指定できるよ!(このレポジトリでもそうしている)
    ○ https://black.readthedocs.io/en/stable/pyproject_toml.html#configuration-format
    black
    23

    View full-size slide

  24. autoflake
    未使用変数、 未使用importを自動で検知/削除したいよ
    poetry run autoflake -r --check \
    --remove-all-unused-imports\
    --ignore-init-module-imports\
    --remove-unused-variables .
    ● --ignore-init-module-imports : exclude __init__.py when removing unused imports
    ● --checkを--in-placeに書き換えるとファイルの修正を行う
    ● https://github.com/myint/autoflake
    ● pyproject.toml対応したらオプション記述を移動したい
    24

    View full-size slide

  25. isort
    ライブラリのimportする順番もあまり気にしたくないよ!いい感じに並べ替えてほしいよ!
    poetry run isort . --check --profile black
    ● --checkを外すとファイルを修正する
    ● --profile blackとすることでblackの方針に合わせた修正をする
    ● これもpyproject.tomlで指定可能
    ● https://github.com/PyCQA/isort
    25

    View full-size slide

  26. mypyでType Hintsを徹底活用しよう
    26

    View full-size slide

  27. 型付けについて
    ● 型付けってなに?
    ○ 関数の引数がstrなのかintなのか等、その”型”を明示しておくことだよ
    ● 何が嬉しいの?
    ○ パッと見で関数から返ってくる型&引数の型がわかる
    ■ 型が合わなくて処理停止(動的な言語なので実行時にわかる)!がなりにくくなる
    ○ mypyが勝手に型情報をもとにCodeをチェックしてくれるようになる
    ● mypyはなんなの?
    ○ そんな型情報に基づいてオレたち開発者をこっそり守ってくれるものだよ!
    ■ 静的な言語(Scalaとか)だともっと強力にオレたちを守ってくれるよ!(移行したい)
    ○ 型があってないと警告をだしてくれたりする
    ● mypy以外にもそういうライブラリを有名所が出していてくれたりもするよ!
    ○ ここは好み&宗教戦争になりそうなので深く言及しない
    ○ Pyre (Facebook)、Pyright (Microsoft)、Pytype (Google)
    27

    View full-size slide

  28. mypy
    poetry run mypy . --platform linux --config-file mypy.ini
    ● 3.9系のPythonだとまだ完璧には動かないぽいから、必要に応じて #type: ignoreをつけて凌いでいこ
    う!
    ● こちらがマージされれば3.9対応(including PEP585)
    ● 設定ファイルを適当なiniファイルに書いておけば --config-file mypy.ini で読ませられるよ
    ● https://github.com/python/mypy
    28

    View full-size slide

  29. 退屈なことはGithub Actionsにやらせよう
    29

    View full-size slide

  30. 退屈なことはGithub Actionsにやらせよう
    ● この手の整形・チェックは人間がやるのは時間の無駄です
    ○ 無駄というかミスが出て余計な工数がかかります
    ○ “やった感”があるので個人の業務達成感はあるが、1円も売上にならない
    ● こういうのは何も考えずに勝手に誰か()がやってくれているべき
    ● https://github.co.jp/features/actions がそれをサポートしてくれるよ!
    ● とりあえず .github/workflows/ というディレクトリを掘って、 適当なyamlファイルを作ろう!
    ○ ここではci.ymlにしておくよ!
    30

    View full-size slide

  31. .github/workflows/ci.yml はこんな感じに書いておくと良いよ
    31
    ※写経が面倒な人は https://github.com/forcas/analysis-example-app-gbizinfo をCloneしてしまおう!
    ● 我々はナウい集団なのですでにPython3.9系のみを使っているよ!!!

    View full-size slide

  32. Pushするたびに勝手にCIが走って今まで説明してきたことの全てを勝手にやってくれ
    るよ!
    32

    View full-size slide

  33. 開発を進めていこう!
    33

    View full-size slide

  34. 開発を進めていこう!
    ● まとめ
    ○ 現状弊チームでは以下で運用しているよ
    ■ パッケージマネージャ:poetry
    ■ コードフォーマッター:black/autoflake/isort
    ■ Type Hintsの活用:mypy
    ● これらのチェックがgit pushする度にGithub Actionsにより勝手に走っているよ
    ● これで冒険に出る準備は整ったので、一緒にヤッテイキましょう!
    ● ここで紹介したコードは以下にありるよ!
    ○ https://github.com/forcas/analysis-example-app-gbizinfo
    34

    View full-size slide

  35. ※ここからエンジニア採用広告
    35

    View full-size slide

  36. Uzabase データサイエンティスト 機械学習エンジニア 検索
    データサイエンティスト/機械学習エンジニア募集中
    keyword
    機械学習、データサイエンス自然言語
    処理、クローリング、ソフトウェア開発
    ※経営統合によりUzabase採用になり
    ます
    36

    View full-size slide