文科省のPythonはPythonじゃねぇ


TL;DR

文科省によるプログラミングの教材は最悪。PEP8読め。

追記

もちろん、この指摘が普通のコードに対するものだとすれば「重箱の隅をつつきすぎ」だというのは全くその通りだと思います。こんな指摘をするつもりはさらさらありません。

しかし、これが文科省という権威ある機関が発表するものならば話は全く違います。

全ての日本の教育を一身に背負うくらいの気持ちと成果を伴わなければならないとも思います。

そういう理由での、厳しい(というか細かい)指摘です。

追記2

自分の説明が足りませんでした(すみません)。ちなみにこの教材は「教員研修用」です。

この教材で研修を受けた教師にプログラミングを教えられると思って考えてみてほしいと思います。


なにがあったか

ネットを見ていると、こんな記事を見つけました

高校生全員が「Python」を履修するかも。「情報科」における学習内容、Pythonやmicro:bitが例示に挙がりましたが致命的なミスが!

おっ!Pythonなのか!!

と思いましたが、よくよく見てみるとコードがひどい。

MicroPythonでの実行を想定しているそうなので、Python3での実行として添削します。

特に、基礎的で大切な部分のみ添削したいと思います。

以下が実際のコードの載っている資料です。


添削開始

基本的に全て添削対象ですが、特にヤバいもののみ取り上げます。

また、一度言ったことはその後には書きません。

早速


全角スペース使うな

まず初めに、8ページ目のコードから

import sys                 # 変数や関数のライブラリを呼び出し

x=sys.float_info.max             #float 型で表せる最大値を x に代入
print(x)                   # 画面に x の値を表示
x=1.797693134862315799999e+308     #float 型の小数点以下に 5 桁「9」の追加した値を代入
print(x)                   # 画面に x の値を表示
x=1.8e+308                 #float 型の最大値より大きな値を代入
print(x)     

はい。赤線だらけですね。これを綺麗にしてみましょう。

import sys  # 変数や関数のライブラリを呼び出し

x = sys.float_info.max # float 型で表せる最大値を x に代入
print(x) # 画面に x の値を表示
x = 1.797693134862315799999e+308 # float 型の小数点以下に 5 桁「9」の追加した値を代入
print(x) # 画面に x の値を表示
x = 1.8e+308 # float 型の最大値より大きな値を代入
print(x)

言いたいことは以下の点です。


  • コメントアウトの#の前には半角スペース2つ以上(今回では守られてますが)、あとには1つ

  • 「=」 などの計算記号の前後には半角スペース

  • てかまず全角スペース使うな(コメントアウトのためのスペースが全角になっている)(PDF化の時に全角になった説も十分あり得るというか多分そう、そうじゃなきゃ困るが、それでもそうならないよう気遣うぐらいして♡)

変なコードなんてレベルじゃないですね。これを教育に使うなと。


組み込みをシャドウするな

28ページのコードです。

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

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

これは極刑ですよね

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

sum_val = vals[3] + vals[7]
print(sum_val)

つまり、こういうことです


  • 組み込み関数を上書きするな

  • カンマ「,」の後にはスペース

  • 変数名は意味を持たせろ

sumという関数はデフォルトで用意されています。それをたった一度の宣言で上書きするなんて、正直考えられません。

計算させたいのは分かります。コード書いて理解してねっていう気持ち。

でも、実行時環境を汚すのは別問題です!

また、同じページ

a=[56,3,62,17,87,22,36,83,21,12]

sum = 0
for i in range(0,10,1):
sum = sum+a[i] #a[0] ~ a[9] まで全て加えていく
print(sum)

なんのためにPythonを選んだんですか?

こうしましょう。

vals = [56, 3, 62, 17, 87, 22, 36, 83, 21, 12]

sum_val = sum(vals)
print(sum_val)

こうしないまでも

vals = [56, 3, 62, 17, 87, 22, 36, 83, 21, 12]

sum_val = 0
for i in range(10):
sum_val += vals[i]
print(sum_val)

あるいは

vals = [56, 3, 62, 17, 87, 22, 36, 83, 21, 12]

sum_val = 0
for i in vals:
sum_val += i
print(sum_val)

こうかく努力はすべきです。

注意すべき点は


  • インデントはスペース四個

  • 「a = a + b」 は 「a += b」と等価、こういうことはrangeより先に教えるべき

  • range(0, 10, 1)よりrange(10)を教えよう

  • てか、シャドウするようならそれを使ってあげてよ

言いたいことがちょっとぶれてますが、要するに、それって学ぶ順番間違ってるでしょってことです。


さっきとやってることちゃうやんけ

29ページ、乱数に関する項から

import random

r = random.randrange(10)+1
print(r)

さっき、思いっきりrange(0, 10, 1)とかやっとったやん……

import random

r = random.randrange(1, 11)
print(r)

なんでrange(0, 10, 1)ができてrandom.randrange(1, 11)ができないんですか!


さっき(二行目前)とやってることちゃうやんけ

29ページのコードです

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 の方が小さい ")

なんでインデント揃ってないんですかーーーー!!!???

import random

a = 5
r = random.randrange(10)
if a == r:
print(" 当たり ")
elif a > r:
print("a の方が大きい")
elif a < r:
print("a の方が小さい")

はぁ……


言葉は慎重に選ぼう

31ページより


 Python で WebAPI を扱う場合は OS のコマンドプロンプトを起動し,pip install requests と入力して requestsモジュールをインストールし,requests モジュールと json モジュールを import 文で取り込む必要がある。


おいちょっと待て!

それはライブラリだ!モジュールではない


@amuyikam様の指摘が無ければ見逃していました


Python で WebAPI を扱う場合は(略)requests モジュールと json モジュールを import 文で取り込む必要がある。

...は?

なんでrequestsjsonを用いる必要があるんですか(正論)


@toritoritorina様からの指摘を受けて追記。厳密に言えば、モジュールを間違いとするのは正しくないかもしれません。というのも、パッケージはモジュールの仲間だという言い方もできるからです。

とはいえ、例えばイヌ科の動物であるタヌキだと言い張るのはおかしいですよね。

いやまぁ、この例がおかしいのは分かりますが、なんとなくそういう気持ちっていうことです。

また、Whats the difference between a module and a library in Python?に分かるように、Pythonを書いている人間からは明らかに違ったものとして扱われているという事実もあります。

こういったことを無視してモジュールでくくってしまうのは、誤りに思えてなりません。



Python3...だよね?

36ページより、二分探索をする項です。

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)

int((i+j)/2)ってマジ?こうすべきです。

def binsearch(a, p):

i = 0
j = len(a) - 1
while i <= j:
m = (i + j) // 2
if a[m] == p:
print(" 見つかりました ")
return
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)

Python3にはa // bという数学記号があります。それを使ってください(半ギレ)


もう疲れた

もうこれ以上は疲れました。ちょっと長すぎます。

皆さんも良ければ探してみてください。


編集履歴



  • @takuyakubo様から誤字の修正をいただきました。僕も敗北者でした。


  • @saturday06様からまたもや誤字修正。土下座じゃ済まねぇ……。

  • コメントアウト前のホワイトスペースに関して、記述を直しました。指摘していただいた方ありがとうございます。