質問: 私は趣味でプログラミングをしています。(本職はNWエンジニア) そもそも、自分がプログラムに興味を持ったのは機械学習を少しでもできるようになってみたいなあと思ったからです。(たびたびオセロのプログラムについての質問をここでさせて頂きました) ただ、機械学習を実装するにあたって基本的なプログラミング知識が足りなさすぎると感じ、いろいろなサイトを巡って上達法を探ってみました。 例えば、バブルソートを自分で実装してみたりとか、paizaなどプログラミングの題材が置いてあるサイトで学習したり(レベルBくらいならスラスラとけるようにはなりました)、ネットではあまり意味がないとよく書かれていますが、javaの資格(silver)を取得するなど、いろいろやってみました。しかし、個人としてはあまり成長している気がせず、あまり面白さを感じなくなってきてしまいました。 皆さんはどのようなプログラムを作り、そしてどのように上達してきたのでしょうか? 体験談やアドバイスなど頂ければ幸いです。
回答: 以下の文章は私の偏見に満ちています。 参考になれば幸いですが、「ふーん、こんな考えの変人も居るんだ」くらいの認識でサラッと読んで下さい。 NWエンジニアならターミナル(コマンドプロンプト・PowerShell・Bashなどなど)を立ち上げて作業したことはありませんか? あれの自動化からはじめてみる事をオススメします。 もし手順書を確認しながらコマンドを打ち込むようなオペレーションがあるならば、 その手順書とコマンド群はリソースの無駄遣いです。 その手順書にはxxxコマンドでyyyを確認し、 aであればA操作をbであればB操作を行うみたいに書いてあることでしょう。 スクリプト化すれば、実行権限を付与してやれば勝手に複数コマンドを使い分けて、条件分岐させて仕事の完了まで面倒みてくれます。 それなりに長く続いているプロジェクトならば、先輩や前任者が作った秘伝のタレ(スクリプト)が幾つも転がっていることでしょう。 あれはよく忌み嫌われますが、本来とても重要なものです。 禁止する方向に向かうべきではなく、どうすれば可読性や再利用性が上がるかを検討すべきです。 複雑な手順だから無理?そういうのを上手く整理して書ききる事がプログラミングの腕の見せ所です。 数書いて後悔して書き直すフローを数十回こなせば、自然とあるべき処理をあるべき場所に整理整頓出来ます。 電子世界のおもちゃ箱を触るには誰も彼もが三歳児なのです。何度も散らかして片付けて洗練させるしかありません。 ターミナルはマシンに入れた全てのプログラムを実行出来ます。 プログラムとプログラムをパイプで組み合わせて、いくらでも新しい仕事の形に順応させることが出来ます。 (コマンドプロンプトやBashでは`|`の縦棒をパイプと呼びます。左から右にコマンドを数珠繋ぎのように組み合わせて問題を一撃で解決出来ます。) 仕事の形がうまくフィットしない時は、いくらでも自作のプログラムを作ってあてがう事が出来ます。 別に後から探して同じライブラリが見つかったとしても、そのライブラリのコードを見て評価してやろうという時に頭への入り方は段違いになりますので無駄にはなりません。 実行速度が必要でなければ是非スクリプト(batやシェルスクリプト)や、スクリプト言語(Node.jsやRuby、Python)で自作のプログラムを作ってみてください。 注意点としては、後からいくらでもパイプで組み合わせる事が出来るという点です。 実行するスクリプトはなんでも出来るファットな仕様にするより、小さな事を確実にこなすようにしてください。 あとで正しく組み合わせるスクリプトをあてがえば済みます。 自作したスクリプトはGitで世代管理しましょう。 これが先輩や前任者達が失敗した秘伝のタレを脱却する第一歩になります。 現場には**work.sh、work2.sh、work-new.sh、work-new.sh.bk**等の名前も付けられずに放って置かれたスクリプトの山があるかと思います。 さて、これのどれが最新でしょうか?私にはもはや捨てることしか出来ないゴミにしか見えません。 Gitならwork.shという1ファイルで管理出来ますし、目的に応じて当時の状態に瞬時に戻って取り出す事も可能です。 GitHubやBitbucketというGitのリポジトリホスティングサービスがあります。 GitHubの無料版は公開設定しかありませんので、Bitbucketでプライベートリポジトリを作る事をオススメします。 自作したスクリプトはドキュメントを残しましょう。 これが先輩や前任者達が失敗した秘伝のタレを脱却する二歩目になります。 特別な事をする必要はありません。 Gitのプロジェクトルートのフォルダに、README.mdファイルを投げ込むだけです。 書き方はTeratailと同じMarkdownで、今後のエンジニアのデファクトスタンダートになるフォーマットなので覚える価値は十分あります。 GitHubやBitbucketでそのディレクトリのページを表示すると自動的に記事であるかのように振る舞います。 「概要、インストール方法、使い方」の三項目を記載するだけです。 使い方に至ってはコマンドを作ったら実行してみて、結果とそのコマンドをバッククォート3つでくくりながらコピペしてExampleとタイプするだけ。簡単でしょ? これでもう半年後の自分や後任者が、使い方ワカンネ、秘伝のタレ乙と悪態をつくことはありません。 余裕が出てきたら、特殊な動作をするコマンドは-hや--helpコマンドを仕込んでみてもいいかもしれません。 manファイルを仕込んで見られるようにするのもありでしょう。 自作したスクリプトはテスト用スクリプトでテストするようにしましょう。 これが先輩や前任者達が失敗した秘伝のタレを脱却する三歩目になります。 ○○のレアケースでうまく対応出来ないんだけど... 目視で確認は漏れます。 正常系、エラー系をスクリプトに定義してしまえば一行修正する度に全てのケースで正常であることを保証出来ます。 うっかり漏れても保証すべきテストケースが増えるだけで対応完了。 手順書通りのコマンドが叩けず手痛い失敗をしてしまい、「次は危機感を持って対応するように気をつける」という始末書を書くほど無駄な事はありません。 ここまで出来ればあなたはもうそこらのプログラマより優れています。 NWエンジニアであると同時に、プログラマーとしても十分やっていけるでしょう。 明確な判断が出来るスクリプトは全て作り出せます。 しかしそうこうしている内に、正解が出せるわけではない問題が立ちふさがります。 囲碁将棋等の手が広すぎて最善の手を指し続けられない完全情報ゲーム、 次にどうすれば改善されて利益が上がるのか予測し辛いWebサイトやビジネスの戦略等です。 こういったものが相手として登場して初めて機械学習が出番になります。 とはいっても、基本的には一緒です。 偉い学者さんが作った公式を元にコードを起こせば機械学習プログラムの完成です。 TensorFlowに至ってはGoogleのサイトからSDKを落としてきてAPIを叩くだけです。 後は上記のスクリプトによる自動化の手法がまるっと使えます。 いかがでしたでしょうか? この世界は解決を待っている魅力的な問題でいっぱいです。 是非身近で(未来の自分から見て)無駄なモノを見つけて自動化することに取り組んでみてください。 その過程でわけも分からず打ち込んでいたコマンドの本当の意味や、オプションの使い方がわかります。 興味のある機械学習を使いこなす土台作りと平行しつつ、本業の腕もメキメキ上達することでしょう。