SSブログ
プログラム ブログトップ
前の10件 | -

プログラミング言語を放浪する(2) [プログラム]

 もう、僕が必要としているようなプログラムでは、Cなどのコンパイラを使う必要はない。特定のOSでのインターフェース、特にグラフィカルなインターフェースが必要でなければ、これらのコンパイラ系の言語を使う必要はあまりないようだ。

 もしダイアログのようなものが必要になったとしても、場合によってはWebアプリケーションにするか、あるいは大抵のスクリプト言語でも何らかのグラフィカル・ユーザー・インターフェース用のライブラリなどを備えている。といっても、これまでそういうものを使う必要は感じなかった。

 むしろ、テキスト処理が中心となる場合、C言語やJavaなどでなければならない必要性は全くない。こうして、僕はある時期以後、コンパイラを使うことを止めてしまった。

 最初のころはPerlを使っていた。その処理速度はCで作るもの程速くはなかったが、開発の効率は圧倒的に優れていた。その要因は二つあった。一つは高度な正規表現が使えること、もう一つはスクリプトがコンパクトに書けること。また実行速度が速いことも利点であった。確かに、シェル・スクリプトやAWK、C言語などが出来る場合、その文法は覚えやすく、またPerlに特有のイディオムに習熟すると、非常に短いスクリプトで多くのことができるようになった。

 これは、プログラムの見通しがよくなる、という長所がある。ディスプレーの1画面に入るスクリプトの情報量も多くなる。見通しがいいと、メンテナンスが楽になる。修正もしやすい。

 しかし、これはプログラミングの初心者がプログラミングの本質を学ぶためには、あまりいい選択にならない理由にもなる。実用性は高いが教育的な効果は少ない、というのがPerlの特徴だろう。

 その後、日本人が作ったために日本語の処理が楽なRubyに乗り換えた。特にRubyでなければならないわけではなかったが、純粋なオブジェクト指向言語であり、その点での文法が一貫しているように思えたこともあった。それと日本語の処理について、特別なことを考えないでも問題がないこともよかった。オブジェクト指向を導入しなければならないほど大きなプログラムを作るわけではないが、しかし、Rubyなら、余り肩肘張らずに、単に面倒なものを一つのクラスにまとめてしまえ、というイージーな感じでオブジェクト指向ができた。

 僕が多用する正規表現については、最先端のPerlほどではないが、十分に協力なので特に問題はなかった。ただし、これもMacOS9では、うまく動かず、結局、OSXになってから本格的に使うようになった。そして、無謀なことに、大学での講義でこれを説明することにした。実習でやるならばいいが、講義でプログラミング言語を説明するというのは、全くの失敗だった。半年講義をやり、後期に実習をやったが、結局、ある程度できるようになったのは、一人だけだった。

 そうこうしているうちに、もう一方でPythonの勉強も始めていた。特にオライリーの『初めてのPython』の翻訳が出たことであった。PythonはMacOS9でも、OSXでも問題なく動くので、そういった意味ではRubyよりもやりやすかった。最初は、一部に見られる文法上の不整合を理由に、余り乗り気ではなかったが、結局大学のプログラミング言語の演習で使うようになって、そのテキストも書き、またサンプルのプログラムも作り、授業でも説明をしているうちに、割合、手に馴染んでくるようになった。

 そうやって馴染み出すと、今度はRubyの不自然な表現が気になり出した。まだ、Perlの方が自然だが、それ以上にPythonの表現は、生の英語あるいは擬似コードに近く、非常に自然な表現に思えてきた。プログラミング言語としての構文や構成要素も、Rubyよりもずっとシンプルで、学生にプログラミングの基本概念を教えるには、Rubyよりもずっとやりやすかった。Rubyでは、たとえば、繰り返しを特殊な概念イテレータで処理することが多いが、Pythonは for 〜 in リスト という、構文を使い、直感的には非常に分かりやすいし、同時に初心者にも教えやすい。

 オブジェクト指向を導入しなくても何とかなるのも、初心者に優しい。初心者がオブジェクト指向の概念を身に付けるのは、変数や代入、繰り返しや条件分岐、関数定義、そして一つの問題を解くためのに手順を記述するのがプログラムだ、というような、プログラミングの基本概念に十分習熟してからの方がいい。そして、これらの基本概念をPythonは非常に分かりやすく提供してくれるし、それだけで十分に高度なプログラムを組める、というのが、Pythonのいいところだ。

 僕は他にSchemeにも興味があって、『コンピュータプログラムの構造と解釈』を少しずつ読んでいるし、また極めて特殊なプログラミング言語であるTeXのスクリプトも書いたり、今年はXSLTも、学生の卒論とともに勉強したりしていて、スクリプト言語としてPythonを使うようになってはいるが、その他の言語にもまだまだ関心がある。そうそう、あまりやりたくはないが、これも卒論がらみでPHPにも手を染め、Javascriptも機会があれば、教えたいと思っている。

 本当は、なぜPythonが教育用言語に適しているか、そしてそれはひいてはwythonが教育用言語として、どの程度の有効性があるかを示すことにもなる、そういう話をしたいと思っていたのだが、それは、直ぐに書くには難しい話なので、とりあえず、僕のプログラミング言語遍歴をまとめることでお茶を濁してしまった。Pythonについては、また別の機会に考えてみたいと思う。


プログラミング言語を放浪する(1) [プログラム]

 僕は、プログラミングをC言語で始めた。Basicではないし、Pascalでもない。が、Pascalは並行してやってはいた。ちょうどTurbo PascalがBorland Pascalに移行するころの話だ。そういえば、CもTurbo Cだし、Borland Cだったから、これまでMicrosoftの開発言語は、その環境も含めて、使ったことがない。

 最初のころ、プログラムはCかPascalで作っていた。が、少し実用的なプログラム、つまり仕事で使うようなプログラムはほとんどCで作った。Pascalの方が文法がきれいだとか、教育用にも適している正統派の言語だとか言われていたが、僕には、簡潔な表現のできるCの方が合っているようだった。

 Macintoshに移ってからは、MetroworksのCodewarriorという開発環境を使っていたが、もともとPascalが主流であったMacOSのプログラミング環境も、このCodewarriorではCないしはC++が主流になっていた。チベット語関係のコンバータやデータベースのプラグインを作っていたときは、Cで書いていた。C++も勉強したことは勉強したが、そのメリットを受けるほど大きなプログラムは作らないので、その割りにはファイルサイズが大きくなるC++のクラスライブラリを使ったプログラムは作らなかった。

 そのころ、Javaが発表されたりして、これも多少勉強はしたが、当時のMacintoshの環境ではまともなものは作れなかったので、これも放棄した。

 その頃にはPerlも使うようになり、特にチベット語の処理やデータベースのデータ処理などでは、使い捨てのスクリプトで様々な処理をした。最初の頃は同じような処理をCのプログラムを作ってやっていたが、さすがにPerlはテキスト処理に向いているので、Cで何度も実験をしながら時間をかけて、不自由なプログラムを作ったものを、Perlのスクリプトならぱ、ものの1、2時間で完成させてしまうことができた。まだ、ラクダ本の翻訳が出る前で、英語で勉強していた頃だった。

 この時期、(文系でプログラムを作っていた)一部の人は、AWKやsedといったスクリプト言語を使っていたが、そして、AWKをいじったりしたこともあったが、結局同じことをはるかに自由に、かつ分かりやすく、しかもC言語に似た形で書けるPerlの方が、はるにか便利であった。その言語に特有の制約を余り気にするひつようがない、というのは重要なことだ。AWKやsedは汎用で使うには制約が多すぎ、またC言語のギャップも大きかったのである。

 CGIでオンライン検索をするプログラムを作るには、何よりもネットワーク上でテキスト処理をするのに適した言語と言えば、Perlが唯一の選択肢のころだった。僕が作ったオンライン検索のCGIは、データベースを用いず、データをテキストファイルとして保存しておいて、それをPerlのスクリプトで検索する、というやり方をとった。そのため、検索のスピードは極めて高速である。

 TeXでチベット文字を使うためのパッケージTibTeXパッケージでは、ローマ字で入力されたチベット語文をTeXのコマンドに変換するスクリプトを提供している。実はチベット語を分析して変換するというコンセプトは、Tibetan Converter と同じだが、その変換の手順は全く異なっていた。Cで書いたときには、一月からいかけてプログラムの試行版を作ったが、Perlでは似たような処理は、数十分で出来てしまった。確かにCで作るよりも、実行スピードは遙かに遅いが、作りやすさはPerlの方が圧倒的に有利である。一回の処理の時間が多少長くなっても、作る時間が圧倒的に短いことは、作る側にとって最重要項目である。

 そのころから、RubyやPythonといった、他のスクリプト言語の知名度が上がってきた。(続く・・・)


変数宣言と初期化 [プログラム]

 夏休みの課題の第一回目に、Javaの初歩的なプログラムの一文一文について、その「文の種類」を書かせる問題を出した。文の種類については、予め、種類を上げて説明しておき、またサンプルも出した上で、三つの初歩的なプログラム(テキストに使用していた結城本の中からピックアップ)について、文の種類を書かせるものだった。

 if文やfor文、あるいはメソッド定義文、try文など、大きめの構文は割合よくできていたが、かなりの学生ができなかったのは、「変数宣言文」と「変数宣言と初期化の代入文」であった。その他に、式だけで文になっているものや、複合代入(+=とか*=とか)なども引っかかっていたが、これは僕の説明も不足していたので、仕方がない。

 しばらく前、このブログでも何度も問題にしたように、プログラムは、変数をどう使うかによって展開していくものである。Wirthの本のタイトルにあるように「アルゴリズム+データ=プログラム」であるとすると、そのデータを担っているのが変数なのであり、それがなければそもそも、有意義なプログラムにはなり得ない。そのデータをどのように処理するか、という方法がアルゴリズムであり、それもデータがなければ、そもそも何の意味もないのである。

 つまり、変数の扱い方に慣れていないと、プログラムが作れないし、逆に変数を中心にプログラムを考えていくと、割合すんなりとプログラムを書けるようになる。

 変数がこのようにプログラムにおいて大事だとして、その変数をそのプログラムに導入するとき、つまり、初出の変数について可能な文は、Java(C言語などでも同じだが)では、二つに限られる。一つは「型(クラス) 変数名」という組による変数宣言文。ここでは、変数に初期値は与えていない。もう一つは、この変数宣言に加えて、代入による初期化も行う場合である。変数はデータを代入しなければ、何の意味もない。したがって、変数を宣言するときに、その値も代入しておくのが、基本的には好ましい。

 これはそれほど難しい話ではないと思うのだが、どうも、学生は、この変数の宣言と初期化が苦手らしい。どうしてなのか、分からない。それほど難しい話ではないと思うが、それは初心を忘れてしまったからかもしれない。もちろん、提出された答案にコメントをつけて返し、再提出をさせるとほとんどが、正解を書いてくるのだから、これもまた僕の説明不足(そもそも、Webページで説明をし、問題をだしている。)によるものかもしれないし、あるいは、これは単に慣れの問題で、それなりの数を こなせば、自然にできるようになることかもしれない。

 課題の第二回目以降は、Pythonでプログラムを教えることにしているが、Javaが初出の変数について二種類の文があったのに対し、Pythonでは、代入による初期化文のみである。型やクラスを宣言する必要もない。これらは代入留するデータの種類によって自動的に決まるからである。実際、初歩のプログラミングを教えるのにPythonを使うのは、いい選択だと思う(それについては、後日、再び取り上げよう。)。シンプルであり、かつ、素直な書き方(その言語特有のイディオムなどが少ない)であるので、初心者には最適である。

 話が逸れてしまったが、何度でも、ことある毎に、この変数の導入についての文には注意を促す必要があると思う。


一人の人が作れるソフトウェアー [プログラム]

昨日、卒論に取り組む姿勢について書いたが、実は、書きたいことは別のことだった。書いているうちに、最初の意図とは違った方向に話がいってしまった。そこで、きょうもう一度、最初に書こうと思っていたことを書くことにする。

 もちろん、多少は関連はある。何度か話を戻したいと思いつつ、書いていたから。卒論を一年かけて取り組んでいくと、予想以上に規模の大きいものになっていく。卒論のための卒業制作でソフトウェアーを作っていく場合にも、同様に、一年間作り続けていると、相当の規模のソフトウェアーになっていく。ある意味では、ソフトの規模は時間に比例するところがある。単純に増加していくわけではないにしても、物理的に時間をかけることで、いろいろな機能を追加していくことができるから。

 しかし、もう一方で、一人の人が把握し制御できるソフトの規模というものには、ある程度の限界がある。それも人によって、能力によって違いはあるだろうから、厳密な限界というわけではないが、ある線を越えると、一人で維持するには大きすぎる、という段階が必ずやってくる。

 これは一人の人に限らない。現代のソフトウェアーは、肥大化の傾向にあり、一人でゼロから作ることは不可能に近い。すでにある様々なライブラリーなどを利用して、作っていくことになる。それでも、その全体の動きは、作った人の計量できる範囲を超えていることがしばしばである。動かしてみてから、バグをチェックする、ということが行われ、そのためのテストの仕方の研究も進んでいる。

 それほどではないにしても、いろいろな機能を追加し、それらをバグのない状態に保っておくことは、規模の増大よりも遙かに急速に難しくなっていく。それが、公開し多くの人に実用的に使ってもらえるようなソフトウェアーであるならば、なおさらで、バグのない状態に保つのは、全体を制御する以上に労力が必要となる。ユーザーからの様々な要望や不具合の報告に対処するためには、相当の時間を要するだろう。

 そのようなソフトウェアーは、次から次へと開発できるものではない。そんなことをしたら、体がいくつあっても間に合わない。それなりの規模で、人々に便利に使ってもらえるようなソフトは、一人の人がある一定の期間、たとえば、数年くらいの間には、一つ以上作るのは難しいのではないだろうか。

 実際、世の中でフリーであれ、シェアウェアーであれ、多くの人に使われているソフトの作者は、ほとんど一つのソフトを維持管理しているだけだろう。一人の作者が複数の現役のソフトを維持していることは稀だ。つまり、一人の人が作って維持できるソフトというのは、たいてい、一つが限度であるように思われる。そのソフトが、その人の顔になる。あるいは、そのソフトとその人は一対一対応で、いつもセットで思い出される。

 それくらいのソフトを作れるようにがんばってほしいし、そうやって作ったソフトは、ずっと自分の息子と思って育てていってほしいと思う。

 (僕自身は、いくつかのソフトを作り、本当は、アップデートなどもして維持管理しなければならないのに、放置しているので、残念なことに決していいお手本にはなれない。)


プログラミングの基本問題集 [プログラム]

 4年生の卒論で、初心者向けのプログラミング学習を考える場合、どのような項目が必要になるかを調査するというテーマで研究している学生がいる。とりあえず、言語を問わず、初心者向けのプログラミングのテキストをいろいろ集めて、そこから「練習問題」を抽出した資料集を作った。

実際に集めてみようとすると、一冊のテキストから抜き出せる練習問題は決して多くないことが分かった。また説明はしているが、例題という形にもなっていないものも多い。前にも書いたが、実際にはプログラミングの学習は、練習、練習、また練習、基礎練習を毎日欠かさずに、という姿勢が大切だ。説明を聞いて分かっても、何らかの問題を解くことができるようになるには、その間のギャップが非常に大きいのである。

 それでも何冊かのテキストから横断的に問題を集めたら、それなりの量になった。さらに僕の昨年度の授業用プリントにも、相当数の練習問題が含まれているので、それからも収集した。

 次には、それを整理・分類し、似たような問題をまとめていくことで、初心者がプログラミングを学習するときに、何を身に付けたらいいか、何を理解したらいいかの範囲が分かってくるのではないか、というのが、先の学生のテーマである。実際に考えただけでも、パターンはすぐに出てくるだろう(それについての予想は、以前、このブログでも書いた。)。

 今、ここで言いたいのはそのことではなく、その学生が集めたテキストの言語は、Pythonだけではなく、C言語やJava言語、Perlなど複数のものに及んでいるが、その問題を取り敢えず、Pythonで全部解いていくことにした。こうして、かなりの量の問題を解いてみると、最初は一つ一つの問題を解くのに難儀していたのに、徐々に一人で問題を解いていけるようになった。

 初心者の学生に教えていると、かれらは説明したら理解できるし、もちろん、例題として挙げられているプログラムを入力しても動かし、そのプログラムを(一応)理解したと思っている。しかし、いざ、応用問題を出すと、しばらくは問題の前で少しもプログラムを入力していけず、それでは駄目だと思って、取り敢えず断片的な、これまでどこかで出てきた変数なりの式を書いてみたりする。しかし、それはそのプログラムにとって必要なものでもなく、いや、そもそも意味も不明な、単に覚えていた断片を繋ぎ合わせてみた、というだけのものを書き出したりする。しかも続けてではなく、1行ほど難儀して書いて、再び指を止めて、眺め始める。

 つまり、ゼロからプログラミング言語で何かを考え解決していくのが大変難しい。これを乗り越えるには、「理解」するだけでは駄目で、経験をたくさん積むことが必要なのである。しかも、たまに経験するだけではなく、毎日続けることで、カンと腕を鈍らせないようにしておく必要がある。

 そのためにたくさんの練習問題が必要なのである。そのことを分かっているテキストは少ない。というか初心者向けにはほとんどない。有名な本でもそうだ。『初めての何とか』という類の本でも、長い章の最後に3題くらい問題がついているだけだ。そうではなく、説明よりも問題を解かせているうちにできるようになる。できるようになってから、復習として説明を加える、そういう方が上達する。

 ということは、やはり、他人の本に頼らず、自分でプログラミングの教科書を作らなければならない、ということなのだろう。そのために問題を集めている学生の作った資料を使わせてもらうことにしよう。


繰り返しを止めて考える。 [プログラム]

ループ(繰り返し処理)をどのように説明したらいいか、説明のたびにいろいろと工夫してみている。今日はそのパートツー。

 繰り返しを理解するのに、for構文は、全ての制御処理が最初の一行に集約されているので、whileではなく、for文で繰り返しを教えるのがいい。昨日は、そのfor文を、「指折り数えること」と考えたが、今日は、繰り返される処理の方に焦点を当てて考えよう。

 繰り返しは、最初のforで繰り返しの条件、つまり、いくつからいくつまで、変数の値を動かすか、を設定したら、繰り返す、ということは忘れてしまう必要がある。変数、たとえば、iはそのとき、一つの数値に固定される。というか、常に、何か一つの具体的な数値であると考える。それは、条件の範囲内なら、どの数でもいい。

 その一つの固定された値に対して、繰り返される処理の部分は、繰り返しではなく、一回の処理にすぎない。もう繰り返しのことは考えないようにしよう。繰り返しというのは、それを繰り返しと考えているうちは、頭がこんがらかって、いろいろなものを混同してしまう。また、人間は、繰り返しをひと纏まりで表現してしまうので、コンピュータがするように一つ一つの状態を積み重ねて、それで繰り返しが出来上がることを忘れてしまう。話をするだけならば、それでもいいが、コンピュータに作業を命じるならば、その手順はコンピュータが理解できるように、単純な処理に還元し、単純な指令を発しなければならない。

 そうやって、一回だけの処理を考えられるようになれば、繰り返しは考えなくていいことになり、繰り返しにまつわる複雑そうな内容は存在しないことになる。繰り返しが必要なときにも、必ず、それは繰り返しが必要のない部分に還元することができる。繰り返しは消去できるのである。

 問題は、どうやって、繰り返しの中の一回の状態に焦点を絞れるかにかかっている。もし、その処理の中に、もう一度for文が必要になったとしても、それもまた同じように、繰り返しの条件を確認したら、その内部の一回だけの処理に焦点を絞れる。そうやって、さらに内側の処理に還元したら、たとえば、それはアステリスクを1個表示する、という処理だけになるだろう。

 今度は、その一番単純な処理から徐々に繰り返しを復元していく。一番単純な部分で、アステリスクを一つ表示する、という処理は、それを取り囲むforの条件で、ある回数繰り返される。たとえば、20回繰り返される。すると、そのfor文全体は、日本語で言えば、「アステリスクを20個表示する」という動作だと考えられる。実際にこれを実現するには、for文による繰り返しが必要だが、それを一つのまとまった処理として考えてしまえば、それは20個アステリスクを表示するという一つの単純な処理と考えることができる。

 そして、それを含めた一連の一回だけの処理を考え、それがさらに外側のforの条件によって、ある回数繰り返される。このようにして、一番根本の処理から徐々に繰り返しが復元されるが、しかし、このときにはもう、繰り返しの複雑な処理は考えなくてもよくなっている。単にこれこれの処理を、何回繰り返す、と単純に日本語で表現できるようになる。

 つまり、まず、繰り返しに拘泥せずに、一番基本的な処理にまで還元していき、それを起点に繰り返しの条件を付け加えていく、という考え方をすると、繰り返しを全体として考えていたときの、こんがらかる難解さが消えていくのがわかるだろう。

 学生に教えるとき、こういうことを、プログラムのforの条件節を紙で隠して、それを見せないようにして、一回の処理に意識を集中させ、それが十分確認できたら、それからforの条件節を見せて、それがどういう条件かを確認させる、という具合に説明していくのである。


ループ(繰り返し)処理の教え方 [プログラム]

初心者にとって、繰り返しの制御構造を理解するのは、条件分岐よりも、ずっと難しいということを、最近書いたが、少し教え方、というか話の仕方を工夫してみた。

 その一。

 Java(でも、Cでもそうだが)のfor文による繰り返しについて。繰り返しの一般形式はwhile文だと思っていた。for文はその特殊な一形態だと思っていたが、実は繰り返しを理解するには、簡単な例題をいろいろと作れるfor文の方が適しているらしい。単に例題が作りやすいだけではなく、繰り返しに関わる条件が最初の条件節に集約されているので、説明もしやすい。K&RもCのfor文について言っていたことだが、今回、それを実感した。

 問題は、

  1. 0から9までの数字を一行に一つずつ表示する。
  2. 0から9までの数字を一行に一つずつ表示し、その各行の数字のあとにコロン、次にアステリスク20個を表示する。
  3. 0から9までの数字を一行に一つずつ表示し、その各行の数字のあとにコロン、次のアステリスクをその行の数字と同じ数だけ表示する。

という順番で徐々に処理内容を増やしていく。

 コンピュータは非常に単細胞だから、複雑なことは理解できない。その代わり、面倒くさい繰り返しは、何の苦労もなくやってのける。そこで、コンピュータへの作業手順の命令は、できる限り単純にしないといけない。

 for文は、一般的には「指折り数えること」のプログラム的表現だと考えられる。0から9まて順番に数字を打ち出すためには、毎回、いくつを打ち出すかを忘れないように、紛れないように、指折り数えていく必要がある。まず0は何も指を折らない。次に、一つで親指を折る。そこで1を打ち出す。次の人差し指を折り曲げて、次を数える。そして2を打ち出す。次に中指を折り曲げ、次の数字3を打ち出す。以下、最後に左手の薬指を折り曲げて9を数えるまで続ける。そして、一つ数える毎に、その数字をprintする。

 for文では、まず「いくつから、いくつまで」数えるかを指定する。数える場合、必ず数え始めと数え終わりを指定しなければならない。forの後の括弧の中の最初の部分に、「いくつから」を書き、セミコロンで区切って「いくつまで」を書く。今の場合だったら、for (int i = 0; i <= 9; ) となる。

 次に、一つの処理を終わる毎に、次の指を折る、という動作が必要である。指折り数えるためには、指を次、次、と折り曲げていかなければならない。というか、次の指を折り曲げる、ということが「数える」という行為なのである。それをJavaでは、for文の最後の部分にi++と書く。

 次の中括弧{が来て、次の行から中括弧閉じ}までの間に、繰り返し行われる処理を書く。最初は、数字iを表示すること。これは簡単だ。

 次は、その繰り返される処理の中で、数字以外に、20個アステリスクを表示する。この場合、人はどうやってアステリスクを20個書き出すだろうか。この場合も、いくつ打ち出したかを指折り数えながら、指を折る毎にアステリスクを一つ書き出すだろう。だから、これも指折り数える繰り返し、つまりfor文を使う。

 今度は、しかし、0から9までの数字を数えていた右手で数え始めてしまうと、さっき数えていた数が分からなくなってしまうので、左手で数えることにする。左手で、0から19まで数えると、これで20個になる。右手とは別の左手で数える、ということは、iではなく、別の数えるための変数jを用意する、ということだ。そこでfor文は、for (int j = 0; j <= 19; j++)になる。0から19まで、jで数えるのである。

 そのあとに書かれる繰り返し処理は、アステリスクを1個打ち出すことである。それを指折り20回数えながら、一度に1個ずつアステリスクを打ち出していく。

 以上のように、forの構文を指折り数えることになぞらえ、実際に指というか手を用意させ、指をおらせ、一回ごとにこれこれを表示する、ということを確認させてから、それをforの構文を書かせる。必ずしも、直ぐに納得するわけではないが、しかし、少なくとも、「説明」としては、うまく行ったのではないかと思う。

 長くなったので、もう一つの説明の仕方については、日を改めて述べよう。


いっそ、模型でやろうか [プログラム]

昨日の、「変数と代入と繰り返し」の続きです。

 日本語で説明を細かく書くのもいいけれども、変数や値の代入、値の参照、値の変化などを具体的にイメージできるように、箱と、そこに入れるデータカードと、式や文を書くカードとを用意して、実際に値の書き換えや入れ替えなどを現実の模型で辿られるといいかもしれない。

 箱にはポストイットのようなラベル用紙で名前を付ける。データは、小さいカード型の紙切れに書いて、それを箱の中に入れる。これが道具立てである。

 もう一つ、少し大きめの箱は関数に見立てる。それにもラベルで関数名と引数リストを貼っておく。関数の前には、引数名を書いた紙片を置き、また何も書いていない紙片を箱の中に用意しておく。関数を使うときには、引数名を書いた紙片に、値を書き込み、それを箱に入れて、箱の中の紙片に、その関数での計算結果を書いて、箱から取り出す。必要があれば、別の変数の箱にそのデータの紙片を入れる。

 制御文を含む文は、別の紙片に一行分ずつ書いて、順番に並べておく。代入文も文としてプログラム紙片に書いておく。

 実際に実行を開始したら、まずデータを書いた紙を変数の箱に入れ、式の計算があれば、その結果を計算して再び紙片に書いて変数の箱に入れ、前の紙片は取り出して捨てる。

 繰り返しも、値の変化を常にデータの紙に書き、変数の中身をそれで入れ替える。画数があれば、引数に値を書いて関数の箱に入れ、結果として出てくるものを関数の箱の中の紙片に書いて、出してくる。大抵それは、もう一度変数の箱に入れることになる。

 条件判断や繰り返しの条件部そのものは、比較をする式になるので、紙片に書くことは滅多にない。この部分は具体的にモデルで操作できないので、「もし・・・ならば、」の判断が真なのか偽なのかによって、その後の処理の方のみを残して他の処理は脇に寄せておく。

 このようにして、データを書き換えながらプログラムを一歩一歩進めていくことで、変数や代入、値、式などの重要性をビジュアルに理解できるようになる。

 これは全くの空想の話だが、実際にやってみる機会があれば、十分試してみる価値があるだろう。これと日本語スクリプト言語wythonの日本語プログラミングとを組にして教えていけば、そうとう有効なプログラミング境域ができるような気がする。


変数と代入と繰り返し [プログラム]

プログラミングを学ぶ初心者が、最初にぶつかり、そこを何とか越えないと結局、少しでもプログラミングができるようにならない、そういう難関が、何かの値を変数に代入し、変数を参照し、その変数によって繰り返し処理を制御する、という、この三つの要素である。

 ある程度プログラミングができるようになった人からすれば、それがどうして難しいのか、どうして、これらが分からないのか、分からないことだろう。変数という箱を用意して、そこに値を入れ、必要になれば、その値を取り出す。一回ごとの繰り返しに値を変化させて、ある条件になったら繰り返しを抜ける、これは別段難しいことではない。

 初心者向けと称するプログラミングの入門書でも、せいぜい、箱の絵に値を入れたり出したりするような、イラスト入りではあれ、たいてい、通り一遍の説明で、先を急いでいる。

 しかし、ここのところが本当の初心者には難しいのである。とにかく、変数といい、値といい、代入といい、これらはかなり抽象的な概念なのである。そうでしょう?

 前にも書いたが、プログラムはバーチャルな一つの世界であり、その世界を構成する存在要素は、個々の具体的なデータと、それらを抽象化し、一般化した変数である。(定数とかもあるが、これはなくても困らない。)こういう非常に限られた構成要素を使い、それらの間に「作用」を起こさせる演算子、関数、制御構文が、それら構成要素を縫い合わせることで、一枚の服、すなわち一つのプログラムが出来上がっている。

 こういう抽象的な理解は、初心者、特に数学を苦手とする文系の初心者には、当初難しいものである。これを一つ乗り越えてしまえば、つまり、こういうバーチャルな世界の構成の仕方が身に付いてしまえば、あとは雪だるま式にプログラムを勉強していくことができる。

 そこで、まずはとにかく、そのプログラムで使う変数を宣言し、データをそこに格納させるべきである。プログラムの最初に、その世界では何をするのか、を考え、それに必要な道具を揃えさせる。道具とは、つまり変数である。その場合、どういう目的でその変数を用意したか、日本語でちゃんと書かせる必要がある。

 データを用意すると言っても、それは素のままでデータを使うのではなく、必ず変数に代入させる。これは宣言と初期化をセットで、プログラムの最初にしておく、ということだ。

 変数にはデータは出したり入れたりする。大抵は、変数とデータを使って計算をし、その結果をもう一度変数に入れ直す、という形ですることが多い。この基本を徹底的に覚え込ませる必要がある。計算は数値だけではなく、文字列についても、合成することができる。

 また変数には、計算だけではなく、その計算を関数に分離して、関数にデータを渡し、結果だけを戻して、それを変数に代入することも多い。これも代入の一種であるが、また関数を使う使い方を覚えるのでもある。

 変数とその値という考え方も徹底して理解しないといけない。代入の左辺にくるのは、変数という入れ物、右辺に変数が使われると、その変数に入っているデータ・値を使うことになる。この区別は、ある意味では自然だし、特に断らなくても分かる場合があるが、そもそも変数や代入にもたもたしているような場合には、その変数と値と代入の関係について、図を書きながら、ゆっくり、何度も教えなければならないだろう。

 繰り返しも、その変数の値の変化によって動くものである。逆に言うと、一回の繰り返しごと、変数の値が変化し、そによって実行される内容や繰り返しのカウントが変わっていく。これも非常に強い抽象である。だって、一回のデータの代入は、とにかく一つ一つ順番に辿れば理解できるだろう。しかし、繰り返し処理は、いわば、毎回変化する値を使いながら、ある一つの作業のひな形、テンプレートのようなものである。そのテンプレートを、一度ずつ変数が変化しながら、実行する。

 後は若干の関数を知っていれば、以上の道具立てで相当な長さのプログラム、あるいは多種多様なプログラムを書くことができる。と同時に、ここまでを徹底的に理解するためには、そのレヴェルでの練習問題を数多くこなす必要がある。

 実は、初心者にとって、上に挙げたような説明よりも、この練習問題を解くのがすごく難しいのだ。ある問題を解決するために、どうしたらいいか。何もない白紙の状態から、そこにデータと変数を生み出し、それらを組み合わせて、最終的に問題を解決する仕組みを作り上げていく。

 問題を前にして、紙の上にいろいろな値を具体的に書き、どのような手順で問題を解決するかを、落書きしてからプログラムを作り始めるようにしよう。何も見通しなくコンピュータに何かを書き始めてしまってはならない。初心者が書くような短いプログラムであれば、手書きで擬似コードを書いても、大した手間ではない。それなくして直接入力し始めてしまうと、どうしてそういう変数を用意したのか、よく考えることなく入力してしまう。そうなると応用がきかなくなってしまう。手を動かして自分の頭で考えてみる、これが大事なことである。

 いずれにせよ、これまでプログラムの教授はうまくいった試しがない。毎年工夫をしてはいるが、初心者のためのプログラミングではまだ成功したことがない。今年も、すでに反省材料が山のように出来てしまった。それでも、今年を棒に振るわけにはいかないのだから、現状から出発して、最低限でも身に付くように、いろいろと励ましていかなければならないだろう。


突然アクセスが増えた [プログラム]

 ここ2、3日、どういうわけかアクセスが異常に増えている。そのほとんどが「Pythonを知らないなんて」という記事に対するものだった。ここでは、就活先の企業で、「Pythonを勉強してきたー」と言っても、誰もPythonを知らなかった、ということから、そんな会社は先行き危ないか、おもしろくないから避けた方がいい、という過激な内容だった。もちろん、一方では、自分の勉強してきたことに自信をなくすかもしれない学生を元気づける意味もあった。

 現場からの意見では、Pythonではお金にならない、現場の仕事はこなせない、Pythonをやっていても意味がない、という態度をとられたのだろう、という意見が多かった。

 一方で、前に引用したことのあるポール・グレアムというLispプログラマーの「Pythonの逆説」という文章をリンクしてくれた人もいた。要するに、できる会社は、よいJavaプログラマーを募集するために、その条件としてPyhtonを知っていることを挙げる、という逆説を述べたものだった。

 ポール・グレアムの

ハッカーと画家 コンピュータ時代の創造者たち

ハッカーと画家 コンピュータ時代の創造者たち

  • 作者: Paul Graham
  • 出版社/メーカー: オーム社
  • 発売日: 2005/01
  • メディア: 単行本


は、以前に紹介したように、とてもおもしろい本だ。特にマイナー言語が好きなオタクには。

 僕は必ずしもPythonやLispを勉強すべきだと言っているわけではない。これらはおもしろい言語だし、またすっきりしたプログラムを書くにも適している。これらでできることは非常に多く、そして非常に短期間にプログラムを作ることができる。しかし、だからといって、これらを誰もが身に付けるべきだと言っているわけではない。

 問題は、現在のプログラミングの世界は、特定言語で、定型処理を書くだけでは済まない状況になってきている、ということだ。技術の進歩は早く、新しい概念や手法、ツールが次々に発表される。それらに取り残されないためには、そういうソフトウェアーの展開に目を配っているべきだし、そのときには、当然Pythonの存在も、その重要性も目に入ってくる、ということなのだ。

 それに気付かないようであれば、5年、10年経ったときに、大きな差が開いてくる。開発は止めてマネージメントだけ、現場は下請けに丸投げ、というのが目指す道なら、それでもいい。仕事と割り切って、そういう道を目指すなら、プログラミングの世界の情報よりも、経営についての才覚を磨くのがいい。でもプログラムを作るのが好きならば、そういういろいろな技術革新に興味を持って、その中から自分でもできそうな分野を絶えず勉強していく姿勢が欲しいと思うのだ。


前の10件 | - プログラム ブログトップ

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。