Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

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

Slide 4

Slide 4 text

この研修は何なの? 4

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

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

Slide 7

Slide 7 text

開発の基盤を整えよう 7

Slide 8

Slide 8 text

poetryを使ってみよう 8

Slide 9

Slide 9 text

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

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

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 ※インストールの様子

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

● 画像の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してしまおう!

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

弊チームが採用しているコードフォーマッター 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

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

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

Slide 30

Slide 30 text

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

Slide 31

Slide 31 text

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

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

開発を進めていこう! 33

Slide 34

Slide 34 text

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

Slide 35

Slide 35 text

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

Slide 36

Slide 36 text

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