見出し画像

文科省研修用教材を検討する(5) プログラミング(2)

学習14 応用的プログラム の続き。

(3) 関数

関数の説明は次のようになっている。

一般にシステム開発などで行われるプログラムは大規模なので,コードの長さも膨大となる。このような場合, 文章の章,節,段落のような適切な構造を作らないと,コードの可読性は著しく低くなってしまう。 そこでプログラムの機能ごとにメインコードから切り離し,関数という単位で分割することで,プログラムを 機能ごとに整理,構造化することが可能となる。また,作成した関数はメインコード内で何回でも呼び出すこと が可能となるため,作成した機能を再利用することが可能となる。

一見するとよさそうだが,どこかひっかかるところはないだろうか。

その後の例と課題を見てみよう。
次の図表3を関数に分割することを考える,という例。

画像2

それが次の図表9だ。

画像2

どうだろう。「関数に分割」する意味がわかるだろうか。
「長くなっただけじゃないか」と思われた人は正しい感覚をしている。そう,これでは長くなっただけ。

そのあとに,<演習3>がある。

<演習3>
上の図表 9 のコードを参考にして『指定した回数 p 回 2 を加算するプログラム』を作成し,関数に分割してください。なお引数は「繰り返す回数 p 」,戻り値は「加算した結果」としてください。


 しかしこの例題と演習で「関数で分割する必要性」が理解できるだろうか。
何のために関数化するかという認識が間違っているのではないかとさえ思える。

関数化するメリットは,次のような使い方をすることにある。 

def listgoukei(a):
      goukei = 0
      for i in range(0,len(a),1):
      	    goukei = goukei + a[i]
      return goukei
 
 a =  [56,3,62,17,87,22,36,83,21,12]
 print(listgoukei(a))
 b =  [39,23,12,77,17,62,96,33,28,82]
 print(listgoukei(b))


これを,合計を求める部分を関数化しないで書いた次のコードと比べてみるとよい。

a =  [56,3,62,17,87,22,36,83,21,12]
goukei = 0
for i in range(0,len(a),1):
   goukei = goukei + a[i]
print(goukei)
b =  [39,23,12,77,17,62,96,33,28,82]
goukei = 0
for i in range(0,len(b),1):
   goukei = goukei + b[i]
print(goukei)

合計を求める部分を関数化したのは,プログラムを「分割」するのではなく,「構造を簡素化」するためなのである。「合計を求める」という同じような作業が複数回出てくるで,その機能を持った関数を作って利用した。そのために,

リスト a を定義する。
aの合計を求める。
リスト b を定義する
bの合計を求める。

というプログラムが冗長性を排して簡素に記述できたわけだ。

次のような例もある。大学入試センター試験「情報関係基礎」2007年の問題を実際にコーディングした例である。
元の問題はこうなっている。条件判断の部分だ。

画像3


 ここで,数ブロックとは整数,演算ブロックとは文字 "+","-","×" のいずれかである。
 数ブロックかどうかの判断は組み込み関数を使えばよい。演算ブロックかどうかの判断は,そのような組み込み関数はないわけだから,ユーザー定義関数を作るのだ。

def isop(block):
   return(block == "+" or block == "-" or block == "*")

これだけのことだ,この関数 isop() を使えば,問題の部分は

if isinteger(T[x-1,1]) and isop(T[x,1]) and isinteger(T[x+1,1])

のように書けてすっきりする。なお,isinteger() のところは,Pythonでは,isinstance(T[0][x-1],int) と書くことになるだろう。

 つまり,関数を定義して用いるのは,プログラムを分割することではなく,ある機能を持ったプログラムを作って構造を簡素化すること,なのである。もちろん,結果的に一度しか用いず,プログラムを分割して可読性を増した,というだけのこともある。しかし,もともとの意味は「分割」ではないのだ。 したがって,<演習3>は次のように表現すべきだ。

上の図表 9 のコードを参考にして『指定した回数 p 回 2 を加算する』機能を持った関数を作成し,それを利用して,50回2を加算した結果と75回2を加算した結果を表示してください。なお引数は「繰り返す回数 p 」,戻り値は「加算した結果」としてください。


(4)WebAPI

 例として,郵便番号から住所を検索する方法が載っている。説明はこうだ。

Python で WebAPI を扱う場合は OS のコマンドプロンプトを起動し,pip install requests と入力して requests モジュールをインストールし,requests モジュールと json モジュールを import 文で取り込む必要がある。また, この例で使用する WebAPI は「http://zipcloud.ibsnet.co.jp/」が提供するものである。この例では指定する郵便番号を「param = {"zipcode": "100-0013"}」で郵便番号 100-0013 を指定している。なお,実行結果は「東京都 千代田区霞が関」と表示される。

 まず,「requests モジュールをインストール」の件だが,その前に,Pythonをどのようにインストールし,どのような環境で使っているかが問題になる。直接 Python をインストールしたならば,pip コマンドで様々なライブラリ・モジュールをインストールすることが必要になる。しかし,Anaconda を利用したのであれば,すでにこのモジュールは入っているのでインストールは不要だ。
 このテキストでは,Pythonの場合には大前提となるインストール方法や,コマンドラインで Python を使うのか,IDLEを使うのか,Jupyter notebook を使うのか,といったことには一切言及されていない。にもかかわらず,ここで「pip install requests 」といきなり書くのはいかにも奇妙ではないか。
 このテキストを研修会で使うのであれば,初めにインストール方法もやるのかどうか。やらないなら当然必要なモジュールはインストールされているはずである。

この例で使用する WebAPI は「http://zipcloud.ibsnet.co.jp/」が提供するものである。

はデータを提供しているURLを示しているわけだが,これを提供しているのは「郵便番号配信サービス zipcloud」である。
したがって, 

この例で使用する WebAPI は「郵便番号配信サービス zipcloud (http://zipcloud.ibsnet.co.jp/)」が提供するものである。

と書くべきだろう。生徒によく言っているのは,出典を示すときはURLではなく,何のページかを書きなさい,ということである。その上でURLを書くならよい。URLだけだとなんのことかわからない。中には,Windowsで文字化けしたURLをそのまま貼ってくる生徒もいるのだ。

閑話休題。

このあとにサンプルコードがある。

import requests
import json
url = "http://zipcloud.ibsnet.co.jp/api/search"  #使用するWebAPIのURL #WebAPIの引数
param = {"zipcode": "100-0013"}
res = requests.get(url,params=param)    #WebAPIの戻り値がresへ
response = json.loads(res.text)
address = response["results"][0]
print(address["address1"] + address["address2"] + address["address3"])

該当ページに行ってみると,リクエストのしかたが書いてある。 

それに従って書くと,

param = {"zipcode": "100-0013"}
res = requests.get(url,params=param)    #WebAPIの戻り値がresへ

は,次の1行でも書ける。

res = requests.get(url,params="zipcode=1000013")

また,この戻り値を

print(res)
print(res.text)

で表示してみると次の結果が表示される。

画像4

研修会で使うのであれば,こういう実験:元ページにアクセスして,コードを変えたり,戻り値を表示するくらいのことはやってみるべきだ。
そうでなければ,【研修の目的】にある

API の概念を理解し,外部のビッグデータや処理機能を活用できるようになる。

など,到底望めない。

ところで,「学習活動と展開」に,次の記述がある。

関数の理解から API の必要性を理解する。

奇妙な話だ。関数を作るにあたって,APIの必要性を理解する必要はない。

以上,関数についての節についていくつか補足した。


<追記>
 三重大学の奥村先生より,PEP8(Pythonコードのコーディング規約)についてご教授いただいた。
 その詳細はここには書かないし,研修会でもやる必要はないと思うが,そういうものがあることや,いくつかの例示はしたほうがいいだろう。
 研修用教材で自学,ということであれば,やはりPythonに限らず,その言語のkーディング規約について書いておかないと,初心者は何もわからないのだから。

 ただし,Pythonの場合,

のようなこともあり,初心者にはなんのことやらわからないこともある。
たとえば,「複数の文を1行で書く」は,プログラミングの経験者ならわかるが,初めての人にはわかりにくいだろう。こういったことも,研修会で触れるか,あるいは,教科の研究会などでの勉強会をやるのもいいだろう。

 ともかく,教員自身ができるだけ正しい知識を持っておかないと,これからは大変だということだ。