773eafaa28eb98c6ae327aed610810055d202d28
research/\343\201\252\343\202\223\343\201\241\343\202\203\343\201\243\343\201\246\351\226\242\346\225\260\345\236\213\343\203\227\343\203\255\343\202\260\343\203\251\343\203\237\343\203\263\343\202\260\343\201\247\347\240\224\347\251\266\343\201\256\343\202\263\343\203\274\343\203\211\343\202\222\346\233\270\343\201\223\343\201\206.md
... | ... | @@ -0,0 +1,75 @@ |
1 | + |
|
2 | +- ベースは関数型プログラミング。 |
|
3 | +- ただし"頑張りすぎない"。 |
|
4 | +- Python + Pandasでコードを書く場合を想定しています。 |
|
5 | +- たくさん方針はあると思いますが、良ければ参考にしてください。 |
|
6 | + |
|
7 | +## 方針 |
|
8 | +### 方針1: 想定されるエラーでクラッシュさせる |
|
9 | +- 入力するデータの質をコントロールできるので、例外処理で頑張らない。 |
|
10 | + - きっと入力したデータの生成も自身でやったのではないだろうか。 |
|
11 | +- もし実行中に例外が発生したら? →そこでクラッシュさせる。 |
|
12 | +- 例えば生のCSVがパースできなかった |
|
13 | + - なぜそれ以上処理を続ける必要がある? |
|
14 | + - そこでクラッシュさせて直せばよい。 |
|
15 | + - パース用の関数を修正する必要があるかもしれない。 |
|
16 | + - 計測機器の設定を間違えたのかもしれない。 |
|
17 | + - 計測方法自体が間違っているかもしれない。 |
|
18 | + - → どちらにせよ対処しないと正しい実験結果は出せない。 |
|
19 | +- エラーハンドリングで頑張るのでは無く、エラーが起きる度に正していく。 |
|
20 | +- ただし、例外を発生させている時点で、純粋関数とは言えない。なので"なんちゃって関数型プログラミング"と呼んでいる。 |
|
21 | + |
|
22 | +### 方針2: テスト付きの小さくて分かりやすい関数をたくさん作る |
|
23 | +- DataFrameを受け入れ、DataFrameを返すような関数を作る。 |
|
24 | +- pandasの操作は自分で関数化し、それぞれunittestを追加する。 |
|
25 | + - 最初は全てにテストを付ける必要は無い。 |
|
26 | + - unittestを書いているとコーディング時間が2倍になってしまうかもしれない… |
|
27 | + - しかしコードの間違いに気が付かず、間違いの判明が後になればなるほど差し戻しの影響が大きくなる。 |
|
28 | + - できる限りテストを付けるのが大事である。 |
|
29 | +- 思ったよりも自分はPandasの挙動は把握できていない場合がある。 |
|
30 | + - 特にダウンサンプリング、アップサンプリングの挙動は難しい。 |
|
31 | + - また多数の構文を許容するので、間違った構文でも動いてしまう可能性がある。(そして間違った結果がDataFrameに格納されて気が付かない。) |
|
32 | +- ライブラリのバージョンアップを容易に出来る。 |
|
33 | + - それぞれの関数にテストを付けてあれば、バージョンアップで挙動が変わらないことを保証できる。 |
|
34 | + - pandasの場合は構文が結構deprecatedになることがあり、その関数内の書き方だけを修正すればプログラム全体に適用できる。 |
|
35 | +- 共通化できる処理は積極的に共通化する。 |
|
36 | + - 共通したコードを使うことでメンテナンス性が向上する。 |
|
37 | + - 片方は直したけど、こっちでは直し忘れていた…ということを防げる。 |
|
38 | + - 例外的な対処が必要な場合は、明示的に条件分岐して処理する。 |
|
39 | + - 「この実験の時は実験条件○○が特殊だったから、この値に反映しないといけない…」 |
|
40 | + - 関数に実験名も入力として渡せば条件分岐できる。 |
|
41 | + |
|
42 | +### Enum, dataclassを積極的に使う |
|
43 | +- Enum |
|
44 | + - 同レベルの値を識別するのにとても便利。 |
|
45 | + - 同モデルの計測機器A, B, C, ... |
|
46 | + - 計測者A, B, C, ... |
|
47 | + - 条件分岐がとてもシンプルになる。 |
|
48 | +- dataclass |
|
49 | + - 少し複雑な値を型として扱えるようになる。 |
|
50 | + - 例えば、三次元座標はそれぞれの次元の座標を持っているべき -> `Coordinate(x=1, y=2, z=3)` |
|
51 | + - 型チェックの支援を受けられるようになる。 |
|
52 | + |
|
53 | +## なんちゃって関数型プログラミングをするのに便利なお供たち |
|
54 | +- pandera |
|
55 | + - DataFrameの構造や内容に対してバリデーションを実施できる。 |
|
56 | + - 例えば「このカラムは必ずint型のはずで、-100より大きくなることはない」、など。 |
|
57 | + - 時間の許す限りバリデーションを設置することでDataFrameは堅牢になる。 |
|
58 | +- Pylance |
|
59 | + - Pythonの型チェックに使う。 |
|
60 | + - VSCodeの拡張機能の1つ。 |
|
61 | + - デフォルトだとほとんど警告してくれないので、より多くの警告を発するように変更する必要がある。 |
|
62 | + - 変更方法 -> TODO: 追記する |
|
63 | + |
|
64 | + |
|
65 | +## 参考にした資料 |
|
66 | +- なっとく!関数型プログラミング |
|
67 | + - https://amzn.asia/d/0dzUEAAu |
|
68 | + - 関数型プログラミングの考え方がとても分かりやすく書いてある。 |
|
69 | + - しかも読み物としても面白い。 |
|
70 | + - サンプルがScalaなのでPythonで再現できるところは限られてくるが、できるところまでやれば十分である。 |
|
71 | +- Unixという考え方 |
|
72 | + - https://amzn.asia/d/05YA4XUB |
|
73 | + - プログラムを作成する際の心構えがわかりやすく書いてある。 |
|
74 | + - 内容は古いが今でも問題なく採用できる方針が多数載っている。 |
|
75 | + - 賛否あるようだが自分は好き。 |
|
... | ... | \ No newline at end of file |