深いインプットの探求, ただの理解を超えて

# はじめに
本記事は[リンクアンドモチベーション Advent Calendar 2023](https://qiita.com/advent-calendar/2023/lmi)の4日目になります。

インプット(何かを学ぶこと)には"深さ"と"広さ"があります。
インプットの"深さ"と"広さ"の掛け算である分野における専門性が決まります。
この記事では、深いインプットについて考えます。また深いインプットを行うことで、どのようなメリットがあるのかを考えます。

# 執筆の契機
筆者自身、インプットは継続的に行ってきましたが、シニアエンジニアと仕事をする中で「理解が浅くて、話についていけてないぞ。」と感じることがありました。
その時「つよつよエンジニアの条件」について議論したことがきっかけです。

その中で、「"わからないという気持ち悪さ"に対して敏感になろう」と話題に上がりました。
これはつまり、1つの技術ソースの深い部分まで読み取れるようになろう。読み取れていない時の"気持ち悪さ"について敏感になった方がいいという話でした。

実務に落とし込むと、普段使っているライブラリの仕様をどれだけ語れるか？が１つの点検になるとも話に上がりました。

この話をして、表面上の問題解決にとどまった浅いインプットを繰り返しているなと感じました。ちょうどよかった、これを機に言語化をしています。

# この記事の対象読者
想定している読者は、継続的にインプットは行ってきたが"つよつよエンジニア"と比べて「理解が浅いのではないか」と不安を持つ人などです。

:::note warn
「経験が豊富でシステム周辺の課題解決力が高いエンジニア」を総称して、「つよつよエンジニア」と呼ばせていただきます。
:::

# なぜ深くインプットするのか？
それは、**システム的な課題解決能力を恒久的に高めるため**と考えています。
課題解決力が高まると、例えば"厳密に境界条件を語れる", "厳密に技術を選定できる"などできることが増えます。

また一度深くインプットした時に、新しい情報や技術に対する適応力が高まると思い、「恒久的に高まる」と考えました。
いわゆる「１を聞いて１０を知る」人は、他領域で深くインプットした経験より類推が使えている場合が多いです。

## インプットの深さをレベル分けする

筆者なりに、開発に関するインプットの深さを抽象化してレベル分けしました。

| レベル | 基準 |
| :-- | :-- |
| 1 | 既にあるものを動かせる。 |
| 2 | 0から目的に応じて適切に構築できる。 |
| 3 | 周辺の技術に対する深い理解を前提に、無数の選択肢から目的に沿って最適な手段を選べる。 |


# 検証: 実際に「Pythonの仮想環境構築」を深くインプットしてみる

Pythonの仮想環境構築を題材に、深いインプットを行ってみます。
レベルごとにインプットの内容がどう変わるか、を見ていきます。
深さについては、上の抽象化した基準をもとに３つの完了条件を設定しました。

| レベル | 完了条件 |
| :-- | :-- |
| 1 | 先人が構築したPythonの仮想環境を利用できる。 |
| 2 | Pythonの仮想環境を目的に応じて適切に構築できる。 |
| 3 | Pythonの仮想環境に関して、最適な手段を選択できる。 |

レベルごとにインプットの結果と気づきをまとめていきます。果たして、課題解決能力は恒久的に高まるのでしょうか？

## Lv1: 先人が構築したPythonの仮想環境を利用できる。

### やること
- `python 環境構築 初心者` で検索してみる
- 良さそうな記事「[Poetryをサクッと使い始めてみる](https://qiita.com/ksato9700/items/b893cf1db83605898d8a)」を見つける
- 上から順番に実行してみる

### インプットの結果

Poetryの基本的な使い方がわかり、仮想環境を構築する手順がわかりました。
```bash
# Poetryのインストールするんだなあ
$ poetry install
# パッケージを追加できるんだなあ
$ poetry add <package-name>
# Pythonプログラミングを実行できるんだなあ
$ poetry run python <python-file>
```

pyproject.tomlの記法、つまり設定の変更手順がわかりました。

```toml: pyproject.toml
[tool.poetry]
name = "project_abc"
version = "0.1.0"
description = ""
authors = ["John Doe <johnd@example.com>"]

[tool.poetry.dependencies]
python = "^3.9"

[tool.poetry.dev-dependencies]
pytest = "^5.2"

[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"
```

### インプットした気づき
- Poertyはなんとなく使えそう。
- 今までpyenvとpipで環境構築してみたが、今度使ってみよう。


## Lv2: Pythonの仮想環境を目的に応じて適切に構築できる。

Poetryに絞って環境をカスタマイズできるようにインプットしてみます。

### やること
- 公式ドキュメント「[Poetry documentation (ver. 1.1.6 )](https://cocoatomo.github.io/poetry-ja/cli/)」を読む

### インプットの結果
Lv1では知り得なかった新しいコマンドを知る。

```bash
# exportコマンドはlockファイルを他のフォーマットへ出力します。
$ poetry export -f requirements.txt --output requirements.txt

# check コマンドは、 pyproject.toml ファイルの構造を検証し、エラーがあった場合は、詳細なレポートを返します。
$ poetry check

# build コマンドは、ソースアーカイブとwheelアーカイブへビルドします。
$ poetry build

# 前に build コマンドでビルドしたパッケージを、リモートレポジトリに公開します。
$ poetry publish
```

グローバルオプションの存在を知る。

```markdown
--verbose (-v|vv|vvv): メッセージの冗長さを増やします: 1つでは標準の出力、2つではより冗長な出力、3つではデバッグ出力です。
--help (-h) : ヘルプ情報を表示します。
--quiet (-q) : メッセージを出力しません。
```

installコマンドのオプションを知る。

```markdown
--no-root: ルートパッケージ (あなたのプロジェクト) をインストールしない。
--no-dev: dev-dependencies をインストールしない。
```

### インプットした気づき
- exportコマンドは使ったことがなかったな。
  - Poetryサポートしていない環境でも簡単に利用できるように開かれてるのかな。
- build, publishコマンドは使ったことがなかったな。
  - プロジェクトの公開が簡単にできそうだ。
- verboseオプション, checkなどでデバッグの仕組みもあるんだな。
  - これを使うと、Poetryの内部の仕組みも理解できそうだ。
- **今まで使ったライブラリのオプションとか他のコマンドも見てみよう。**
  - 例えば、pytestのオプションとか。

## Lv3: Pythonの仮想環境に関して、最適な手段を選択できる。

### やること
Pythonの仮想環境の歴史や競合を調べてみます。
比較検討を詳しく行った記事「[pipとpipenvとpoetryの技術的・歴史的背景とその展望](https://vaaaaaanquish.hatenablog.com/entry/2021/03/29/221715)
」を見つけたのでこちらを精読してみます。
~~この記事を積読してて読む口実が欲しくて、このテーマを選びました。~~

### インプットの結果
※引用は全て、「[pipとpipenvとpoetryの技術的・歴史的背景とその展望](https://vaaaaaanquish.hatenablog.com/entry/2021/03/29/221715)」より抜粋しています。

Poetryって１ユーザーが開発しているんだなあ、すごい。（小並感）

> 先のPipenvと違い、PyPAではなく、1ユーザである@sdispaterが主導し開発されている。

Poetryの開発経緯、pipenvに対する課題を知ることができた。

> pipenvに対する課題とpoetryを作成した経緯が書かれている。要約すると以下の3点になる。
・setup.pyやrequirements.txt、Pipfileを導入せずcargoやcomposerのようにbuildしpublishしたい
・pipenvの意思決定のいくつかが好みでなかった
・より良い依存解決リゾルバの導入

pipenvとpoetryの違いについて、概観を知った。ツール選択の観点を知ることができた。
>pipenvとpoetryの違いについて、以下にまとめる。
・build/publishの機能の違いはpyproject.toml誕生の前後関係とPyPAのエコシステムの思想からくるもの
・lockファイル生成速度は、PyPIのjson-apiの結果をどこまで信頼し、どこまでパッケージを自分でbuildするかに関係
　・依存解決リゾルバの違いもここに縛られている側面がある
　・解決するにはいくつかの方法こそあるが、下位互換やセキュリティ、金銭的な側面の課題もある
・Pipenvはissueではなくメーリングリストを利用して開発が進んでいる
　・徐々にissueでの議論も進んでおり開発フローの改善も進む
　・poetryの方が開発体制が良いという訳では必ずしもない
・それぞれゴシップ的な炎上を経験しておりディスカッションに参加する場合は丁寧な理解をしておくと良い

プロジェクトテンプレート、運用ルールがないと、容易にファイルや管理場所が乱立するのだと知れた。
[ばんくし](https://vaaaaanquish.jp/)さんの苦悩が追従できた。

> pipenvからpoetryへの移行を行った。要点としては以下のようになる。
・社のVPN起因でpipenvのlock速度に課題があり技術的解決も困難であったため乗り換えを決意した
・乗り換え先の選定においてはversioning等の既存のCI、OSSの移植の簡易さを考慮した
・数十のプロジェクトで1年単位での移行となった
・結果として課題が解決するだけでなくpyproject.tomlへの情報集約、OSSの盛り上がり等の副次的効果も得られた

### インプットした気づき

- *[ばんくし](https://vaaaaanquish.jp/)さんのインプット量が桁違いじゃないか？？？*
- これが"つよつよ"の基準かもしれない。

## 検証結果
深くインプットしたことによって、課題解決能力は高まると感じました。また、次のインプットへの良い影響やアイディアも感じました。
具体的には、以下のような変化がありました。

| レベル | 気づきの変化 |
| :-- | :-- |
| Lv1~Lv2 | ・短期的な問題解決だけではなく、未来の変更,開発に対して思考する機会が得られた。<br>・Poetryで活かせなくても、他のライブラリで有効活用できそうな知見が得られた。 |
| Lv2~Lv3 | ・ツールのメリットデメリットを知ることで、ツール選定のイメージが湧いた。<br>・**トレードオフを語れると説得力がとても高いことを知れた。** |


# まとめ
新人のうちや趣味の範囲だけを考えれば、Lv1「基本的な使い方を理解し、説明できる。」のインプットで十分かもしれません。
しかし、Lv2「細かい部分（オプション、類似の処理方法、構造など）について詳細に説明し、応用する」のインプットを行うことで、課題解決能力を恒久的に高めることができると、筆者は信じています。
Lv3「背景や歴史」を知りに行くことで、自分のインプットの深さがどの程度なのかを知ることができました。

１つのツールに対して解像度高く熱く語れるのは格好いいと思いました。それと同時に、私も格好良く強いエンジニアになりたいと決意を改めました。


# あわせて読みたい
- [新人プログラマに知っておいてもらいたい人類がオブジェクト指向を手に入れるまでの軌跡](https://qiita.com/hirokidaichi/items/591ad96ab12938878fe1)
  - オブジェクト指向について歴史から深ぼっている記事です。
- [好きなものと向き合う](https://note.com/vaaaaanquish/n/nc84c55985412)
  - ばんくしさんの個人的に好きな記事です。
- [いわゆる強いエンジニアは何が強いのか](https://qiita.com/mu-suke08/items/59d10481e93f2e51d750)
  - つよつよエンジニアについて考察している記事です。