詰将棋のようにTDDでC#を学ぶ実験

「ハチワンダイバー」を通読したので、浦野真彦著「1手詰めハンドブック」を買いました。子供用にどうぶつしょうぎを買っている訳ですが、結構いけそうなので、それならば詰将棋を試してみようという次第です。自分で読むというのもあるけど。私は、7手詰め位でギブアップですね。

[amazonjs asin=”4839933324″ locale=”JP” title=”1手詰ハンドブック”]

将棋とプログラミングは似ている

プログラミングは、新しい問題を解決すると同時に、既存の問題を解決する手段でもあります。新しい問題ってのは、人工知能とかVRとか、新しい技術ですよね。なんらかの技巧を駆使して実現するわけですが、一方で、みずほ銀行リプレースのような既存の技術の積み重ねで成り立っているところもあります。所謂、社内の情報システムの構築なんかは、大抵はこの「既存の技術」の組み立てで十分だったりします。そのあたりを主な仕事にしていると、面白いか面白くないかは別として、仕事としてやっていけるかが重要になります。

それを将棋に例えれば、終盤の詰めの場面で、詰められるかどうかの棋力が重要なのと同じで、きちんと構築されるべきモノに対しては、きちんと構築する力量が必要でしょう。プログラミングで言えば、基礎体力というべきものでしょうか。

「1手詰めハンドブック」は面白い構成になっていて、駒の種類と動き方を網羅かつ分類して詰将棋が作られています。なるほど、手駒に何があったとき(あるいは何もなかったとき)、盤面に何の駒が配置されていたときには…という具合に分類ができるわけです。1手詰めですから、手駒を打つか、盤上の駒を1手だけ動かすか、という基礎的な力が試されるものです。実際の場面では、1手で詰むかどうかは分からないわけですが、詰将棋の場合は「必ず1手で詰む」というルールがあるわけです。

これをプログラミングに置き換えると、

  • 仕様変更があったときに、どこの行を修正すれば、仕様を満たせるのか。
  • バグが見つかったとき、どこの行を修正すれば、バグが解消されるのか。
  • 何か機能を追加したいとき、何を追加すれば、機能が満たされるのか。

という具合に、ちょっとずつ進めるところに似ています。

じゃあ、この1手詰めのところを、TDD(テスト駆動)に直してみたらどうだろうか?というアイデアです。

テスト駆動的に問題を解いて学習する

プログラミングを学習するときに、どうやったら一番よいのか…は、まだ判明していませんが、既にいくつかの方法は提案されています。

  • ひたすら、先人のコードを写経する
  • Scratch のようなブロック型の言語を使って学習する。
  • 独習 C# を読み込んで書物で文法から学習する。
  • Swift Playgrounds のように RPG のように学習する。
  • 学習ビデオを買って、学習する

などなど、何を目的にするのかによるので、一概に何がベストという訳ではありません。ただ、ソフトウェア開発を主とする会社に入ったときに、新人教育でプログラミングを学ぶ場合には「独習 C#」あたりが多いでしょう。文法をひと通り覚えるところからスタートという感じですね。

私も、以前は独習させる場合(大手でない場合は、新人教育のみというパターンは少ないので)、一定のペースで独習シリーズをすすめていたのですが、これが終わってもちっともプログラミング力が上がったように思えないんですよね。確かに、文法はきっちり覚えるかもしれないけど、現場に入ると既存のコードがあって、仕様変更があって、結局のところ、独習シリーズの中にあるような文法すべてを網羅することは皆無であって、当面は、最初の数か所を覚えるだけで済み、あとは現場としてどう対応できるかが問われてきます。

「現場に問われる」という問題は、新人を受け入れる側からみる「即戦力」という視点と同時に、新人/未経験者自身が「仕事としてやっていけるか」の心の支えにも関わります。経験と未経験のギャップが確実にあって、そこをうまく OJT 的にフォローできればよいのでしょうが、最近の現場をみると、それほどフォローできているとは思えません。これは、OJT のリーダーが新人にもっと寄らないと駄目なのか、逆に新人が現場に対して自己的に「戦力になり得る」と思えるかどうか、にも関わる話です。

そうなると、学習のための学習でプログラムの文法を覚えるよりも、まずは、手を動かす形で、コーディングができる状態に持っていくのが先決ではないか?と思い始めました。そうなると、文法を網羅的に知っているという面接的な質問ではプログラミング力というのは測れなくて、もっと、違う面を持ってこないと駄目ですよね。よくある、何か課題を出して解くというのもあるけど、あれもちょっと違う感じがしています(まあ、未経験者の振るい落としとしては良い方法ではあるのだけど)。

面接としてや知識としてではなく、仕事としてプログラミング力を測るのならば、それはちょうど詰将棋を解くのと同じではないか?と思ったわけで、そうなると、問題を解く(実際にコードを動かしてみて解決する)という点では、TDD がよいのではないか、と考えました。

ひとまず10問作ってみた

Visual Studio 2015 の C# で 10問だけ作ってみました。本来は50問ぐらいあると、それなりに学習&実践できるのでしょうが、やってみると結構問題を作るのが大変だったので。

image

最初の変数と配列の扱い方、クラスにいくつかのメソッドを実装するスタイルでコードを完成させていきます。コードを組んで、実際に動かすとテストメソッドがクリアされる(グリーンになる)ので、達成基準が解りやすいと思います。

moonmile/TestPro: TDDで学ぶC#
https://github.com/moonmile/TestPro

なところにコードをアップしたので、気になる方は試してみてください。

ターゲット層

将棋で云うならば、「独習 C#」で文法を学んだだけでは、将棋の駒の動かし方を覚えた10級でしかない。目標とするのは「文法を詳しく知っている」のではなく、「プログラマとしてパフォーマンスが出せる」ということだから、将棋に例えるならば、初段で相手に勝てる、ところまで持って行かないといけない。だから、途中途中で、棒銀や中飛車としての「型」を覚える(高速道路に乗る)ように、オブジェクト指向的なテクニックを学んだり、GoF でパターンを覚えたり、いくつかのフレームワークの使い方を学んだりする。しかし、それだけでは現実には「勝てない」。

[amazonjs asin=”4861916992″ locale=”JP” title=”初段になるための将棋勉強法”]

ならば、プログラマとしてパフォーマンスが出せる≒現実に勝てる、程度が初段としたとき、文法を覚えたときの10級との間はどのように登っていくのだろうか、ということになる。

詰将棋のように TDD で C# を学ぶ前提として、

  • 「独習 C#」などで、C# の文法を学んでいる(本で読んで知っている)
  • Visual Studio の使い方が分かる。
  • .NET Framework のライブラリの使い方/調べ方を知っている(ググるのでもok)

という座学みたいなものがあり、これと実践的な「初段」の段階との間に「詰将棋のように TDD ~」がある。疑似的に5級までの実践力が養えればいいだろう。

  • 新人が3年目程度のプログラマに
  • 未経験の中途採用が3年目程度のプログラマに
  • 未経験のプログラム言語に対しての学習
  • 中途採用するときの経験度の判別に(3年程度の経験)
  • 中途就職するときの実力披露に(3年程度を目安に)

までの、疑似的な実践(スパーリングみたいなもの)ができればよいかなと。

カテゴリー: C#, TDD パーマリンク