[Python]  プログラミング未経験が1つのツールを作るまでにやったこと


## はじめに
現在エンジニア歴2年目ですが、1年目の時に
「こういうツールがあったらな」という要望から実際にツールを作りました。
作成したツールは[こちら](https://github.com/ap-communications/NEEDLEWORK-ScenarioWriter)です。
当時のままとなっていますので、未知な不具合やリファクタリングの余地はあると思います。
これから成果物を作ろうと考えている未経験者に、
当時の自分が未経験ながらどのようにツールを作っていったかを
知ってもらうために今回記事に残そうと思いました。
未経験者の開発への道の手助けとなれば嬉しいです。

## ツールを作るまでの過程
* 開発前にやったこと
    * ゴールを決める
    * 試しにcsvを作成してみる
    * WBSの作成および確認
    * 使用するプログラミング言語の選定
    * ツールの利用方法の決定
    * アルゴリズムの決定
    * プログラミング環境の準備
* 開発中にやったこと
    * WBSの見直し
    * 動作確認
    * テストコード・リファクタリング

次項からは各項目について見ていきます。

### ゴールを決める
実際にツール（成果物）を作るにあたって「何をゴールとするか」を決めます。
期日等も設けると良いでしょう。

* 当時のゴール
    * txtファイルを読み取りそのデータを所定のフォーマット（csv）で出力する
    * そのツールを配布する

### 試しにcsvを作成してみる
ツールが完成した時にどのようなcsvが出力されるのかを知りたかったので、
まずは手動でcsvを作成しました。
これにより以下を理解していきました。

* txtファイルの大体の構成
* csvの作成に利用するtxtファイルのデータ

### WBSの作成および確認
ツールを作成する期間が決まっていなければ必要ないと思います。
しかし「仕事で」となると期間（納期）が決まってない仕事はほぼないでしょう。
となってくると考えることも出てきます。

* その期間内で作るにはどう進めるべきか(各作業にどのくらいの時間を割り当てられるか等)
* その期間内でツール作成以外の作業がどのくらいあるか
* 何を以ってツール作成完了とするか
    * txtファイルの読み取り
    * csvの出力
    * ツールの配布

### 使用するプログラミング言語の選定
何かを作るにあたって適しているプログラミング言語があるものもあります。
今回はそこまで差分が出そうになかった＆資格を保有していたPythonに決めました。

### ツールの利用方法の決定
配布されたツールを実際に使用するユーザー全員がこのツールを利用できる環境を用意しているわけではないので
そのユーザーでも利用できるように環境準備方法を明記する、または環境を準備しなくても使えるようにしなくてはいけません。
開発当時は前者を目標に進めました。（後に環境不要でも使用できるように対応しました。）

### アルゴリズムの決定
試しにcsvを作成した際にわかったものをそのままツールのアルゴリズムとして落とし込みます。
例えば以下の情報を元にCSVを作成しようとします。

```sample.txt
set address "Trust" "192.168.1.103/32" 192.168.1.103 255.255.255.255
set address "Untrust" "200.200.200.200/32" 200.200.200.200 255.255.255.255
~（中略）~
set policy id 3 from "Trust" to "Untrust" "192.168.1.103/32" "200.200.200.200/32" "SNMP" permit log
~（中略）~
```

わかったものとしては以下です。

* 主軸をset policy id〜としそこに関する情報からcsvを作成していく
* 送信元および宛先IPはset address~から成り立つ行に詳細な情報がある
* 送信元および宛先FW IPはゾーン情報（from "Trust" to "Untrust"）から更に割り当てられているインターフェースのIPを使用する
* ”SNMP”はポート番号が161なのでこれを宛先ポート番号とする　etc…

これをアルゴリズムとしていきます。

### プログラミング環境の準備
今回は以下を準備しました。

* Python
* pyenv
* Git

環境準備については[こちら](https://github.com/ap-communications/NEEDLEWORK-ScenarioWriter)に記載しています。
また言語等によって変わってくるので割愛します。
ここまできて開発スタートです。

### WBSの見直し
開発していく中で思ったよりも進んだフェーズ、またはそうでないフェーズがあると思います。
余裕ができたフェーズだとテストコードを書いたりリファクタリングしたりできますが、
一方でそうでないフェーズが出てきたときにどうするかが
今後仕事をしていく上で大切になってきたなとこの頃感じました。

### 動作確認
アルゴリズムに則って実装したものが予想通り動いているか確認します。
予想通り動いていればよし、そうでなければ…修正します。
動作確認で予想通り動かなかった例外に対応するためにアルゴリズムの追加や
既存のアルゴリズムの修正が必要になることもあります。
ここで適切に修正できなければもしかしたら地獄を見ることになるかもしれません（後述）

### テストコード・リファクタリング
動作確認で予想通り動かなかった箇所を修正することで今まで動いてたところが
正常に動かなくなること（デグレーション）もあると思います。
私はそれなりにデグレーションしてしまいました…
テストコードがあればデグレーションした際にすぐ気づけますが、
最悪print等でデバッグしていれば気づけます。
テストコードを書く時間に見合わないこともあるので作ろうとしている成果物の規模感、
メンテナンスの頻度等で書くか決めるのがいいと思います。
（初めてでテストコードも書いてみたいとかでなければの話ですが）

リファクタリングに関しては[リーダーブルコードを読んで](https://www.oreilly.co.jp/books/9784873115658/)を元に行なっていきました。
関数名の命名や汎用性が高い関数にする等とても参考になりました。
他にも[flake8](https://pypi.python.org/pypi/flake8)や[radon](https://pypi.python.org/pypi/radon)などを使用しました。

## Q&A

Q. 事前にプログラミング言語の勉強しないの？
A. 資格以上のことは事前に勉強していません。
必要になったタイミングで使いながら学習していきました。
例：pythonでcsvを出力したい→ググる→pandasというライブラリがあるのを知る→pandasの使い方を覚えていく
資格で勉強した≠実務で使える になる可能性もあるので
スタート地点は未学習者とそこまで大差ないと思っています。
（勉強することに越したことはないですが）

## 最後に
初めは何からやればいいか等色々考えてしまうかもしれませんが
「とりあえずやってみる」が大事だと思います。
当時の「0から1つの成果物を作り上げた」という経験が
今の開発業務に役立っていると感じます。
「ここから始めましょう、イチから…いいえ、ゼロから。」