夏休みだから、30人の中高生にPythonを教えてハッカソンをやってみた : 情熱のミーム 清水亮

誤解なきように言っておくと、僕は故郷に錦を飾りたいと思うタイプではない。 まあいくらそう言っても信じてもらえないだろうが、根本的にそういうものには興味がない。 なぜなら長岡の偉人は誰も故郷に錦など飾っていないからだ。 山本五十六はもちろん、阪神タイガースの生みの親と言われ、アサヒビールの創業者である外山脩造も、月刊アスキーの黄金期を築いた遠藤諭も、特段、そういうことをしていない。そうした人々の情熱や愛情は狭い郷土だけに注がれるべきものではなく、我々が生まれ育った日本、広くは世界人類のために注がれるべきものだからだろうと考えている。 だから積極的な誘致の話がなければ絶対に地元である長岡市でなにか商売をやろうとは考えなかっただろう。なにせ僕の会社には新潟出身の人間はほとんどいないんだから。合理性がなければやらない、というのは最初から決めていた。 しかし地元からの強いラブコールと、そして昨年日本で初めて開催された40歳成人式(大成人式)に伴い開催された中学の同窓会とに後押しされて、地元に会社を作り、地元で人を育てる事業に取り組むという決断をした。 この頃、僕自身は日本だけでなく世界各地に人工知能のためのデータ作成人員を養成し、機械学習向けのデータ作成やスクリーニングの一切を行う学習データ工場の候補地を検討していた。ベトナムやタイ、沖縄や島根県という候補地があったが、結局地元にしたのは、そうした場所に比べて地の利、すなわち東京からそれほど遠くなく、なおかつ移動に気候の影響を受けにくく、土地が安く、成長産業が少ないが若者の人口がそれなりにいて、行政の積極的な支援も期待できる場所として長岡を選んだ。極めて合理的な判断に基づくものである。 僕の実家はとうになくなっており、長岡に戻る理由もなく、基本的にはこちらではホテル住まいである。 ただ、小中高と過ごした場所であり、当時の友人もみんなそれなりにいい大人になっているので、横のつながりが最初からあるのは大きい。 それに土地柄や気質に自分自身が精通しているので、全く知らない土地に比べたらかなりやりやすいと考えていた。 今回の教室も、最初は行政から誘われたものだったが、これまで無料で開催していた教室とは違い、敢えて有料の講座とした。 というのも、それまで無料で開催していた講座は、そもそも同時に教えることのできる子供の数が限られている性格上、抽選になるのが常だった。それは学びたいという熱意とは無関係に無作為に選ばれるわけで、たかがクジに外れたくらいで貴重な教育機会を奪われる子供がいると考えると胸が締め付けられる思いだった。 加えて、昨年、やはり中高生向けに長岡造形大学で行った深層学習プログラミング講座では、GPUを搭載した専用の機材を使用したが、せっかくワークショップで一通りのことを覚えても、家に帰ったら続きができないことを悔しがる子どもたちを見て、自分は実はとても残酷なことをしたのではないかと自責の念にかられた。 そもそも優秀な子供が育つには2つの必要条件がある。 一つは、子供自身の熱意、もう一つは環境である。 子供にとって環境とは、両親の態度や考え方によって大きく左右される。どれだけ素質と才能のある子どもであっても、両親が無理解ならば決してその才能が開花することはない。残酷だが、子供は平等ではないのだ。 そこで、まず子供を選抜する前に、本格的なプログラミングを学ぶ機会を与えようとする環境があるかどうか、要は両親が本当に子供がプログラミングを学ぶことへ投資する気構えがあるのかどうかを問わなければならないと考えた。 また、わずか数日のワークショップのあとで、自宅に帰ったらマシン(環境)がなくて続きができないという状況を回避するためには、どうしてもマシンそのものを講座と同時に買い与える必要がある。 そこで、地元ではかなり高額と言われた、教材費7000円、受講料6000円、合計1万3000円という価格設定に挑戦してみた。定員は30名。 少し計算すればわかると思うが、仮に教室となるスペースを無料で借りることができたとしてもギリギリである。満席になっても18万円で三日間というのは、3で割れば一日6万円でしかない。東京から講師を呼んで、アルバイトや社員の人件費として回すことを考えても損しかない。 それでも数百円でも黒字が出るようにしなければならないと思った。 そうしないと、合理性を考えて継続することができないからだ。継続できない教育プログラムは不公平だし、不健全でもある。 イベント単体でみれば黒字でも、トータルで見ればまだ赤字である。 テレビCMやFacebook広告、そして教育委員会の協力を得て、全ての中学校、高校にチラシを配った。印刷代もかかる。 市の職員の方からも「地方の習い事としてはかなり高額なのではないか」という指摘があったが、果たして、実際には満席でキャンセル待ちを多数抱える結果になった。 今回の教室では、ラズベリーパイ3を教材として使い、Pythonをいきなり教えるという挑戦的なものだった。 果たしてそんなことが本当にできるのかといえば、昨年の経験から、Pythonのコードを写経するくらいならアルファベットが読み書きできるレベルの子供なら可能であることを確認していた。 次の問題は、わずかな期間で写経しただけの状態から抜け出せるかどうか。もっといえば、「プログラムを自分の道具として使いこなせるか」である。 そこでハッカソンをやることにした。 子供を対象としたハッカソンはenchantMOONで何度も経験がある。 子供は道具と使い方を教えると、自動的に自分の表現したいものを表現しようとすることは確認できている。 初心者がプログラミング言語の文法や仕組みを厳密に覚える必要は全く無いと僕は考えている。 僕自身、自分が書いているプログラムの意味を完全に理解したのは、プログラミングを初めて10年ほど経ってからである。 ここ一年通っているパーソナルジムのトレーナーの先生はオリンピック強化委員を務めるほどのベテラン選手だが、彼が中学の陸上部で最初に短距離走を走るようになってから、自分の納得の行く走りを獲得できたのは、10年掛かったという。 プログラミングだけが例外であるわけがない。 しかし、日本語の文法を完璧に知らない子供でも日本語を話せるのと同じように、プログラミングの文法を完全にしらなくてもなんとなく雰囲気でプログラムを書いて表現していくことを繰り返すうちに覚えてくれるのではないか。 そういう期待があって、敢えて彼らを千尋の谷に突き落とすことにした。 プログラミングを子供に教えやすいように、長年研究を重ねてきたenchant.jsのノウハウをそのまま使える、enchant.pyというライブラリを作り、この上でPythonの文法を教えることにした。 自画自賛になってしまうが、この作戦は正解だったと思う。 なぜなら僕も講師の後藤も、enchant.jsでのワークショップは無数にこなしていた。 また、子供の興味や関心を引き出し、ごく自然にベクトルを理解させるのにうってつけな手法だと考えているからだ。 最初はラズベリーパイの組み立ての方法(家に帰った後でちゃんと組み立てられるように)からスタートして、Pythonを解説し始める。 するといきなり異変が起きた。 彼らの理解が僕の予定よりも早すぎるのだ。 そこで予定していた内容の三倍程度の内容について解説する必要があった。 Linuxのコマンドラインの解説から入ったが、最終的には素数を数えるプログラムを教えることになった。 素数がすごい勢いで出てくることに子どもたちは興奮していたようだった。 そのプログラムの出力をgrepしてwc -lすると、「2が含まれる素数」の数や「10000未満の素数の数」が瞬時に得られることに驚いていた。 確かに、コンピュータが計算機として本当に凄い、ということを実感できる機会は少ない。 この素数に関するプログラムもまた、僕自身が中学1年生の最初の数学の授業の宿題で書いたものだった。 数学の先生は進歩的な先生で、「宿題として、1から100までの素数を書いてきなさい。ただし、プログラムを使って解く者は1から10000までの素数を書いてきなさい」という出題だった。僕は興奮した。プログラムを道具として使って学校の宿題をやっていいんだ、ということがわかった最初の瞬間だった。 午前中は素数で盛り上がってそのまま終わった。 午後はいよいよenchant.pyである。 enchant.jsのシンボルとも言えるクマの絵を出したとき、ある生徒が言った。 「あ、おれこのクマ知ってる!」 彼は何年か前にenchantMOONのハッカソンにも参加したらしい。 一通りの説明をしたあと、僕は驚いた。 彼らは写経したあと、パラメータを勝手に変えて遊び始めたのだ。全く自発的に。 実はこういうことは、都内で行うワークショップではなかなか起きない。 だいたい、親御さんがマンツーマンでいることが多く、子供はあまり自分の好きに遊ぶということがない。 今回のワークショップでは親御さんが隣に座れるスペースが全く無いほど密集していたため、子どもたちは数字をいじったり違う絵を表示させたり、勝手にテキストを先読みして三角関数を書いたりと、都内ではまず見られない行動をとり始めた。 なんだろう。いつも不思議な気分になる。 その日は無事終わり、翌日二日目、「鬼ごっこゲーム」と称して、イベントドリブンやクラスの継承、オブジェクト、といった概念を説明した。さすがにいきなり難易度が上がったので、質問の手が次々と上がった。 この日、初めて試したのはプログラムの音読である。 タイプミスを見つけるためにはプログラムを音読しなければならない。 初日は極めて些細なタイプミスに関する質問が多く、二日目もそれが続いた。 そこで、デバッグをするときにほとんどのプログラマーが行う、「コードの音読」をやってみた。 英語の授業のようだ。 「リピート、アフター・ミー。フロム・スペース・エンチャント・スペース・インポート・アスタリスク」 括弧の始まりを「カッコ」、終わりを「コッカ」と呼ぶプログラマー独特の呼称も教えた。 僕を含めた四人の講師はフル稼働で、次々と子どもたちの疑問や質問に答えなければならなかった。 そしてそうした疑問の数々は、極めて的確でもっともなものだった。 その分、僕たちもかなり真剣に取り組まなければならなくなった。 へとへとになった昼休み。 僕は、今回最も大きな挑戦を始めることにした。 「よし、これからハッカソンをやろう」 ハッカソンとは、ハッカーのマラソンである。 つまりブログラムをひたすら書く会合のことだ。 テーマは「花火」にした。 地元では花火大会直前で毎日のように北島三郎の能天気な歌声が商店街に流れているし、花火を楽しみにしている子供も多い。 しかし花火はテーマとして少し難しすぎたようだ。 最初は全員が腕を組んで考え込んでしまった。 いまからでもテーマを変えるべきか・・・ そう思うほど沈黙が流れた刹那、猛烈なキーボードのタイプ音が聞こえ始めた。 それぞれがとにかく自分の頭の中にある「花火」のイメージを、この二日間で学んだ知識でどのように表現できるかを模索し始めたのだ。 しかしここからが戦争だった。 次々と質問の手が上がり、僕たちは軽くパニックになった。 「こんなことがしたい」「こうするにはどうすればいいのか」そんな質問が矢継ぎ早に飛び、僕自身の脳もフル回転させなければならなかった。予想外のアイデアが次から次へと飛び出すのだ。 子供は発想が柔軟だというが、それにしても、こんなにも積極的に質問が飛び交うとは予想できなかった。 「できた!」 二時間後、一人の子供がそう叫んだ。果たしてそれは、確かに花火だった。 スプライトを八方向に分裂させ、見事に「花火」を表現していた。 彼を壇上に招き、みんなの前で作品を発表してもらった。 ハッカソンが予想よりも遥かに盛り上がったので、僕たちはヘトヘトになっていた。 最近、経営者としてどちらかというとスピード感を落とすように意識していた。 というのも、経営、特に契約や資金調達といったものは、焦ってはうまくいかないからだ。 現役のプログラマーだった頃のように、一人で次から次へと実装するのとはわけがちがう。 相手のペースにあわせて辛抱強く行動しなければならない。 それは人材獲得や会社としての投資判断に関しても同じで、とにかく人間が絡む以上、自分と同じ反応速度を求めては仕事にならないのだ。 それに比べると、やはりプログラマーというのはやればやるほどスピードが上がっていくので、こちらはついていくのがやっとだった。小さなプログラマーたちの思いや勢いを僕たちはたった四人で受け止め、跳ね返さなければならなかった。 ひとつ思ったことは、「これは素晴らしい教育機会だ」ということだ。 なにより自分が鍛えられる。常に子どもたちに対して誠実であろうとすればするほど、自分の中のプログラマー魂が試される気がした。 つまり、相手は子供だからいくらでも誤魔化しができてしまう。しかし、誤魔化さない、と決めた瞬間、極めて複雑で高度な概念を正しく簡潔に子供に伝えるという「あたりまえ」のことが途端に難しくなる。 全てを瞬時に伝えることはできないが、あとで振り返って本当に深い理解が得られたときに「あのとき先生が言っていたのはこういう意味だったのか」とわかるような教え方をしなければならない。そういう記憶は長く一生残るからだ。 あまりに疲れたので酒を呑むのも程々に眠りについた。 開けて朝、予定を変更して朝イチからハッカソンを継続することにした。 というか、朝8時30分に会場につくと、もう子どもたちは昨日の続きを始めていた。 小さなハッカー達に情熱の火が灯ったのだ。 予定より30分早く授業はスタートした。 そこからは本当に戦場だった。 二日目はチーム戦をやることにした。 三人一組で共通の課題について取り組む。テーマは「夏」だ。 プログラミングがなぜ素晴らしいか。 なによりも、複数の人々が協力する最良の方法なのだ。 そのためにクラスの書き方から教えた。クラスを書くということは、プログラムをモジュールに分割し、作業を分担するということだ。 とはいえ、果たして本当に作品めいたものは完成するのか。 昼休みもそこそこに、子どもたちは熱中し続けた。僕たちは戦い続けた。 結果、できあがったものは、素晴らしい作品たちだった。 ▲目隠しをしたクマがスイカ割りをするゲーム。秀逸なのは、矢印キーの動きが逆になっていることと、歩いた歩数が少ないほど点数が高くなるようになっているところだ。 ▲三角関数を使って不思議な動きをするクマが逃げるスイカを追いかけるゲーム。サンプルプログラムを「遊んで」改造した結果、「追いかける」から「逃げる」に発想の転換をした。 ▲海を表現したアニメーション作品。ドット絵で「魚」と書かれた魚が縦横無尽に泳ぐ。僕の作ったライブラリのバグを利用して、多彩な表現を行っている。まさにハックだ。 ▲弾幕ビーチバレー。当たり判定が自機の直前にしかないので、必然的に弾幕をすり抜けて敵の眼前に切り込む必要がある。 ▲花火のアニメーション作品。限られた時間で見事にアニメーションを表現した。 ▲丁寧に書き込まれた金魚が画面を踊る金魚すくい。金魚はきちんと枠の中で跳ね返る。枠に当たると移動ベクトルの成分を反転させるというアイデアを自力で思いついて実装した。 僕が開催するハッカソンでは、必ず評価をつける。その評価のポイントは、ピアレビューだ。 ハッカソン後に15分間、他のチームの作品を遊ぶ時間を設けた。「かならず全ての作品を体験すること」という条件を出したが、みんな一様に楽しそうだった。 そのハッカソンの苦労はそのハッカソンを経験した人間だけがわかる。 したがって、僕は評価に一切関与せず、全員の多数決で一位を決定する。 優れた仲間を適切に評価することの大切さを教えたかった。 一人あたり二票もっており、自分のチーム以外に投票できる。 その中でも30人中24人が「面白い」と手を上げた作品がこれだ。 このゲームは、夏野菜であるキュウリを投げ合うゲームだが、敵のほうが数が多く、投げるスピードが速い。プレイヤーは障害物として置かれたスイカを盾にして、敵を狙い撃つ。 非常にバランスよく出来たゲームで、しかも僕自身がenchant.pyのバグに気づくことになるほど、ライブラリの性能を限界近くまで引き出した作品でもある。 子どもたちの人だかりや、表情を見て、僕はこのハッカソンが成功したと感じた。 教え方の面や運用の面で課題も多かったが、継続していくべきものだと思った。 なぜ、こんなことをやらなければならないのか。 ひとつは自分自身を磨くためだ。 この三日間ほど学びの多かった日はそうそうない。 これはやった人間だけがわかることだと思う。 そしてもうひとつ、「教える」ということは、インターフェースを設計するということであり、リアルタイムで考えるということである。これほど効果的に「プログラミングで人間を拡張する」インターフェースを研究する方法が他にどれだけあるだろうか。 紙にいくら格好の良いスケッチを書いても、モックを何個作っても、それが本当に使えるものでなければ意味はない。 僕は人工知能を人間が当たり前に使いこなす方法を見つけるため、これを続けなければならないのだと思った。 そして全くの初心者やこれから人工知能と暮らしていく子どもたちが、何を欲し、何を期待しているのか、どうすれば彼らの興味を引き出し、どうすれば彼らが手足の如くAIを使いこなせるようになるのか。 先日、enchant.jsはスピードが遅い、という批判をFacebookで頂いた。 しかし当然、enchant.jsの持つ価値は実行速度ではない。 実行速度だけを求めるなら、Unityを使えばいい。 今回改めてenchant.jsのモデルを踏襲したenchant.pyを実装してみて、このイベントモデルの秀逸さに関心した(※enchant.jsは僕が設計したのではなく、当時の学生アルバイトが設計している)。 Flashのイベントモデルを踏襲してはいるが、ずっとシンプルでエレガントである。 プログラミング言語やフレームワークの設計は、インターフェースの設計が鍵である。パフォーマンスを優先すると、どうしてもインターフェースが疎かになりがちだ。 正しいパフォーマンスを実現するメカニズムも重要だが、インターフェースはもっと重要だ。 今どきスプライトが何個とかポリゴンが何億枚とかで自慢する時代はとうに過ぎている。これからの時代に必要なのは使える人をできるだけ多く増やすということだ。 enchant.jsやenchant.py(とはいえ内部的にはpygameのラッパーなのでそれなりに速い)のパフォーマンスに不満を抱いたとき、他のフレームワークを学ぶきっかけになる。それはそれで素晴らしい動機づけだ。 僕が子供の頃、BASICのパフォーマンスに不満を抱いて、C言語やマシン語を勉強したように、子供はいつか成長して、小さくなった服を脱ぎ捨て、大人にならなければならない。それを繰り返しているうちにようやく一人前になれる。 僕の思う「プログラミング教育」は職業プログラマーを養成することを目指していない。 そんなことには意味はない。どうせ職業としてのプログラマーの寿命は長くないのだ。 自転車に乗るくらい簡単にプログラミングができるようになることが目標である。 つまり少し練習すれば、人類の大半が使えるようなものになることが目標だ。 そしてもしも仮にそれほどプログラミングが簡単になるとすれば、そこから得られる効果は、モータリゼーションの比ではない。 プログラミングというのは、人類が時間や空間を超え、知恵をあわせて協力することを実現する最強の手段である。 これまでのエリート教育とは、競争させ、生き残らせることで「一部の人間」を選抜する方法だった。 それは、知識や経験をネットワークやハードドライブ経由で共有することができない、人間という「かよわい」生き物の中から優れた少数のリーダーを見つけ出すためには有効な方法だったかもしれない。 しかし今や、人間はスマートフォンを通して常にネットに接続され、あらゆる叡智に瞬時にアクセスできる手段を持っている。 プログラミングを学ぶということは協力して知恵をあわせる方法を学ぶことと等しい。 実際、我々は原理をよく理解していないモジュールをしばしば使うことが少なくない。やればわかるが、原理を理解する必要性が出てくるのはトラブルに遭遇したときだけだ。 そしてプログラミングをすると、真に創造的な思考と、退屈で苦痛でしかない単純作業の両方がプログラミングには含まれていて、できるだけ前者だけに集中できるよう単純作業を省略するべきだとわかる。それが省略されたものが、ライブラリでありフレームワークであり、オープンソースであると言える。 つまりプログラミングを学べば、全員が能力を強化できる。競争のための手段ではなく、協力のための手段として、プログラムを使うことができる。これはもっと多くの人、それこそ、職業プログラマーではない人たちにこそ知ってほしい事実だ。 プログラマーの考え方を様々な分野に適用すれば、きっとそれまでよりもずっとマシで、効率的で、創造的なことに集中できる方法が見つかるだろう。 まあ誇大妄想かもしれないが、それくらい能天気に考えなきゃ、やる気も出ないよね。