kagamihogeの日記

kagamihogeの日記です。

ステップバイステップ・プログラミング教育

新人への業務指示 を見てちょっと笑ってしまったが、プログラミングの教育という点からみると少々興味深い事例でもある。

俺が新人に対してプログラミングの初等教育をする際に取る手法の一つに、脳内で「ステップバイステップ」と呼んでいるものがある。この手法は、新人が何かしらの練習問題を解いていて、詰まってしまったか何かで質問された時に用いる。

何をやるかというと、実は俺自身は何もしないw

まず、新人に対してどんな練習問題を解こうとしてるのかを本人の口から説明してもらう。次に、問題をヘンな風に捉えてないか、どんな風に解こうとしてるか、どこまで出来てるのか……新人が何を・どのように理解しているかの「理解度マップ」を自分の脳内に作っていく。数十行で終わる練習問題ならざっとコードを見ることで、今どんな状態かだけはつかめる。ただ、理解度マップを作るには本人の口から直接聞かないと中々難しいものがある。

「どんな問題を解こうとしてるんだい? ちょっと説明してみてくれないかな」
「なんでこういうアルゴリズムにしようと思ったんだい? ちょっと説明してみてくれないかな」
「このコードはなんでこうなってるのかな? ちょっと説明してみてくれないかな」

質問の仕方は基本的に「ちょっと説明してみてくれないかな」という形式になる。なぜこうした質問をするか? こうした質問をする他者に対しては自分の頭の中で色々考えないと答えることが出来ないから。これの繰り返しにより、新人が今・何を・どのように把握してるかを自分の理解度マップに少しずつ埋めていく。

新人が混乱してるようだったり、理解が足りなくて困ってる様子だったら、理解してる/理解してない等の Yes/No二択型で答えられる質問に切り替える。質問の仕方はあまり変わらない。異なるのは、より対象を絞った質問形式になる。

「練習問題は『1 から 100 までの数値を足した結果を求めなさい』か。数学の公式はおいといて、for 文を使わないとダメそうだな、ってのはわかる?」
「どんな風に解けばいいのか、大雑把でいいからまとまってる?」
「C でコンソールから入力値を受け取るにはどんな風にやるんだったか覚えてる?」

さっきから繰り返してるけど、まずは自分の脳内に新人の理解度マップを作る必要がある。理想的には、新人が、いつ・何を・どこで・どのように理解したかを把握しておきたい。あと、誰がいつ何をどんな風にどんな内容を教えたのかを知ることが出来ればなおよい。

まぁ、現実的にはそんな時間を取れることはまずないので、ある程度把握できたらコードを一緒に見る。ある程度コードが出来てるなら、

「じゃあ、コードを動かしてみようか。……確かに期待通りの結果にはなってないね。なんでだと思う?」

この段階で直ぐに答えにたどり着くケースもちょくちょくある。科学的見地には疎いが、人間というのは、誰かに何か話してると脳内で勝手に整理されていくことが結構あるらしい。……厄介なバグの内容を誰かに話してると自分で勝手に納得して自席に戻ってくヤツいるよねw*1

この段階でもやることはあまり変わらない。まず大雑把な質問をして、必要に応じて細かい質問に切り替えていく。ケースバイケース&ステップバイステップ。100 行ぐらいのコードならざっと見ればヤバい場所は大体わかるので、

「この変数ってどんな役割持ってるの?」
「ここのコードって、どんな動作してほしくてこういう風に書いたんだっけ?」

大前提として「ココがダメ」と直接は言わない。あくまでも「俺はここがヤバいと思うんだけど、君はどう思う?」という態度を装う。何故すぐに正解を教えないのか? これはあくまでも自力で答えにたどり着いてもらうための措置。そうしないと身につかないし、達成感が得られないからね。

あとは、随時ちょっかい出す。

「ちょっとここまでばばっとコメントアウトしちゃおうか。……お、これはここまで動くみたいだね。今、君はここをコメントアウトしてこの部分動かないようにしたんだけど、その結果、なんでこんな動作になったと思う?」
「ここでブレークポイントいれるか printf で値見てみようか。……ちょっと予想外の値が出てるみたいだね。ちょっとコードの動きをトレースした様子やって見せてくれる? 紙の上でいいからさ」

何をしたら何が起きたのか。これを逐一説明してもらいながらコードを書いてもらう。極端な話、一行変えたら一回実行する度に「今、君は何を変えたっけ? それで、何が起こったっけ?」と質問するぐらいの勢いで良い。俺がこの手法を脳内でステップバイステップと呼んでるのはこの辺のやり方に由来している*2

もし新人が「ここってこうすればいいんでしょうか?」と言ってきて、それが間違っていてもそのままやらせる。目論見どおり(?)失敗したら「あーダメだったなぁ、んじゃなんでダメだったのかわかるかい?」とステップバイステップの質疑応答を繰り返す。

まぁ、大抵の人はここまでやらなくても、途中で「把握した!」って状態になるんで、後はひとりでじっくり取り組んでもらえばいい。躓いてまた助けが必要になったら「なんでダメだったと思う?」からはじめる。

つまるところ俺は何も教えない。ただ横に座って「なんでだと思う?」「ライト、ついてますか」と繰り返すだけ。要領良い子なら 2,3 の質問で結構な成長見せてくれるんで楽ですな*3

プログラミングは失敗したところでそう簡単に物理破壊起きないんで 新人への業務指示 と事情は違うんだけどね。もしプログラミングの教育っぽくやるんだったら俺だったらこうすると思う。

俺「パン焼いて皿に載せて食べて」

父: 皿に載せたパンをトースターに入れる→火事

俺「トースター爆破してしまったなぁ。なんで爆破しちゃったと思う?」
父「わからない」
俺「そうか。実は、皿に載せたパンをトースターに入れると『爆発しろ!』って言われてしまうんだ。じゃあ、どうしたらうまくパン焼けると思う?」
父「つまり、トースターにはパンを皿に載せずに入れればいいのか」
俺「よし。じゃあそれでやってみようか」

父: 素手で皿をつかもうとする→火傷

父「火傷してしまったんですが」
俺「ふむ。なんで火傷してしまったと思う?」
父「熱っされた皿を素手でつかんでしまったからか」
俺「そういうこと。じゃあどうしたら火傷せずに皿をつかめると思う?」
父「何か、別のものを間に挟めば……」
俺「そうだな。直接つかむのは、マズいみたいだよな」
父「なるほど。このなべつかみを使えばいいのか」

リアルで例えると「失敗すんのわかってんなら止めろよwww」というギャグにしかならんなw

失敗するのを見届けて、何故失敗したのかを説明させて、じゃあどうしたらいいのかを質問して、自分で考えてもらい、それでダメそうだったら助言する。頭ごなしに言い聞かせず、正解をいきなり教えず、「自分の成功」を導き出してもらう。そのためには相手の「理解度マップ」の構築が必要で、マンツーマンでコードを教える手段に「ステップバイステップ」を使用する。アジャイルな考えを流用したとも言えるのかな。ちょっとの成功を繰り返すことでおおきな目的を達成する、というのをプログラミングの初等教育に流用した、とでもいうべきか。

ちなみに「なんで出来ないの?」はマジ禁句。これほど大威力のスターライトやる気ブレイカーは他に知らないです。元増田も書いてるけど、絶対服従の奴隷作りたいならこれほど便利な言葉は無いかもしれない。人間って激しい抑圧受けてる状態だと、他人から強く命令されるとカンタンに従っちゃうらしいからね。

ただ……そんなプログラマー育てても何にもならないからなぁ。

*1:「このバグはここがこうなっててさ、あれがああでアッー! わかったよありがとう!」とかそんな感じ

*2:まぁひがさんが Teeda 関連で使っていた「ステップバイステッププログラミング」という言い回しのパクりでもあるんだけどw

*3:大抵の子は丁寧に質問繰り返してあげればそこそこ出来るようにはなるけど……やっぱり根本的にプログラミングに向いてないなぁ、って子はいる。ただ、Algol 系の言語に向いてないってだけで他の言語だと別かもしれないから難しいんだよなぁ。Lisper なんてぜんぜん文化違うし。それと、コの業界でも QA とかシス管とか激しくコード書かない仕事には向いてるかもしれないんで、カンタンにこの業界で生きていくのあきらめて欲しくないなぁ……とか思います。結局は色々やってみてその結果自分がどうしたいか、ってことになると思うんだけどね。