文科省の教員向けPythonプログラミング研修資料の杜撰さ


この記事を書くに至った背景

文科省のPythonはPythonじゃねぇ の記事が反響を呼んでいますが、例の資料はPythonのコード以外でも杜撰なところが多く、日本の将来を不安視するような仕上がりになっています。

コーディングスタイルや書法の指摘に対して「言語を学ぶのではなくプログラミングの考え方の基礎を学ぶのが目的だ」という理由を掲げて擁護される方がいるようですが、コード以外の部分でも杜撰なのでちょっといろいろ書いてみたいと思いました。といいますか「ちょっと」のつもりだったのが相当たくさん書いてしまい、おそらくミスリードや誤解しているところもあるかと思いますが、暇つぶしがてらゆるく読んでいただければ幸いです。

資料ページはこちら実際のPDFファイルはこちらです。


コンピューターの仕組み ( PDF 4ページ、通番 98ページ )


コンピューターの仕組み


構成要素


 ブラウザのアイコンをクリックして検索をする時について考えてみよう。

 この時,マウスやキーボードで入力してコンピュータが動き,画面に結果が表示される。

 入力装置や出力装置を含め,すべてを制御するのが制御装置,様々な演算を行うのが演算装置である。


最初の3段落で文体の統一が崩れている(「考えてみよう。」→「考える。」)というのは文科省が出す資料としていかがなものでしょうか。ざっと見た感じこれ以降は文体乱れていなかったのでレビューミスだと思うのですが、しっかりしてもらいたいものです。

「文体の乱れは心の乱れ!」(煽り)

そして、ここで書かれているのは「ノイマン型コンピュータ」の説明だけど、生徒は知らなくても先生はキーワードとして知っておくべきだと思います。


 CPU にとっての作業場所がメモリである。十分な広さが必要であり,特に複数の仕事を同時に進行する場合は広くする必要がある。


メモリ容量を「広さ」として表現するのはいかがなものでしょうか。普通に「容量」でよいし、「広い」「せまい」とかいう表現はちょっと違和感があります。その違和感が図表3では


メモリ 机の広さ、多いほうが作業しやすい。


と、気持ち悪い表現になっています(本文では「広い」「せまい」という表現な一方でここでは「多い」と統一性も失われていますが)。あいまいな表現つかうくらいなら容量の大小といった表現のほうがマシです。

そして主記憶装置と補助記憶装置の違いもイマイチで、速度と利便性(電源切っても永続的に情報保持できる、容量が大きい)のトレードオフがあることが説明しきれていません。


 メモリが少ない場合は,あふれたデータをハードディスクに保存するため,ハードディスクとのデータのやり取りにほとんどの時間がとられ,いくら CPUが高速でも実行速度は上がらない。


なぜコンピュータ・アーキテクチャの話でOSの機能の話がでてくるのでしょうか。

「節子、それは構成要素じゃなくてOSの仮想記憶の説明や!」(煽り)


論理演算を用いた二進数の足し算


0 + 0 = 0

0 + 1 = 1 or で対応できる

1 + 0 = 1

1 + 1 = 10 or で対応できない

A + B = CF C は桁上がり,F は 1 桁目の値 ※ A も B も 1 の時だけ C=1,F=0 になる。


ダウト。「or で対応できない」のではなく「論理演算を組み合わせて加算器を作る必要がある」であるべきです。あいまいな表現は不要な誤解を生みます。


四則演算の考え方


コンピュータは基本的に足し算しかできない。従って,他の計算は足し算の繰り返しで行う。

(引き算)

5-3=2の計算は,5に7を足して1桁目の数字を用いる。

※ここで7は3に足して 10 になる数字(1桁あがる数字,補数という)。

引き算は補数を使った足し算


ノー。加算操作を繰り返して四則演算を実現しているのは事実だけど「コンピュータは基本的に足し算しかできない。」 というのは大嘘。前段で加算器の説明したのにこれはどういうことでしょうか。あえて言うのであれば「コンピューターは論理演算しかできない。」でしょうに。

そして、引き算のところで出てきているのは正しくは「10進数での10の補数」。引き算は「5に7を足す」のではなくあくまで「5に-3を足す」ことであって、負数を補数で表現(実際には2進数での2の補数)することで、加算器を使って矛盾なく計算できるということです。この例では10進数1桁同士の減算だという前提条件が隠れているのですが、そのことが全く説明されておらず、率直に言って雑です。


計算誤差について

それっぽく説明されているように見えて何も伝わっていない説明に見えます。誤差が生じるのは、桁あふれ、情報落ち、丸め誤差、打切り誤差といったケースがありますが、整数でも浮動小数点数でも桁が固定だとなぜ誤差が起きるのかの説明が足りません。コード実行結果に浮動小数表記が出てきますが、具体的にどんな数なのかの読み方すら説明されていません。そして生徒から

「小数同士の減算で誤差が出るのはなぜですか?」

と質問されたら先生はどう答えるのでしょうか。現場で「こういうことが起きます」と言うだけでは教育とはいえないのではないでしょうか。


外部装置との接続 ( PDF 12ページ、 通番108ページ )

そもそも掲載順番がおかしくて、外部装置をつないでプログラミングする前に後の「基本的なプログラム」を先に学ぶべきです。途中から唐突にフローチャートやPythonのコードが出てきて「ナニコレ?」となってしまいます。


センサの値をもとに LED を制御するプログラム - 順次構造

フローチャートの


LEDに○を点灯


の項目の前に「LEDに表示する○の形状を定義」という項目があるべきです。


センサの値をもとに LED を制御するプログラム - 条件分岐構造

while ループでウェイトかけずに accelerometer.get_x() かけつづけるのはデバイスにあたえる負担が大きく発熱したりしそうです。


センサの値をもとに LED を制御するプログラム - 反復構造

ループのフローチャートの表現が後の「基本的なプログラム」での表現と合致していません。ループ内に唐突に「LEDにiを表示」とか書かれても何のことだかわかりません。


基本的プログラム ( PDF 20ページ、 通番 114 ページ )


制御構造のプログラム例

Python の制御構造はコードのインデントと密接な繋がりがあるのが全く説明されていません。執筆者は Python の特徴を全く把握していないように見えます。ちゃんとインデントをつけないと動作しないことは説明されるべきです。

蛇足かもしれませんが、この章でのキャプションがすべて「流れ図」「日本語記述」「コード」といういいかげんさはなんとかならないのでしょうか。


応用的プログラム ( PDF 28ページ、 通番 122 ページ )


リスト - リストを用いたプログラムの例

図表 2

a=[56,3,62,17,87,22,36,83,21,12]  # リスト a の定義

sum = 0
sum = a[3]+a[7]
print(sum)

コードスタイルが乱れている上に、なぜ sum0 で初期化したのでしょう?

生徒が書いたものであればまだ許容できるのですが、先生が規範として示すコードとしてはちょっとオススメできません。sum という名前が組み込み変数を上書きしている上に、リスト内の2つの値を加算したものにこの文脈で sum と命名するのは無理筋で、リスト a 全体の値の合計と誤解される恐れがあります。

a[3]a[7] を選ぶことに意味がないのであれば、sum ではなく b くらいでも良いのではないでしょうか。

「コードスタイルの乱れは心の乱れ!」(煽り)


乱数


実行するたびに処理内容が変わるような変則的なプログラムを作成することが可能となり,


乱数を使うこと自体は全く変則的ではありません。

「恣意的な表現は恣意的な教育につながります」(煽り)


乱数 - 乱数を用いたプログラムの例

図表 4 (インデントズレてたのは直した)

import random #random モジュールを読み込む

a = 5
r = random.randrange(10) #0 ~ 9 までの整数をランダムに発生
if a==r:
print(" 当たり ")
elif a>r:
print("a の方が大きい ")
elif a<r:
print("a の方が小さい ")

そもそもベタに書かずに __main__ 使って欲しいところや、 import の後や、a,r の変数定義後に空行欲しいところですが、それに目をつぶったとして、最後の elif a<r: の条件記述は不要で else: であるべきです。

分岐構造のコードを書く時にそれぞれの場合を MECE に数え上げる能力はプログラミングを行うにあたって非常に重要な力なのに、なぜこれほどまでに軽視されているのでしょうか。

それぞれの場合の表示文字列も何を意味するのか類推するのが難しくメッセージとして不適切です。プログラムを実行した際に単に「当たり」とか表示されても予備知識がないと何が起きたのかわかりません。

さらに厳しい指摘かもしれませんが、ar を比較するところでは基準である a は定数に準じる性質のもので、掲載されているコードは条件式の左辺に定数を配置する「ヨーダ記法」のようなテイストがあります。コードレビューで直すほどまでのことではありませんが、生徒(教師)が学ぶためのお手本となるコードではより一般的な記法が好ましいと思います。


アルゴリズムの比較( PDF 34ページ、通番124ページ)


探索アルゴリズム 線形探索と二分探索

図表 3

def linsearch(a,p):

for i in range(0,len(a),1):
if a[i]==p:
print(" 見つかりました ")
break
a = [61,15,82,77,21,32,53]
p = 82
linsearch(a,p)

コードスタイルの件は置いておいたとして、関数についての説明をさんざんやってきた後にこのコードを見せられるのは悲しくなってしまいます。関数の中で「結果を表示させる」という、必要以上の責務(というか副作用)を linesearch に担わせている上に、文字列の変更に弱いコードです。関数に判定結果を戻り値として返させて、それを判別して表示を行うべきです。

そもそも探索で見つからなかった場合の期待する動作が本文に書いていないことも問題です。またこの関数は探索値に加えて探索対象も引数として入力されている一方でフローチャートには「探索値の入力」としか書かれていないところにも不備があります。

図表 6

def binsearch(a,p):

i = 0
j = len(a)-1
while i<=j:
m = int((i+j)/2)
if a[m]==p:
print(" 見つかりました ")
break
else:
if a[m]>p:
j=m-1
else:
i=m+1
a = [25,33,43,51,66,71,88]
p = 43
binsearch(a,p)

コードスタイル、関数についての問題はおいておいたとして、if a[m]==p: の条件分岐に引っかかったときには whilebreak するので、後段の部分は else: にぶらさげる必要はありません。


確定モデルと確率モデル ( PDF 42 ページ、通番 136 ページ)


確定モデルのシミュレーション

コードスタイルまわりの問題は置いておいたとして、ひと通りシミュレーションしたあとに、指数関数で計算できることを示すべきではないでしょうか。単に実行したらOKではなく、モデルを定式化する訓練になると思うのは私だけでしょうか。

と書いたのですが、この資料の前提は中学校で学ぶ範囲での説明することを試みているのですね。後ろの方で三角関数とか出てくるんだけど、大丈夫なのかなー。


自然現象のモデル化とシミュレーション ( PDF 50 ページ、通番 144 ページ)


物体の放物運動のプログラムによるシミュレーション

図表 2

import math as math

... ある意味伝説のコードですね。ちゃんとコードレビューしたのでしょうか?

「みなさんこんにちは、『佐藤』です。これから私のことは『佐藤』と呼んで下さい。どうぞよろしくおねがいします!」(煽り)


全体を通じた学習活動を行ううえでの注意点 ( PDF 58 ページ、通番 152 ページ)


全体を通じた学習活動を行ううえでの注意点


③教える側が得意なプログラミング言語を選択するのではなく,授業のねらいを生徒が達成するのに最適なプログラミング言語を選択する


プログラミング言語がどうこうという議論を行う前に、コンピュータ・サイエンスの基礎を踏まえた研修資料を作られることを望みます。この状況では WebAPI やら AI やら IoT などと掛け声かけても所詮は砂上の楼閣です。


総評

教師向けの研修資料がこんな状況で、生徒にプログラミングを学ばせようというのは相当無理があるのではないでしょうか。私もコードを書くことを生業にしているのですが、将来この資料に書かれている程度(率直に言って何も知らないほうがずっとマシなレベル)の方がエンジニアになることを想像しただけでもぞっとします。

この記事では「Pythonらしい書き方」や環境に依存するかもしれないお作法(#!とか# -*- coding: utf-8 -*-とか)については不問というかスルーしているわけですが、プログラミング言語に依存しないところでもこれだけ不備があるというのは看過できない状況です。

先行する記事 文科省のPythonはPythonじゃねぇ のコメント欄でコーディング規約についての議論というか言いがかりがつけられていますが、私に言わせればコーディング規約は「原稿用紙に日本語の文章を書くときには、段落の先頭を1文字あける」といったルールと一緒で、制御構造をインデントで表現するという Python の考え方、そしてコーディング規約の PEP8 はコードを簡潔に美しく可読性を維持した状態でプログラミングするためのベストプラクティスだと思っています。

原稿用紙はルールを守るけれども、プログラムは動けばOKだからルールをないがしろにして良いものだという考え方は甘えにしか見えません。「〇〇のほうがわかりやすい」といった意見も、「わかりやすさ」を免罪符に思考停止しているのを咎められて逆上している側面があるのではないでしょうか。

もしかしたら「実は執筆者は IT やプログラミングにそれほど明るくない」という言い訳(プログラミング義務教育化を進めているのにそれはどうかと思いますが)が出るのかもしれませんが、IT 要素を抜いた「単なる日本語の資料」と見ても成果物の品質はお世辞にも高いとはいえません。せっかくカラーの印刷物なのに、シンタックスハイライトで色分けする配慮もありません。おそらくこの資料を作るにあたって業務請負として外注したのかと思いますが、執筆者は日本の将来がかかっているという認識を持つべきですし、発注側も質の低い成果物は受け入れ時に検出して弾くということをしっかりやるべきです。

個人的に救いがあるのは、幸いなことに今の私の立場がプログラミング教育界隈から遠く、プログラミング教育を受けるような子供も私にはいないので、純粋に外野からの視点で見ることができることです。関係者の方にはしっかりと振り返りを行い諸々改善されることを望みます。