プログラミングの勉強をどうすれば良いか
以前に「何かを教えるという行為について」自分なりに注意していることなどをまとめた。とはいえ仕事で関わる相手は、それなりの知識があるという前提条件の下で会話している。Javaについてにしろ、SQLにしろ、浅瀬には足を入れてるくらいの感覚だ。
そんな今日この頃。X(旧Twitter)で「コードは半角英数で書く」という前提がない初学者を観測した。個人的にこの事実は目から鱗であった。そういう初学者にとって、「全角も半角も書きたいことは同じじゃないか!」という理解なのかもしれない。しかし、人が書き下したプログラムを機械語に翻訳するコンパイラにとって、全角と半角は全く違うものであるはずだ。
おそらく、そういった知識や感覚はITと関わってこなかった者には存在しないのだろうと思う。ここで考えたいのは、「そういった知識や感覚はどうやって培われるのか?」という問題だ。
今、自分がIT分野で働くことができているのは、それらの ”感覚” があるからこそだと思っている。その ”感覚” を明確に言語化すると、下記の通りではないだろうか。
- 数学的思考
- プログラミング的思考
数学的思考
さて『数学的思考』とはなにか。数学の点数が良い人の特徴である「公式をたくさん覚えている」とか「計算が速い」といった要素は、あくまで数学の問題を解く上での便利ツールに過ぎないはずである。『数学的思考』ではない。
ここで文部科学省が提供している資料幼稚園、小学校、中学校、高等学校及び特別支援学校の学習指導要領等の改善及び必要な方策等について(答申)(中教審第197号):文部科学省』から紐解いていきたい。
こちらの資料によると、小学校~高校生にかけて育成を目指す『思考力・判断力・表現力等』について、『数学的に考察する力』『数学を活用して論理的に考察する力』といったような記述がある。
これは結局どういうことかといえば、日常生活や社会の事象を数学の世界に落とし込むことで、数学の問題を解くのと同じような道筋で解決に導くことができる……そういったことができるような力を身につけることが、高等学校までの教育では期待されているのだ。
【高等学校】
◎ 数学的な見方・考え方を働かせ、本質を明らかにするなどの数学的活動を通して、数学的に考える資質・能力を次のとおり育成することを目指す。① 数学における基本的な概念や原理・法則などを体系的に理解するとともに、事象を数学化したり、数学的に解釈したり表現・処理したりする技能を身に付ける。
② 事象を数学を活用して論理的に考察する力、思考の過程を振り返って本質を明らかにし統合的・発展的に考察する力や、数学的な表現を用いて事象を簡潔・明瞭・的確に表現する力を養う。
③ 数学のよさを認識し、数学を活用して粘り強く考え、数学的論拠に基づき判断したり、問題解決の過程を振り返って評価・改善したりする態度を養う。
詳しくは資料を確認して欲しいが、ひとまず本記事で語りたい『数学的思考』というものは「難しい数学の問題を解ける」という類いのものではなく、現実の問題を数学の世界に落とし込み解くことができるといった類いのものだ。
実際に社会で役立っているプログラムは、現実の情報をコンピュータでも扱えるデータに落とし込んで操作している。日本人全員に割り振られるマイナンバーが良い例だ。個々人を名前や性別といった情報ではなく、割り振られた数字で区別した方が、コンピュータとしては間違いがなくやりやすいのだ(名前だと同姓同名とかあるし)。
そういったコンピュータでも扱えるデータに変換するには、『数学的思考』が必要不可欠だ。なにせコンピュータは数字しか扱えないのだ。現実の状況を数字で表現するしかない。
全角の「a」と半角「a」も、人の目から見れば同じ音かもしれないが、コンピュータからしてみれば全然違う。全世界共有で使われるユニコード表記*1での「a」は「U+FF41」、「a」は「U+0061」であることを見て貰えば一目瞭然だ。互いに似て非なるものなのである。
こういった現実世界を数学世界に落とし込む思考(=『数学的思考』)の重要性は理解いただけたのではないだろうか。
プログラミング的思考
ではお次の『プログラミング的思考』とはなにか。
小学生からプログラミングを学ばせるIT教育が始まっているので、数学的思考と同様に文部科学省の資料小学校プログラミング教育の手引:文部科学省から紐解いていきたい。
そもそもプログラミングを学ぶ意図について、この資料には下記3点が挙げられている。
- 「プログラミング的思考」を育むこと
- プログラムの働きやよさ、情報社会がコンピュータ等の情報技術によって支えられていることに気付くことができるようにするとともに、コンピュータ等を上手に活用して身近な問題を解決したり、よりよい社会を築いたりしようとする態度を育むこと
- 各教科等の内容を指導する中で実施する場合には、各教科等での学びをより確実なものとすること
はっきりと『プログラミング的思考』の文言が登場している。という訳で、その定義についての言及も当然ある。
有識者会議「議論の取りまとめ」において「プログラミング的思考」は、
「自分が意図する一連の活動を実現するために、どのような動きの組合せが
必要であり、一つ一つの動きに対応した記号を、どのように組み合わせたら
いいのか、記号の組合せをどのように改善していけば、より意図した活動に
近づくのか、といったことを論理的に考えていく力」と説明されています。
そもそもプログラミングとは(厳密には)「プログラムを書くこと」であり、プログラムは「コンピュータに実行させる処理の順番を示すもの」である。
それらを踏まえて、もっともっとプログラミングというものを噛み砕くと「コンピュータにして欲しいことを順番に列挙する作業」ということになる。つまりプログラミングというのは、「コンピュータにして欲しいこと」と「順番」が整理できていれば、あとは文法の問題ということだ。
この「コンピュータにして欲しいこと」と「順番」を整理する論理的思考が『プログラミング的思考』なのである。
さて、実際にプログラミングする時には、実現したい機能というゴールがある。ここでは「家から学校まで荷物を運んでくれる」という機能を持った歩行ロボットをプログラミングで実現させるケースを考えよう。
では機能を実現させるために必要な処理を書き出してみる(順不同)。
- 荷物を受け取る
- 荷物を受け渡す
- 歩く
- 学校までの道を探索する
上記を機能を実現するための順番に並べてみよう。
- 荷物を受け取る
- 学校までの道を探索する
- 歩く
- 荷物を受け渡す
さて、機能を実現するための処理として、これで十分だろうか。
そもそも学校まで向かうのに「歩く」という動作だけで十分なのだろうか。途中で赤信号に遭遇した場合、「止まる」という動作が必要になる。なので信号を渡らなければならないような状況になった場合、「信号を確認する」という処理も必要になる。
「右に曲がる」「左に曲がる」という処理も必要になる場合があるだろう。「~に曲がる」という処理も、「止まる」と「~に身体の正面を向ける」という段階を踏む必要があることも想定される……とまぁ、考えていけばキリがない。
プログラミングとはあらゆる状況を想定し、それら全ての状況において「コンピュータにして欲しいこと」と「順番」を整理することが求められる。なにせコンピュータはプログラムされたこと以外のことはできないのだ。
「家から学校まで荷物を運んでくれる」という機能を持った歩行ロボットが、途中で風に煽られるなどして倒れたとしよう。しかしながら「倒れた場合に立ち上がる」機能をこのロボットは搭載していなかった。倒れたまま歩こうとし続け、しかしならが進めないという状況でこのロボットはどうなってしまうのだろうか。
進んでいた道が工事などで進めなくなっている可能性だってある。その場合は「進めないことを確認」し、「学校までの道を探索する」処理をもう一度実施する必要がある。探索する処理一つとってしても、地図上では進めても実際には進めない道が発見された場合を想定していなければ、この再探索は意味をなさない。同じ道を提案し続けることとなる。
そういった例外についても、「コンピュータにして欲しいこと」と「順番」を新たに整理する必要がある。『プログラミング的思考』というものの重要性が理解いただけたのではないだろうか。
まとめ
IT業界に身を置く自分の ”感覚” というものを言語化してみた。この言語化した理論通りであるならば、義務教育を終えた高校生までの内に身についていることが期待されるようだ(『プログラミング的思考』については置いておくとして)。
つまりちょっと物事を捉える見方のヒント――「こういう考え方もありますよね?」という刺激を与えれるだけでも、 ”感覚” が身について文系からエンジニアへの転向は簡単なのかもしれない……? いや、どうだろ……。
せっかくなので「プログラミングの勉強をどうすれば良いか」という題材でまた書きたいと思う。