オンライン学習の未来 ー高校生にプログラミングを教えて知り得たこと

学校で習うような物事をインターネット上で学ぶことは、将来的には不可避なことのように思えますが、現状において、多くの人々はオンラインで効率的に学習をしているとは言い難いようです。Sebastian Thrunも、数カ月前のFast Companyのインタビューでこのことを認めています。私はこの夏、高校生に教える傍らソフトウェアを作り、コンピュータがどの程度、人々の学習の役に立つかを検証してみました。

この投稿ではその夏について、つまり生徒がどのように学び、私が作ったソフトウェアがどの程度、彼らの学習の役に立ったか、何がうまくいき、何がうまくいかなかったか、そして次に目指すべきところはどこなのか、について書いていきたいと思います。

カリキュラム

今回の検証の実践の場として、AP(アドバンスト・プレースメント:成績上位の高校生が受講可能な大学の科目)コンピュータサイエンスの講義を選びました。プログラミングは今なお教えるのが非常に難しい科目ですし、プログラミングであれば、例えば地理などに比べると、コンピュータ支援による教育も自然に受け入れられるはずだからです。それにプログラミングは初心者にとって、不必要に不親切でややこしいですからね。

APコンピュータサイエンスは8カ月にわたる講義で、個人講義やGoogleのHangout
を通した対面講義の場合だと約20時間が必要となります。私は天才ではないですし、決定版と言えるような教育法を持ち合わせているわけでもありません。どうしたって学習には時間がかかります。講義において、私が作ったソフトウェアに一定の効果はあったものの(ソフトウェアが改善するにつれて、生徒に対して説明やデバッグ、それに軌道修正の助言をする機会は減っていきました)、それでも生徒たちは都度現れる新しい問題に苦戦しながら学習を続けていました。

College Boardは、APコンピュータサイエンスの講義と学力試験のための標準カリキュラムを提供しています。試験が高得点の場合、公立大学での単位が認定されるため、その分だけ大学在学中の必要単位が少なくて済み、学費を減らせる仕組みです。私立の大学では単位にはならないものの、成績優秀者として認めてもらえます。

APコンピュータサイエンスのカリキュラムは標準化されていますが、大規模なものではありません。Javaのオブジェクト指向プログラミングの導入部で、その範囲はArrayList1までです。平凡で、似たようなカリキュラムや教材、実習はオンライン上に散見されます。私は、それらの中から個人的にいいと思った教材をまとめて、フリーのオープンソースレポジトリとしてまとめました。Teach APCSで公開しているので、ぜひご覧ください。

Javaは初心者にとっては面倒な言語です。その構文は間が抜けていて、見た目は外国語のようであり、必要以上にグラフィックを単調にし、処理が重くなるJava仮想マシンを使わなければなりません。それでもAP試験で出題される言語であることから、多くの学校で教えられています。初心者にとっては、何も学ばないよりはマシといったところでしょうか。

プログラミング言語を取り巻く状況において、生徒たちにとって最も難しいのはJava自体ではなく英語のパズルを解くということでしょう。多くの場合、生徒たちはロジックを適当に扱い、この段階をスキップします。しかし、それではうまくいきません。いったんJavaのことは忘れて、2つの質問”やろうとしていることを英語で表現するとどうなるか”、”それを5歳の子供に向かって説明するには何と言えばいいか”を投げかけてみることが大切です。彼らがその質問を説明できたら(その間は、ワードスクランブルのように全ての文字を精査し、前後の文字を入れ替えてみたりするのも手です)、Javaは容易に出来上がります2

なぜプログラミング?

APコンピュータサイエンスの試験は、高校生にとってはご褒美のようなものですが、美味しいものではないでしょう。講義を受ける生徒は、おおむね2パターンに分けられます。一方はJava以外の言語である程度のプログラミング経験がある生徒、もう一方はコンピュータの理解は乏しいものの、APの修了資格が欲しい生徒です。

私は講義を始める前に、”何でも可能なら何を作りたいか”ということを生徒たちに聞いてみました。

  • 援助が必要な人々を助けられるようなアプリケーション
  • 動画
  • 最高のビデオゲーム
  • タイムマシン
  • 学校の授業が不満な場合、学校が単位を認めてくれるよう自分でその科目を学べるようになるツール
  • 多様な分野におけるネットワーキングを改善するアプリケーション
  • 最小の停車で全米を網羅するような、早くて効率的で安全な列車のネットワーク
  • 患者に苦痛を与えないガンの治療薬

この中の一部のアイデアは、他のものに比べるといくらかはソフトウェア向きと言えるでしょう。ただ、何より驚いたのは、ほとんどの回答が畑違いな点です。”Xが出来るアプリケーションを作るのが夢”だとか”Yのホームページをずっと作りたいと思っていた”というような回答は見当たりません。今日の言語学習ツールは、具体的なアプリケーションやサイトを作ることによって言語を習得するものが多いのですが、講義に参加した高校生たちは、プログラミングで自分たちに何が出来るのかといったことも分かっていないようでした。プログラミングって楽しいかもしれない、という程度の感覚なのかもしれません。

プログラミングは不要?

“プログラミングしなさい。さもないとされてしまう”というゾッとするようなレトリックが、一部の言語学習の取り組みにおいて存在しますが、それはあまりにも馬鹿らしいことです。やりたいことがなければ、プログラミングなんて学ぶ必要はありません。コンピュータは、言わば100年前の電気3のようなもので、決して人を襲うものではないのです。より現実的な観点から考えると、何であれ新しいことを学ぶのには困難が伴うもので、罪悪感(あの時、勉強していれば…)のような動機だけでは不十分でしょう。

ただし、私は学習意欲をそごうとしているわけではありません。ソフトウェアをプログラミングすることは、すばらしい体験となり得ます。そして私が特に強調したいのは、その気もなりさえすれば、誰にだってそれは可能だということです。

メタ学習

総じて、生徒たちの学習速度には驚かされるものがありました。ただ、微分積分をまだ学習していない生徒の方が、習熟が速いように思えました。これは別段、不思議なことではありません。数学の関数や変数とコンピュータサイエンスは、関連しているものの全く同じものではないため、そういった違いをスルーできる生徒は、その点について考えなくて済むからです。

夏の終わり頃になり顕著になったことは、多くのミスをする生徒の伸びが目立ってきたことです。彼らはいろんなことにチャレンジし、間違ったコードをコンパイルし、多くのランタイムエラーを発生させ、REPLを激しく混乱させました。しかし、失敗を繰り返すことで頭の中でより優れたイメージを持てるようになります。そのためコードを実行したときにどのように動作するか予測することができるのです(Xcode PlaygroundsLightTableといった環境で成功した場合に、全てのプログラムを頭の中でトレースするのは隠し芸的ですが、今日では必要な能力です)。生徒は論理的方法で実験を行うことで、コードを用いた問題解決において自信を持つようになります。

当てもなく書き換えを続けることは(つまりは”適当に打ち込んでいけば、いつかうまく動作するだろう”ということ)まったくためにならず、やる気をなくさせるような行為です。プログラミングのそれぞれのコードがどのように結びついているかといった知識を持たずして、コンピュータを理解することは出来ません。いくらやる気がある人でも、現代のプログラミングのツールを使って当てもなく自由に学ぼうとすれば、すぐにイライラしてしまうでしょう。

我々が行ったこと

まずは2時間に及ぶ変数を用いないプリミティブ型のみを扱ったREPLの指導から始めました。プログラミングの土台となる考え方(”なぜ分割がおかしいのか? いつ乱数ジェネレータを起動し、どれくらい待てば乱数を得られるのか? 実際substringメソッドがどのように動作するのか?”)を身につけるためです。

REPLはツールを調査するのに便利な環境です。理由の1つとしては、新しいことに挑戦するのが簡単で、失敗しても何も壊したりすることなくさほど時間もかからないからです。REPLのプロンプトは講義によって洗練され、新たなツールを導入し、入力すべきことを提示します。リターンキーを押すと実験が始まり、すぐにフィードバックが帰ってきます。生徒はあっという間にそれがコンピュータにどう作用するかといったことを学び始めるのです。これは、私が作った自動化されたプロンプトです。
Standalone

REPLには限界がありました。誰もその中では全てのプログラムを再現できなかったのです。そのため我々はエディタ上での単純なスクリプトの記述に移行しました。使用したのは彼らがREPLで学んだツールで構築されたコードスニペットです。下記のようなものです。

int wallet = 100;
System.out.println("I have $100");

while(wallet > 0){
    wallet = wallet - 25;
    System.out.println("Spent $25.");
}

System.out.println("No money left!");

これは理解できるようにgraphicsクラスや視覚的言語、またはステップスルーの評価といったものを用いずにJavaで書かれています。実行前は、このスニペットはmain メソッドやクラスにラップされており、これが唯一の新しい部分です。今回の場合は”while”がそうです。

新たなプログラマにこのコードが何をするか聞いてみると、おそらくこう答えるでしょう。「財布の中にある全てのお金を使い、もうお金は残っていないと伝える」と。また、何回25ドルを使うかと聞くと、4回と答えるでしょう。実際に、スニペットはこのように出力します。

"I have $100"
"Spent $25"
"Spent $25"
"Spent $25"
"Spent $25"
"No money left!"

ここでそのプログラマに、25ドルを使ったらすぐに財布の中身を出力するようコードを改造してもらいます。

"I have $100"
"Spent $25. I have $75."
"Spent $25. I have $50."
"Spent $25. I have $25."
"Spent $25.  I have $0."
"No money left!"

コードを少しずつ変更していくにつれて、生徒は”while”ツールにどんどん慣れていきます。このように少しずつ教えていくことでツールの構築やそれらを使用する技術を学ぶことが出来るのです。

我々は知っているツールでパズルを解いていきました。生徒はMagic 8 BallsBitcoinHangman AIsChatterbotsなどを作成しました。これらは習得したツールを利用して彼ら自身の力で作り上げました。ちゃんと動作もし、大成功でした。これは生徒がFizzBuzzを解く様子を撮った高速ビデオです。
Fizzbuzz

初めの頃、コンピュータの概念はその能力を使って人間の知力を向上させるためのものでした。しかし、一部のコード学習の取り組みはあまり初心者向けではないようでした。問題解決よりも入力することに重きが置かれ、その”問題”というのは変数の名前や値のスワップを扱うものでした。例えば誰かに単一行のテキストボックス内におけるテキストの再入力や編集をお願いしてみてください。彼らは素早くこなすでしょうが、その作業自体は退屈なものです。しかし、ツールを利用してパズルを解くようにお願いすれば、学習は価値のあるものになるでしょう。それがFizzBuzzのような自明なものであっても例外ではありません。

役立つツール

自転車に乗ったことのない初心者は補助輪を欲しがりません。求めるのは乗ることができる自転車です。これと似たように、効果的な初心者用のエディタはないと思います。あるのはプログラマが使用し、初心者でも理解できるエディタです。

残念なことにほとんどのエディタはあまり良い性能ではなく使用法も簡単ではありません。それらの標準的なインターフェースはコマンドラインから借りてきたもので、使いやすくも寛大でもありません。そして何がコードとテキストを区別しているのか教えてもくれません。実際に必要とされるのは高性能で使いやすいエディタです。

誰でも使いやすく、学習者でも分かりやすいエディタをいくつか紹介します。これら全てのデモは私が作った環境で実行しますが、同じ原理をあらゆる所で適用することが出来るでしょう。

コードスニペット

Snippets

すぐに必要なツールを見つけ出せます。それらは種類別ではなく動作別にグループ分けされています。なぜならプログラムを組む上での考え方に近いからです。

見て分かるようにクリックするとサンプルテキストがエディタに挿入されます。(オートコンプリートで挿入されたスニペットも同じように動作します。)プレースホルダ内のテキストは開始場所を教えてくれます。それによりどのように使用するかを知ることが出来ます。

インラインREPL

Repl

エディタに入力するか、コードスニペットを使用すると、そのコードはREPLに読み込まれます。REPLとエディタにおける相互作用によって、より洗練されたコードが入力できるようになります。これは非常に便利で、使えるまでに待つ必要もありません。そしてこの方法で入力したコードを検査することができます。これは他の方法では不可能なことです。

説明機能

Hovers

エディタにある全ての単語はマウスカーソルを当てることで説明文が表示されます。これによりコードの理解をより深められます。そのため言語の用法ではなく実際のプログラミングの構想に集中することができます。無口だったエディタが役に立つガイドに変わります。そしてそれはあまりプログラミングに馴染みのない人々にとって特に有効です。しかし、これは正式な説明とはなりません。仮にstaticメソッドについて聞いたことがないのに、それを使用しなければならなくなった場合、この機能による説明ではおそらく不十分です。ですが、膨大な難しくて混乱を招く使用法の説明を読むよりもこの機能による説明のほうが学び始めるものとしてはより有効です。

変数エクスプローラ

Varexplorer

生徒たちにとって特に厄介だった2つの概念が”変数”と”変数スコープ”です。これまでの環境では変数ボックス背景に色を付けたメソッドを使用していましたが、私の経験上、どちらも適切ではありませんでした。恐らく、エクスプローラに変数を直接表示する方法が最も分かりやすいのではないでしょうか。そうすることで、表示されているヘッダから環境が変数と値をトラッキングでき、計算処理はコンピュータに委ねられます。

バグとエラーの解釈

Compilerish

バグとエラーはその内容が理解できれば、何かと役に立ちます。理解するためには、大抵の場合コンパイラ言語から英語にテキストを解析しなければなりません。講義では、これが生徒たちにとって大きなフラストレーションになりました。”プログラムに問題があるのは分かるけど、どこがまずいのかが理解できない”と愚痴られたものです。コンパイラがコンパイラ言語を使用するのには理由がありますが、我々人間には関係のないことです。これからコンパイラを学ぼうとする初心者なら、なおさらそう思うでしょう。

クラスとスプレッドシートの比較

クラスは最初の頃、何のためにあるのか分からなく感じるものです。そこで、誰もが理解できる例えとしてスプレッドシートを使いました。クラスがシート、その属性が列、インスタンスの構築が行への入力に相当します。例えば、これが単純な例です。


いくつかインスタンスを作成してみました。


さらに一歩前へ

講義が回を重ね、構築が進んでくると、発想はシンプルになりました。プログラムがどのように動くかを見せ、体系的に考えるように促すと、生徒は自分の力で学ぶようになります。そして学ぶためには論理的に考え、積極的に新しいことを試し、失敗しながらその試みから立ち直る必要があります。多くのプログラミングツールはその助けになっていないのですが、本来はそうあるべきです。飲み込みの早い学習者は自力でそれを行っています。

私はオンライン教育の将来には楽観的です。科目を超えて出来ることがまだたくさんあるでしょう。オンライン教育なら生徒を夢中にさせ、好奇心をくすぐることが出来ます。夏の講義でも、生徒にパズルを解かせたことが、良い結果を生みました。しかし、これは何も新しい考えではありません。数学者でもあり発達心理学者でもあるSeymour Papert氏が名著『マインドストーム—子供、コンピューター、そして強力なアイデア』を出版したのは、なんと1980年の話です。しかし、この理論はさらに突き詰める余地がある気がします。この夏の講義も、そのいい機会であることが分かりました。オンライン学習はまだ黎明期にありますが、どうすればうまくいくかはすでに見えてきています。そこで講師が何をすべきかは、生徒たちが教えてくれるでしょう。


私の講義はGirls Who Codeのサマーキャンプに出席し、引き続き受講を希望した者には無償で、Craigslistで私の広告を見て連絡をしてきた者には有償で提供しました。また、TEALSを通じてサンフランシスコの公立高校でAP コンピュータサイエンスの授業補助も行っています。講義の一部にはJava、Pythonに関する内容が含まれますが、全てTeachAPCSの教材に準拠しています。


  1. 他に何があるのか気になる方がいらっしゃるでしょう(ごもっともです)。それほど多くはありません。かつては検索、ソート、(予備的な)ビッグ・オー記法、ハッシュ、LinkedListなどもありましたが、College Boardが全て除外しました。というのも、試験を受ける生徒がほとんどいなかったからです。しかしこれは語弊があります。これは生徒が悪いわけではなく、そもそもこれらについて教える講師がほとんどいなかったのですから。 

  2. プログラミングを始めると、いかに人間の直感が優れており、コンピュータがそうでないかを早々に実感するでしょう。たとえば、リスト内で隣り合う2つについてのやり取りを見れば、お分かりいただけるはずです。
    「2つは互いに隣り合っていますか?」
    「2つが隣り合っていることはどうやって分かりますか?」
    「(互いに隣り合っているからですか?)」
    「リストの順番にすでに入っていたらどうなりますか? その場合、互いに隣り合っていることはどうやって分かりますか?」
    「リスト内の2つの位置は1回限りですか?」
    「了解しました。しかしそれはどういう意味ですか?」
    「リストの位置2にあるものの隣は何ですか?」
    「位置1と3にあるものですか?」
    「つまり、位置番号に1を足したものと1を引いたものですか?」
    「了解しました。その場合は…」 

  3. この分野に興味をお持ちなら、Ernest Freeberg氏の『The Age of Edison: Electric Light and the Invention of Modern America』をお読みになることをお勧めします。ほんの一部を抜粋してご紹介しましょう。

    電気技師は電気に関して人々がいかに無知かをよく揶揄したものです。しかし、この産業で働く者の中には、そうした無知を決して笑いごとではないと考えている者もいました。電気について生半可な知識しかないジャーナリストや政治家は電気会社に無茶な要求をし、電力業界に関する人々の恐れや怒りを引き起こすからです。彼らにはもう少し知識が必要でした。そこで、多くの業界のリーダーたちは電気技師やエンジニアに対する技術的なトレーニングだけでなく、高校のカリキュラムにまで電気技術の授業を組み込むことを求めました。こうした”より広範な教育”によって、多くのアメリカ人が電気について学ぶチャンスを得られ、電力に対する人々の言い知れぬ恐怖は収まりました。…
    この”崇高な使命”から[電力]業界が得られるものも多くありました。というのも、若者の意欲をかきたてることで、電力業界の発展に貢献できたからです。21世紀になると、電力関連のビジネスに携わる者が100万人に迫り、電気と電力は国内最大規模の、最も急成長を遂げた産業となったのです。進歩主義の教育者は電力会社に優れた人材を送り込むことに注力しませんでしたが、アメリカの全ての学生が少なくとも技術教育の基礎を学ぶべきであることには同意していました。