ModuleNotFoundErrorからみるpip, pip3, condaの扱い方

## ModuleNotFoundError
pythonを用いてデータ可視化アプリを作成している際にcondaでインストールしたのにも関わらずterminalでimport <module>を含むpythonファイルを実行するとタイトルのエラーが生じた。ちなみにcondaからjupyter notebookを起動し、import <module>を行うとエラーが出ることなく実行された。

1. terminalでのimport moduleの参照先はどこなのか確認
1. jupyter notebookでのimport moduleの参照先はどこなのか確認
1. それぞれの違いは何かを検証
1. condaでインストールしたモジュールをターミナル実行でも使えるよう参照先の編集
1. pip installとconda installの違いはなにか検証
1. terminal実行とjupyter notebook実行の違いはなにか検証

上記手順で確認していこうと思う。

## 1.terminalでのimport moduleの参照先
python moduleの参照先を確認する場合以下コードで確認できる。

```terminal:terminal
python3 -c "import sys;import pprint;pprint.pprint(sys.path)"
```

実行を行うと以下のように出力された

```terminal
['',
 '/Users/masato/miniforge3/lib/python3.9/site-packages',
 '/opt/homebrew/lib/python3.9/site-packages',
 '/Users/masato/Desktop/Udemy/PythonPlotlyDashApp',
 '/opt/homebrew/Cellar/python@3.9/3.9.9/Frameworks/Python.framework/Versions/3.9/lib/python39.zip',
 '/opt/homebrew/Cellar/python@3.9/3.9.9/Frameworks/Python.framework/Versions/3.9/lib/python3.9',
 '/opt/homebrew/Cellar/python@3.9/3.9.9/Frameworks/Python.framework/Versions/3.9/lib/python3.9/lib-dynload',
 '/opt/homebrew/lib/python3.9/site-packages']
```

'/opt/homebrew/lib/python3.9/site-packages'が２つ有るのはおそらくどこかのタイミングでファイルを編集したからかと思うので後々ファイル編集を行いたい。~~(p.s. [参考記事](https://note.nkmk.me/python-import-module-search-path/)を見ているときにスクリプトファイルが有るディレクトリとカレントディレクトリを参照しており、たまたま２つが等しいため重複しているように見えたことがわかった。)~~

ちなみに```sys.path```で表示されたのは

- m1 macでインストールしたminiforge3でインストールしたモジュールが含まれている```site-packages```ディレクトリ
- カレントディレクトリ
- 標準ライブラリのためのディレクトリ（3つ）
- pipでインストールしたサードパーティライブラリのためのsite-packagesディレクトリ(何故か2つ汗)

である。terminal実行でも一応はminiforgeの参照先を見てはいるが、、、、

## 2.jupyter notebookでのimport moduleの参照先(anaconda activate後)

```python:jupyternotebook
import sys
import pprint
pprint.pprint(sys.path)
```
実行してみると以下の出力結果が得られる。

```python
['/Users/masato/Desktop/Udemy/PythonPlotlyDashApp',
 '',
 '/Users/masato/miniforge3/lib/python3.9/site-packages',
 '/opt/homebrew/lib/python3.9/site-packages',
 '/Users/masato/Desktop/Udemy/PythonPlotlyDashApp',
 '/Users/masato/miniforge3/envs/ds_env/lib/python39.zip',
 '/Users/masato/miniforge3/envs/ds_env/lib/python3.9',
 '/Users/masato/miniforge3/envs/ds_env/lib/python3.9/lib-dynload',
 '/Users/masato/.local/lib/python3.9/site-packages',
 '/Users/masato/miniforge3/envs/ds_env/lib/python3.9/site-packages',
 '/Users/masato/miniforge3/lib/python3.9/site-packages/IPython/extensions',
 '/Users/masato/.ipython']
```

パット見でもかなり違うことがわかる。

## 3.terminalの参照先とjupyter notebookでの参照先の違いについて
共通のものとしては、

```terminal
['',
 '/Users/masato/miniforge3/lib/python3.9/site-packages',
 '/opt/homebrew/lib/python3.9/site-packages',
 '/Users/masato/Desktop/Udemy/PythonPlotlyDashApp',
 '/opt/homebrew/lib/python3.9/site-packages']
```
があり、それぞれ違う部分としては

```terminal:terminal
[
 '/opt/homebrew/Cellar/python@3.9/3.9.9/Frameworks/Python.framework/Versions/3.9/lib/python39.zip',
 '/opt/homebrew/Cellar/python@3.9/3.9.9/Frameworks/Python.framework/Versions/3.9/lib/python3.9',
 '/opt/homebrew/Cellar/python@3.9/3.9.9/Frameworks/Python.framework/Versions/3.9/lib/python3.9/lib-dynload',
 ]
```

```python:jupyternotebook
[
 '/Users/masato/miniforge3/envs/ds_env/lib/python39.zip',
 '/Users/masato/miniforge3/envs/ds_env/lib/python3.9',
 '/Users/masato/miniforge3/envs/ds_env/lib/python3.9/lib-dynload',
 '/Users/masato/.local/lib/python3.9/site-packages',
 '/Users/masato/miniforge3/envs/ds_env/lib/python3.9/site-packages',
 '/Users/masato/miniforge3/lib/python3.9/site-packages/IPython/extensions',
 '/Users/masato/.ipython']
```
とわかる。ds_envというのはcondaの仮想環境の一つで主にデータ分析関連のモジュールが整っている環境を私が作成したものだ。上記を見てわかるように参照先が異なるためterminalとjupyter notebookで実行した結果が異なる。

conda ds_env環境下と同じように実行させたい場合は'/Users/masato/miniforge3/envs/ds_env/lib/python3.9/site-packages'をterminalで参照するリストに追加をすれば良い。

## 4.condaでインストールしたモジュールをターミナル実行でも使えるよう参照先の編集

とりあえずcondaの参照先をterminalでも参照できれば良いので環境変数の記述で簡単に済ませる。これが最適かは果たしてわからない。

```zsh:.zshrc
export PYTHONPATH="/Users/masato/miniforge3/envs/ds_env/lib/python3.9/site-packages:$PYTHONPATH"
```

```source ~/.zshrc```を行い、参照先を確認すると確かに追加されていることがわかる。

## 5.pip installとconda installの違いはなにか検証

私は全く詳しくなかったため[こちら](https://insilico-notebook.com/conda-pip-install/)の記事を参考に確認していく。

ざっくりとした違いは


|  | conda | pip |
|:-:|:-:|:-:|
| コンパイル  | コンパイル済みバイナリファイル  | ソースファイルが含まれ、コンパイル必要(このコンパイルがローカルPCごとにエラーが出る原因)  |
| 依存関係  | 依存関係チェッカーのようなものが存在し、適切な更新・インストールするため依存関係でのエラーが少なく済む  | 依存関係を確かめるためのものがないのでスクリプト作成者がパッケージ間の調整をしてあげる必要がある。  |
| 実行速度  | どうやら速い  |   |
| 言語  | python, R, Ruby, Java,...  |  python **only** |
| 仮想環境  | o  |  x |

上記差異をみてみるとpip, condaの双方を用いてしまうとモジュール間の依存関係の問題でエラーが出てしまう原因となりそう。実際はどうかわからないができるだけ片方だけ用いるのが良さそうだ。

## 6.terminal実行とjupyter notebook実行の違いはなにか検証
なぜterminalとjupyter notebookのモジュールの参照先が違うのか。こちらはかなり大変そうなのでとりあえずは保留にさせていただきます。申し訳ありません。

こちらに関して詳しい方がいましたらご教授いただければ幸いです。

## まとめ
とりあえずはpip, condaについてなんとなく理解してパス設定についてもできそうなのでとりあえずはこちらにて締めさせていただきたいともいます。ちなみにpip,pip3はpython2, python3の管理らしいです。