プログラミング:想定外の解答
プログラミングは「プログラミング言語」という言葉で書いていく。したがって,それぞれの言葉が何を意味するかを理解していかないとプログラミングはできない。・・・・ のだが,もちろんそれだけではない。
「プログラミング的思考」という幻想 ではそのあたりを書いたのだが,また新しい事例が出たので書いておこう。
プログラミングでは,
a=3
とすると,「aと3が等しい」ではなく,「aに3を代入する」という意味になる。
数学でも,
「x に 3 を代入して」を「x=3」 と表すのだから,高校生ならそれほど抵抗なくいけるのではないか。
ただし,「代入」とう言葉の意味がわからなければ話はまた別である。
そのためかどうか,プログラミングの入門書では,「変数」を箱にたとえて,「箱の中に3を入れる」という例示をしているものが多い。しかし,それはそれでまたわかりにくい面があるかもしれない。たとえば,a+b をどう説明するか。箱に入れたものをどう処理するのだろう。数学のイメージなら説明するまでもなくわかるのだが。
「= は代入」はプログラミングの基本中の基本だが,これをすんなり受け入れる人と,そうでない人がもちろんいる。ちょっとしたハードルかもしれない。
さて,
プログラミングでは,「aに3を代入する」を「a=3」と書く
ことを同意いただいたとして,次の問題を考えてみてもらいたい。
もちろん,プログラミングなんかやったことがない人,に,である。
やったことがある人は,その結果について興味があるのではないだろうか。
(1) 値の入れ替え
変数 a と b の値を入れ替える。
2: a=3;
3: b=5;
ここで,b=a としてしまうと,bの値が変わってしまう。そこで,b の値を他の変数にコピーしておく。このような作業用の変数は work , w などの名前にしておくとよい。
次の4~6行目で手順を // でコメント文にしたので,それに対応するコードを書きなさい。コメント文は書かなくてよい。
7行目で,a,b の値をリスト [a,b] にしてコンソールに表示する。[5,3] となればよい。
4: // b の値を w に代入する
5: // a の値を b に代入する
6: // a にコピーしておいた w の値を代入する
7: println([a,b]);
4クラス,同一条件で実習を行った。
あるクラスで,次のような解答が続出した。
4: w=5;
5: b=3;
6: a=w;
もちろん,これでもコンソールには [5,3] と表示される。
これに対して,「これでは無意味。3と5ではなくaとbの中身(値)を入れ替えるのだ」とコメントを書いたのだが,どうも妙だと思って,テキストを読み直した。
4: // b の値を w に代入する
と書いてあるのだから,w=b と書けばよいのだが,ここで気がついた。
「bの値 で,bは5 だから w=5 にしたのか」
だとすると,「3と5ではなくaとbの中身(値)を入れ替えるのだ」とコメントしても意味がわからないだろう。
では,どう書けばいいのか。
書きようがない。
もともとの課題「変数 a と b の値を入れ替える。」の意味がわかっていないのだからどうしようもないのだ。
この意味がわかっていれば,コメント文にしたがって
4: w=b;
5: b=a;
と書けるはずだ。
ちなみに,コメント文の「// b の値を w に代入する」を見て, b=w にした者もいた。「を」「に」の助詞がわかっていないようだ。
要するに,何をすればいいのかがわかっていない。
プログラミング以前の問題である。
実は続きがある。
次の問題
(2) 並べ替え
リスト int=[2,5,3,4,1] を昇順に並べ替えてint=[1,2,3,4,5] にする。
「昇順ということは,大きな値が右にある」と考えて,次のようにプログラムを作る。
① まず,1番目と2番目の要素を比べて,1番目の方が大きければ入れ
替える。今の場合は int=[2,5,3,4,1] でかわらない。
② 次に,2番目と3番目の要素を比べて,2番目の方が大きければ入れ
替える。
これを,1つずつずらしながら,全部で4回やると,一番右に5がくる。
③ ①と②をはじめからやる。ただし,一番右は 5 になっているので,その
手前まで3回繰り返せばよい。繰り返す回数が4回,3回,2回,と減って
いくことになる。
これを一般化する。①②の繰り返し回数を m とする。始めは m=4 で,1ずつ減らしながら4回繰り返す。
このようなとき,repeat の,始めの値を指定するオプション start ,ステップ値を指定するオプション step を使う。-> はハイフンと不等号。
repeat(4,m,start->4,step->-1, 処理 )
次のプログラムを完成しなさい。
// 以降は説明のコメント文。入力しなくてよい。
8: int=[2,5,3,4,1];
9: repeat(4,m,start->4,step->-1,
10: repeat(m,k,
11: if(int_k>int_(k+1), // k+1番目よりk番目の方が大きいならば
12: w= ;
13: int_(k+1)=. ;
14: int_k= ;
15: ); // if の閉じかっこ
16: );
17: );
こちらの方が複雑だ。
しかし,アルゴリズムとしては(1)と同じで,(1)ができていれば 12,13,14行目はできる。(1)ができなければ(2)はできないだろう。
ところが,(1)ができなかった13名のうち11名は(2)ができているのだ。
理由は?
相談可としているからだ。
わからないからできた者に聞く。聞いた通りに書く。しかし,ここで(1) の思い違いに気がついて前に戻ることはしていないわけだ。
はたして,この11名のうち何名が,「入れ替え」の原理を理解したのだろうか。
なお,(2)ができていない2名は,(2)まで進んでいなかった。
昨年のことを書いておこう。
大学入試センター試験の「情報関係基礎」で2018年に,並べ替えの問題が出されている。この中に,次の部分がある。
この問題では,2行目には代入の←しか書かれていないので,先ほどよりは難しい。
授業では,これらの問題をまず机上で解いた後,正解を渡して,実際にコーディングした。空欄はセンター試験と同じ。ただ,「繰り返し」は「repeat」になるなどが異なっている。
ちゃんと答え合わせをして理解した後だからコーディングもできただろう,と思うが意外にそうではない。残念ながら記録が残っていないのだが,期末試験でこの「入れ替え」の問題を出題したときの記録は残っている。
(2) Data_m と Data_(m+1) を比較し,Data_m > Data_(m+1)なら入れ替える
05: if(Data_m > Data_(m+1),
06: w=Data_m;
07: Data_m=
08: Data_(m+1)=
左辺が書いてあるから,センター試験の問題よりやさしいはずだ。しかも授業でやってある。
正答率は,クラス別に次のようになった。
クラス A B C D
07行目 47.5 33.3 35.9 36.6
08行目 15.0 26.2 23.1 9.8
惨憺たるものだった。センター試験の問題で答え合わせをし,さらに実際にコーディングも行った。にもかかわらずこれだ。
この結果を受けての今年の練習だったが,これに比べればよくできたといってよいだろう。
しかし,まだわからない。前述の通り,本当にわかったのかどうか。相談してやっているからだ。ただ聞いて,その通りに書いただけ,ということがありうる。
それは,いずれ期末試験で出題すれば判明するだろう。