【高校情報1】応用的プログラム(Pythonプログラミング リスト・乱数・関数・WebAPI・PEP8)動画解説/ 教員研修用教材 学習14
◆◆はじめに◆◆
第3章 コンピュータとプログラミング
学習14 応用的プログラム(Python リスト・乱数・関数・WebAPI)
https://www.mext.go.jp/a_menu/shotou/zyouhou/detail/1416756.htm
別動画でアップしているPython超入門講座は一通り理解している前提で進めています。
基本的には、教員研修用教材に完全に準拠した形で解説していますが、
(P122~)
E.V.ジュニアさんの「文科省情報Ⅰ教員用研修教材第3章の解答の改善案」の記事を参考に動画作成しています。
以下を研修用教材から変更を加えています。
・PEP8のコーディング規約に違反しているものを規約に準拠した形に修正
※過去分のブログ記事コードは順次修正します。
・PEP8チェックのサイトを紹介し、その目的と早い段階からの癖付けを念押し
・演習1 リスト内の最小値を格納する変数名をmin(予約語)⇒miniに変更
・演習2の模範解答でaとrの表示部分が全てのIF文に記載されていて冗長なので、処理の一番最後行うように修正
・関数の 数学の関数との比較は混乱するので割愛
・演習3の『指定した回数p 回2 を加算するプログラム』を作成し,「関数に分割する」という表現はおかしいので、独自に修正
・WebAPIの、JSON形式について詳細説明(この内容でJSONを理解できる人は、いないと思われるため)
個人的にJSONは過去苦い思い出があって、
とあるプロジェクトのプロジェクトリーダをまかされた時に、(Webインターフェース関連はあまり経験がないとき)
別機能を作成している、会社と接続仕様を詰める打合せの際にJSONという言葉が出てきて、私はついていけていなかったこと。
同行してくれてた、下請けの開発会社が優秀なかたで全て受け答えしてくれて助かりましたが。
その夜家に帰ってJSONとかAPIの勉強した覚えが・・・
システム業界はIT業界(プログラミング等々)の知識だけでなく、システムを発注する側の業界の知識(例:〇〇銀行のシステムなら、銀行業務全般、〇〇不動産なら不動産関連業務全般など)が必要になるので、システムが出来上がって次の現場が変わるごとに勉強量が半端ないです。
◆◆動画解説◆◆
◆◆文字おこし◆◆
今日は、コンピュータとプログラミング から応用的プログラムについて学んでいこう。
今回扱う内容は、リスト、乱数、関数、WebAPIだ
リスト、乱数、関数はPython超入門講座で説明しているから軽くおさらいして、Pythonでプロクラムを組んでいこう。
以前、Pythonの標準的なコーディング規約にPEP8ってのがあると説明したよね。
色んな決まりがあるからすべてを把握するのは大変だけど、規約通りにコーディングされているかをチェックしてくれるサイトがある。
◆PEP8チェック
http://pep8online.com/
例えば xに1を代入しているこのソースコードをチェックしよう。
エラーになったね。プログラム自体は実行できるんだけど、規約に反しているってこと。
代入式のイコールの間には半角スペースが必要だったよね。
半角スペースを入れてもう一度チェックしよう。今度は問題ないね。
プログラミング初心者は「動けばいいんじゃない」と思うかもしれない。
一度作って、二度と見ないならそれでもいいかもしれない。
ただ、実際のプログラム開発現場は一度作ったプログラムコードを何度も修正したり、作った本人以外がさわったりすることも多々ある。
作った本人にとっても、数年たてば他人の作ったコードの様に思えることが普通にある。
コーディング規約をみんなが順守すると、プログラムが見やすくなり解析がやりやすくなる。
自分自身の為に作ったプログラムがコーディング規約に即しているか早い段階から確認する癖をつけよう。
じゃあリストについての復習から入っていくね。
リストは複数のデータを格納できるデータ型のことで、ロッカーみたいなものって説明したよね。
この値の入っている箱の一つ一つを要素って言って、その要素を取り出すときは0番から始まるインデックス番号を使うんだったよね。
このインデックス番号は、日本語で添え字というんだ。
2021年3月に発表された、大学入学共通テストのサンプル問題では、添え字という言葉が使われているから、今回からは、添え字という言葉で統一するね。
例えば、name_listというリスト名で
1番目の箱にミライ、2番目の箱にがっきー、3番目の箱に山田という文字が入っているとした場合
Pythonプログラムで表すと、こんな風になる。
[]角括弧の中に入れたい要素をカンマ区切りで入れるんだ。
文字列の場合はダブルクォーテーションで囲む。数値の場合はダブルクォーテーションは不要。
リストの値の参照やリストへの値の代入は,リスト名と添字を使って,「リスト名[添字]」として扱う
例えば リスト名 a というリストがあった場合
この例だと a[0]はaリストの添え字0に入っている値は56となる。
見た目は1番目だけど、添え字は0番から数えるから注意しよう。
#リストの添字3と添字7の値を合計し表示
a = [56, 3, 62, 17, 87, 22, 36, 83, 21, 12] # リストa の定義
goukei = 0
goukei = a[3] + a[7]
print(goukei)
この10 個の数値からなるリストがあったときに,リスト内の数値の一部を取り出し,足し算するプログラムを作成していこう。
添え字の3番と7番の値を足し算する処理にするね。
まずは、リスト a を定義する
角カッコの中にカンマ区切りでリストに格納する数値を記述して、変数aに代入する。
そして、合計値を出力する変数をgoukeiとする。
初期値として0を代入する。
そして、足し算を行う リスト名の後に角カッコの中に取り出したい添字を入れるんだったよね。
ここでは、a[3]+a[7]として、それをgoukei変数に代入する。
print文で変数goukeiの中身を表示する。
じゃあ、実行してみよう。
ちゃんと 添え字3の要素の17と添え字7の要素の83が合計されて100が表示されたね。
じゃあ、今度はリスト内の数値の合計を求めるプログラムを作成していこう。
# リストの要素の合計値を出力
a = [56, 3, 62, 17, 87, 22, 36, 83, 21, 12] # リストa の定義
goukei = 0
for i in range(0, 10, 1):
goukei = goukei + a[i]
print(goukei)
添え字0から9までを繰り返し合計していくから、for文を使っていこう。
リストaとgoukei変数はさっきと同じ
次に繰り返し処理のfor文を記述する。
rangeの中は0,10,1とする これは、以前説明したように0から始まって10未満の数 9までを1ずつ増やしながらループする。
そして、繰り返したい処理を次の行からインデントをして記述する。
リストの中身を合計したいから
goukei = goukei + a[i] と記述する
goukei 変数の値と リストの添字iの値を合計しgoukei変数に格納するという意味
たとえば、初回ループは goukeiが0 a[0]は56だからgoukeiは56となる
2回目のループは goukeiはさっきの56で a[1]は3だから
56+3で59を変数goukeiに格納する。
最後に合計値を表示したいから、
インデントを戻して、print文でgoukei変数の中身を表示する。
実行してみよう。
ちゃんとリストの中の合計値が表示されたね。
ここで問題、今のコードを参考にして リストaの中の最小値を表示するプログラムを作成しよう。
# リスト内の最小値を出力
a = [56, 3, 62, 17, 87, 22, 36, 83, 21, 12] # リストa の定義
mini = a[0]
for i in range(0, 10, 1):
if(mini > a[i]):
mini = a[i]
print(mini)
これは、リストのなかを1つ1つ比較する必要がある。
まず、さっきと同じようにリストaを定義する。
そして、最小値を保存しておく変数をminiとする。
初期値として、リストの添字0の値を代入する。
あとは、リストの要素数分比較する必要があるから for文を記述する。rangeの中はさっきと同じ。
次に、miniに格納されている現段階の最小値と、i番目の要素の値を比較し
もし、リストの要素がminiより小さかったら、最小値になるから
リストi番目の要素を変数miniに格納しなおす。
ループを抜けたらminiにはリスト内の最小値がはいっているから、それをprint文で表示する。
じゃあ、今度は乱数を使ったプログラムを作成していこう。
ある一定の範囲内において,すべての数が同じ確率で現れるような数のことを乱数という。コンピュータはその特質上計算で値を生成するので計算による擬似的な乱数しか生成できない。これを擬似乱数という。
この乱数をプログラム内で使うことで,実行するたびに処理内容が変わるような変則的なプログラムを作成することが可能で,プログラムを現実世界のシミュレーションなどに活用することができるんだ。
実際に、Pythonのプログラムで確認していこう。
ある値a があるときに,0 ~ 9 までの数をランダムに発生させる乱数r と比較して,大きい場合に「a の方が大きい」,小さい場合に「a の方が小さい」,等しい場合に「当たり」と表示するプログラムを作成しよう
# ある値a があるときに,0 ~ 9 までの数をランダムに発生させる乱数r
# それと比較して,大きい場合に「a の方が大きい」
# 小さい場合に「a の方が小さい」
# 等しい場合に「当たり」と表示する
import random
a = 5
r = random.randrange(10) + 1
if a == r:
print("当たり")
elif a > r:
print("a の方が大きい")
elif a < r:
print("a の方が小さい")
print("a=", a)
print("r=", r)
まず、import random でrandomモジュールを読み込む
そして、比較対象の変数aに 5を代入する。
そしてrandom.randrange(10)と0~9までの整数をランダムに発生する機能の呼び出しを行う。引数は10未満の意味 仮に0から10までをランダムに発生させたかったばあいは、11と引数に入れる。
変数rに返却値を格納して、条件分岐に移る。
まずは if a == r: で比較対象の変数aと乱数の値を比較する。今回の場合は乱数が5と一致する場合は、真となる。
真の場合は、当たりを表示するので、インデントをしてprint文の中に当たりと記述する。
そして、次は aの方が乱数より大きい場合は elif a > r: と記述し
次の行をインデントして print("a の方が大きい") と記述する
最後に、 aが乱数より小さい場合は elif a < r: と記述し
print("a の方が小さい")と記述する。
じゃあ、実行してみよう。
〇〇と出力されたけど、これだと乱数に何が払い出されたか分からないから。
aとrの値も一緒に出力するようにしよう。
print(“a=”, a)とprint(“r=”, r)を追加すれば、判定に使った変数の値も一緒に見ることができる。
実際の開発現場でも、プログラム試験をする場合、その処理の中で変数にどのような値が格納されているかを確認するために、一時的に変数の値を出力したりもする。
乱数の生成の範囲を「0 から」ではなく「1 から」に変更したい場合は
生成した乱数に対して1 を加えることで,1 ~ 10 の範囲に変更することが可能となる。
―――――――
じゃあ、次は関数について復習していこう
以前のPython超入門講座で関数について説明したときに、
処理を行う命令のまとまりをブロックに書いてまとめたものと説明したよね。
もう少し掘り下げて説明すると、関数は英語でfunctionで、機能っていう意味なんだ。
つまり、関数という機能の単位で分割することで,プログラムを機能ごとに整理,構造化することが可能となる。また,作成した関数はメインコード内で何回でも呼び出すことが可能となるため,作成した関数を再利用することが可能となる。
Pythonで関数を定義する場合は
def の後に関数名 丸カッコの中に、関数に受け渡す値である、引数を定義して 最後にコロンを付けて
その次の行からインデントして処理を記述する
関数から返却される処理結果を戻り値という。
詳しい内容は、概要欄にリンクを貼っている、Python超入門講座の関数の回を確認してね。
じゃあ、具体的に関数を使ってPythonのプログラミングをしていこう。
まず、受け渡された リスト型の引数a の要素をすべて合計して合計値を返却する関数を作成するね。
# 受け渡された引数(リスト型)の値を合計して返却する関数。
# 関数名:listgoukei
# 引数:a(リスト型)
# 戻り値:goukei (リスト内の値を合計したもの)
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]
goukei = listgoukei(a) # 作った関数listgoukei を呼び出し
print(goukei)
プログラムを記述するときはコメントでどのような関数か引数はどのようなものを想定しているか
戻り値は何かを日本語で記載していると、プログラムの処理を追わなくても目的がわかるし、数か月経って自分自身がソースコードの内容を忘れていても、内容を思い出すヒントになる。
実際のプログラム開発現場ではこのコメントの入れ方も厳密に決められている場合が多い。
次の行をインデントして
goukeiの変数を初期値0として定義する。
そしてfor文でリストの要素数分回すんだけど、具体的にリストの長さがこの時点ではわからない、
リストの要素数を返却する関数にlenというのがあるからそれを使おう
for i in range の中に初期値の0 そして関数lenの中に受け渡されたリストaを格納する 増分は1とする。 これでリストの要素数が5の場合は lenで5が返却されるから、0から5未満つまり4まで繰り返されることになる。
goukeiはさっきと同じ 変数goukei にリストa の添字i 番目の値をプラスして、再度goukeiに代入する。
そして、ループの処理がおわったら return でgoukei変数の値を返却する。
じゃあ、この関数の呼び出しをしていこう
まず、 数値が格納されたリストaを定義する
そしてlistgoukei(a)としてさっき定義した関数を呼び出す。
戻値があるからこれを変数goukei に代入する。
最後にgoukeiの値をprint文で表示する。
実行してみよう。
ちゃんと関数が呼び出されてリスト内の合計値が計算されたね。
じゃあ、つぎは引数で受け渡された回数分、2を加算して、合計値を返却する関数を作成しよう
# 概要:引数で受け渡された回数分、2を加算して、合計値を返却
# 関数名:twogoukei
# 引数:p(繰り返したい回数)
# 戻り値:goukei
def twogoukei(p):
goukei = 0
for i in range(0, p, 1):
goukei = goukei + 2
return goukei
print(twogoukei(10))
じゃあ呼び出していこう 受け渡す引数である繰り返す回数は10にするね
twogoukei(10) で呼び出せる。
値を表示するためにprint文の中にいれてあげよう
実行してみよう。
ちゃんと2を10回合計した20が表示されたね。
=============
今度はWebAPIについて説明するね。
一般的にシステム開発では作成するプログラムは大規模なので,コードの長さも膨大となり,開発期間もその分大きくかかる。
でも、多くのシステムでは、たとえば「ボタンを押したらウィンドウが開く」や「ボタンを押したらファイルが保存される」などの処理について共通していることが多い。
共通している処理について関数に近い形で提供されているんだ。これをAPI(Application ProgramInterface) という。
このAPIを使って開発期間の短縮することもできる。
インターネット上のサービスやビッグデータへのWeb の通信を利用したアクセス機能を提供しているAPI をWebAPIというんだ。
具体的な例で説明するね。
このzipcloudのサイトでは、郵便番号から住所を返却するWebAPIを提供している。
このデータのやり取りをする際に注意しなければならない点がある。
相手側にどういうデータをどのような形で送って、どのような形式で返却されるのかということを決めておかなくてはならない。
大規模なシステム開発は多くの場合、複数の会社でそれぞれ担当の機能を作る。そのデータをWebAPI経由でやり取りすることは多々ある。
プログラミングをする前段階のシステム設計段階でこのインターフェースの詳細が詰められて、それに即してプログラミングや相手側との接続テストを行う。
このデータをやり取りする形式の代表的なものにJSONというものがある。
JSONは国際的に定められたデータ交換フォーマットなんだ。
このzipcloudもJSON形式で郵便番号に対応する住所が返却される。
このサイトは、相手側のWEBAPIのURLと受け渡したい内容を記述すれば、返却値を表示してくれるサイトなんだ。
◆APIテスト
https://anysweb.co.jp/api/
相手側が郵便番号はzipcodeという変数名の中に入れてくださいという決まりを提示しているから、key1にはzipcodeと入力し、その後に郵便番号を入力する。
今回はJSON形式でもらいたいからapplication/jsonを選ぼう
入力が終わったら送信ボタンを押そう
下に返却値出力されたね。この形がJSON形式なんだ。
今回は、resultsという親の箱の中に
住所1、住所2等の値が格納されているイメージ
これをPythonプログラムで記述していこう。
import requests
import json
url = "http://zipcloud.ibsnet.co.jp/api/search" # 使用するWebAPI のURL
param = {"zipcode": "100-0013"} # WebAPI の引数
res = requests.get(url, params=param) # WebAPI の戻り値がres へ
response = json.loads(res.text)
address = response["results"][0]
print(address["address1"] + address["address2"] + address["address3"])
まず、相手側にデータを送るのに requestライブラリが必要になるからインポートする
そして、JSON形式で返却されたものを分解するのにJSONライブラリが必要になるからこれもインポートしよう。
変数urlにはWebAPIのURLを入力する。
paramはこのような形でzipcode のkey値に対して 100-0013 という郵便番号を指定る。
そして、requests.getの機能で実際に相手側に問い合わせを実施する。
引数にはさっきのurlとparamを渡してあげる
JSON形式でデータが返却されるから それを変数 resに一旦格納する。
そしてjson.loadsでJSON形式のデータの読み込みを行い response変数に入れてあげる。
この時の型は、辞書型という型で格納される。
さっき見たように resultsという親の箱の中にデータがあるから
親の箱の名前を指定して、データを取り出してaddress変数に格納する。
子のデータのaddress1やaddress2を取り出す場合は、
変数address 角カッコの中に取り出したいキー値名を入れてあげると取り出せる
例えばaddress1を取り出したい場合は
address[“address1”]と入れる
実行してみよう。
エラーになったね。
実はこのライブラリは外部ライブラリだから別にインストールする必要がある。
以前Python超入門講座のライブラリの回で説明したように、インストールはpipコマンドを使う。
コマンドプロンプトを立ちあげて
pip install requestsと入力してエンターを押そう。
インストールが終わったらもう一回実行してみよう。
今度は正しく住所が表示されたね。
今回のWebAPIは新しい用語が沢山出てきて、まだ理解できていないと思うけど、別の動画で詳しく説明する予定だよ。
◆PEP8チェック
http://pep8online.com/
◆APIテスト
https://anysweb.co.jp/api/
◆zipcloud
http://zipcloud.ibsnet.co.jp/