Pycharmでディレクトリ構成を誤った話

# 最初に
私は情報専攻の修士です。

といってもプログラムはそこまで得意ではなく、最近になって趣味でプログラミングを家でもやるようになりました。

忘備録として、また同期の間でモチベ維持のために継続して投稿しようとなったので2回目の投稿をさせていただきます。

「自分はこうしている！」「この方がいいよ」といった提案や、「それは違う」といった指摘大歓迎です。よろしくお願いします。

## この投稿の概要
私自身が`Pycharm`を利用していて、理解の浅いままある機能を使っていた結果コマンドライン上で実行ができない欠陥プログラムが完成しました。

この投稿では`__init__.py`を追加するなどして作業環境を整える過程を記しています。

結果として、利用する言語のディレクトリ構成についてベストプラクティスを知らずに、IDEに頼り切って開発をすることによる弊害を知ります。。。

## きっかけ
研究室の同期に、「あんたのプログラム、ぜんぜん動かないんだけど」と言われました。

「しらんがな。。。」と思いましたが、ちょっとショックだったので調べてみたところ私のディレクトリ構成が完全に`Pycharm`というIDEに依存し切った構成のためのよう。

`Anaconda`もそうですが、有名だから安心！とはいかないものですね。。。（自分だけ！？）

## packageとmoduleの曖昧な理解
pythonのファイル単一でモジュール、モジュールを複数集めたものをパッケージと呼ぶそうな

そんなこともよく知らずに作った研究用のディレクトリ。
今までの構成は

```console
PythonProject
├── README.md
├── data
│   ├── input/
│   └── output/
├── lib
│   ├── module_01.py
│   └── module_02.py
├── main
│   └── main.py
├── log/
├── notebook/
└── venv/
```

実行ファイルとimportする自作の関数やクラスは別のディレクトリに分けた。`Java`を少し使っていたときに、ディレクトリを分けて`package`を作っていたのを思い出したからである。でもこれには大きな問題があった。

コマンドライン上で実行ができなかった。

## なんでこうなった
Pycharmの`Preference -> Project:<project name> -> Project Structure`に移動すると、ディレクトリの役割？を決める画面が出てくる。（あんま理解してないです）
<img width="1030" alt="スクリーンショット 2020-01-29 15.07.04.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316993/16c31a4a-785c-3f47-81e7-cdb835f550d7.png">
この青いフォルダ、`Sources`に指定したディレクトリは恐らく自動で`sys.path`に追加されて、プロジェクト内であればimportできるようになった。

こうして`lib`ディレクトリを`Sources`に割り当てた私は、`lib`内のモジュールを`main`ディレクトリで呼び出して利用していた。


この時私は、IDEを使いこなしている感に浸っていた。IDEでしか実行できない制限された環境に自らを追い込んでいるとも知らずに。

## `lib`のパッケージ化
私は他言語でちょっとした変更をするときはvimを用いることがある。

そのため、ターミナルから実行できないというのは研究室の同期はともかく自分も不便だと感じたのでパッケージ化を調べた。

しかし、出てくるのはインターン生向けのきっちりしたディレクトリ構成のみ。もうちっと緩いやつないのかと探し続けて数十分。なんとか緩〜くパッケージ化することに成功した。（？）

```console
PythonProject
├── README.md
├── data
│   ├── input/
│   └── output/
├── lib
│   ├── __init__.py
│   ├── __main__.py
│   ├── module_01.py
│   └── module_02.py
├── log/
├── notebook
│   └── template.ipynb
└── venv/
```

`lib`に追加したのは

- \_\_init__.py
- \_\_main__.py

の2つ。

### \_\_init__.py
これの有用性については、他の人が書いていて分かりやすい記事が多く存在するのでそちらを見て欲しい。最後に参照ページを記載している。

### \_\_main__.py
これを知らなかった。`lib`に`__main__.py`を作成すると

```console
python3 -m lib
```

と書くと、`__main__.py`を実行できるらしい。

```console
python3 lib/__main__.py
```
とするより簡潔である。それに加え、`__main__.py`が実行ファイルであることが、ダンダーの入ったモジュール名により視覚的にわかりやすい。

今までは様々なシチュエーションでの処理を、`main.py`内の条件分岐で使い分けていた。今後はシチュエーション毎にモジュール作成して管理した方が分かりやすいかもしれない。（良いのか分かりません、わかる方いたら教えてください）

## Jupyterはどうするか
`Jupyter Notebook`を用いている学生も少なくないと思う。

個人的に、Jupyterと`.py`を混在するのは嫌だし、私の周りはみんなそうしていた。
そのため、`template.ipynb`を作成し、以下のような記述をした。

```python:template.ipynb
import sys
sys.path.append('<PythonProjectの絶対パス>')
import lib
```

親ディレクトリまでのパスを通してあげることでimportが可能になった。

これで必要な関数をコピペしたり、作業の間だけ`lib`に移すといった黒歴史を繰り返さずにすむ。（恥）

## 結論
Pycharmはデフォルトで多機能が使えるとてもいい環境だが、基準とするべき環境はコマンドラインであるべき。

今後新しい言語やフレームワークなどを利用する際は、ディレクトリ構成のベストプラクティスを検索してから取り掛かる方が後々の修正作業がなくていいと感じた。

## 参考文献
- [\_\_main__.pyについて](https://rinatz.github.io/python-book/ch04-06-project-structures/)
- [Jupyterについて](https://ymgsapo.com/2018/11/03/import-module-jupyter/#i-2)
- [\_\_init__.pyについて](https://qiita.com/methane/items/ed1e5b74747f3ffe9324?utm_source=Qiita%E3%83%8B%E3%83%A5%E3%83%BC%E3%82%B9&utm_campaign=6ff3f76174-Qiita_newsletter_397_01_29_2020&utm_medium=email&utm_term=0_e44feaa081-6ff3f76174-33453545)