Pythonプログラミング(ステップ2・プログラムの基本的な書き方)
このステップの目標
- Pythonプログラムの定型的なパターンを元に、「直線的」な流れのプログラムが記述できる
- print()関数, input()関数を使った基本的な入出力動作が記述できる
- 変数宣言、式の計算と代入を組み合わせ、変数の値の変化を把握しながら、プログラムを構成できる
1. プログラムの書き方
このステップからは、アルゴリズムを具体的なPythonのプログラムに翻訳する方法について学んでいこう。
まずは、感じをつかむために、簡単なPythonのコードの例を以下に示す。
import urllib.request def getContent(url): res=urllib.request.urlopen(url) page=res.read() return page.decode(encoding='utf-8') url=input("URL: ") print(getContent(url))
このコードを実行すると、URLを尋ねてくるので、"http://www.tohoku.ac.jp" のように入力すると、 そのウェブサイトのデータ(HTML)が表示される。 言わば、最も原始的なウェブブラウザといったところである。
文章にも「文の終わりには句点。を付ける」などのルールがあるように、Pythonのプログラムにも基本的なルールがあるので、ここでそのいくつか確認しておこう。
ここは結構大切
-
プログラムは原則的に半角英数字で記述する。プログラムと途中に日本語の文字が混じっているだけでエラーになる(コメントなど、一部、日本語を書いてよい箇所もあります)。特に日本語のスペースには注意すること。TurtleEditで日本語文字はオレンジ色の破線で囲まれて表示されるので、確認の際に参考にするとよい。
良い例: if x==y: z = x 悪い例: if x==y: z=x
- Pythonでは大文字と小文字は区別して扱われる。例題などで小文字のところを大文字に書き換えてはいけない。
また、括弧
( ), { }, [ ]
はそれぞれ用途が異なり、正しく使い分ける必要があるし、コロン:やクォート"などの記号もコードの重要な部品である。 - プログラムはたくさんの文 (statement)の集まりである。文は基本的に1行ずつ改行しながら記述する。
例: x=3 x = x + 3 print("x=",x)
- 文章の段落に相当するものをブロック(block)と呼ぶ。ブロックはコロン(:)に続く行の「字下げ」によって表現する。
同じブロックに属する文は字下げ量(行の左端からの「隙間」の大きさ)が揃っていなければならない。「1段下げるのに半角スペース4つ」が標準的。
正しい例 間違った例(字下げが無い) 間違った例(字下げが不揃い) import urllib.request def getContent(url): res=urllib.request.urlopen(url) page=res.read() return page.decode(encoding='utf-8') url=input("URL: ") print(getContent(url))
import urllib.request def getContent(url): res=urllib.request.urlopen(url) page=res.read() return page.decode(encoding='utf-8') url=input("URL: ") print(getContent(url))
import urllib.request def getContent(url): res=urllib.request.urlopen(url) page=res.read() return page.decode(encoding='utf-8') url=input("URL: ") print(getContent(url))
- コンピュータープログラムの文法は厳密に定義されている。コンマ1つ、大文字と小文字を一カ所、括弧を1つ間違えただけでも、エラーになったり、意図しない動作をする。
ここで、Pythonに限らず、全てのプログラミング言語の共通した「構造」あるいは「パターン」を知っておこう。 基本的に、コンピュータプログラムは
宣言部(以下に記述するプログラム本体に必要な設定など) 計算処理手順の記述1 計算処理手順の記述2 ... |
という形式で記述される。この節の始めのプログラム例では、宣言部が import urllib.request
で、計算手順の記述として、まず、getContent
という「関数」を定義した後、最後の2行で、キー入力と結果の出力を指示している。
2.何もしないプログラム
いよいよ「役に立つ」Pythonプログラミングを学ぼうとするときに、出鼻をくじくようだが、まず、何も結果を生じないコードの例から始めたい:
例題0(ex0.py)
# Example 0 # coding: utf-8 123 3.1415926 "I love Python." '広瀬川'
このプログラムの各行の説明:
# Example 0
- # から行末まではコメントと見なされ、プログラムの実行には一切関係しない。#の後には必ずスペースを1つ入れること。
"I love Python." # 文字列の例
のように書くと、#
から行末までがコメントと解釈される。
# coding: utf-8
- コメントの一種ではあるが、プログラムが記述されている文字コード(utf-8)をPythonの処理系に伝える役割を果たす「呪文」である。 Python 2でコード中に日本語文字を含む場合は、プログラムの先頭部分に必ずこの行を加えておく。 Python 3以上ではこの指定は必要無い(あっても問題ない)。
123
- 整数の123がデータとして入った「箱」を生成する。ここで「箱」とは、コンピュータのメモリ上のデータに対応しており、オブジェクト(object)とも呼ばれる。負の数は
-123
のように表す。
3.1415926
- 実数の3.1415926がデータとして入った「箱」を生成する。
$1.054 \times 10^{-34}$のような指数表現も可能で、
1.054E-34
と記述する。
"I love Python."
- "I love Python." という文字列(テキスト)データが入った「箱」を生成する。 対になったダブルクォーテーションマークの「中身」がデータ(クォーテーションマークそのものはデータに含まれない)。
'広瀬川'
- 「広瀬川」という文字列(テキスト)データが入った「箱」を生成する。 文字列を表す際に、シングルクォートを使っても良い。
このように、この例題のコードを実行すると、整数、実数、文字列のデータがそれぞれ格納された「箱」がコンピュータの内部に生成されるが、 我々はそれを見ることができない。 そこで、次の例題では、データの内容を、スクリーン上にプリントする方法を学ぶ。
「真」 True
「偽」 False
「無」 None
その他の基本的なデータとして、論理的な「真」を表す True
、「偽」を表す False
、
データの実体が「無い」(どのようなデータにも該当しない)ことを表す None
もよく登場する。
3.文字の出力
以下のプログラムをエディタで入力し、実行してみなさい。"Hello!" の部分は、自分の好きな言葉などに変えても構わない。 ファイル名は ex1.py で統一しておこう。
例題1(ex1.py)
# Example 1 # coding: utf-8 print("Hello!")
例題1のアルゴリズム
Input:
Output: "Hello!"の文字列
1: "Hello!"と出力し、改行する
2: 終了する
このプログラムの主な見所は以下の通り:
print("何々")
動作:文字列の出力- 画面に「何々・・・」を表示する。「何々」は日本語でも構わない。
文字列の最後は自動的に改行される。
Python 2では、丸括弧をつけずprint "何々"
と記述する。
print(123)
やprint(3.1415926)
のようにして、数値データをプリントすることもできる。
バックスラッシュ($\backslash$) は ¥ キーで
print("一行目\n二行目\n三行目")
のように、文字列中に \n
(バックスラッシュ n)と書くと、\n
の箇所に差し掛かった際に「改行」される
(\n
は2文字が対になって改行という動作を表し、"\n"はプリントされない)。
改行とは、エディタやワープロでEnterキーを押した際の動作のこと。
バックスラッシュ $\backslash$ をタイプする際には、日本語キーボードでは¥記号を押す。
その昔、米国のコンピュータを日本に輸入する際、
金額処理にどうしても必要な¥記号を、$\$$記号と入れ替えるわけにもいかなかったため、使用頻度の低かった$\backslash$の文字コードに¥を割り当ててしまった名残である。
アスキーアートは、いかにも ローテクな気もするが、それでいて、結構味わい深い。 ここでの例を参考にすれば、絵心のある人は、アスキーアートを出力するプログラム(UNIXコマンド)を作成することができるはずだ。 その際、日本語文字を用いると、エディターや端末エミュレータの設定によっては、「文字化け」が起こるかもしれないので、注意すること。
練習:「花文字」のプリント
このプログラムを改造して,画面に以下のような「花文字のP」を出してみなさい。
******** ** *** ** *** ******* ** ****
解説
文を順に書き並べると、その順に実行される。 例えば、
# print 1,2,3 print("1") print("2") print("3")
を実行すると,画面には
1 2 3
と出力される。この一見当たり前にも思える動作を,まず飲み込んでおこう。プログラムの「流れ」の様子を図にすると,左のように描けるだろう。このような図を流れ図(フローチャート)と呼ぶ。 特に指定しなければ,プログラムというのは「上から下へ順番に」実行される。大切なのは、前の文の処理が完了してから次の文の処理に移る、という点だ。
亀場で練習:グラフィックスで文字を描く
補助教材の「亀場」のイントロダクションのページを開き、 同じページのかなり下の辺りにある練習課題 のうち、アルファベットのPをグラフィックスで描画するプログラムを完成させなさい。
4.変数を使った式の計算
以下の例題をエディタで入力して、実行してみなさい(ファイル名は ex2.py にしよう):
例題2(ex2.py)
# Example 2 # coding: utf-8 a=int(input("整数を入力:")) b=int(input("整数を入力:")) s=a+b print("合計=",s)
例題2のアルゴリズム
Input: 2つの整数 $a,b$
Output: 整数の和 $a+b$
1: "整数を入力:" と出力し、入力データを整数値に変換し、変数$a$に値をセットする
2: "整数を入力:" と出力し、入力データを整数値に変換し、変数$b$に値をセットする
3: $a+b$ を計算し、結果の値を変数 $s$ にセットする
5: "合計= "に続いて、$s$ の値を出力し、改行して、終了する
TurtleEditを使っている場合は、マウスで下側の区画(コンソール)をクリックし、赤くて四角いカーソルが表示されている状態で、キーボード入力を始めること。
プログラムを実行すると、画面に 整数を入力:
と出るので、半角文字で整数入力し、Enterキーを押す。
するともう一度 整数を入力:
と出るので、整数を入力し、Enterを押す。
例えば 7と2を入れたとすると、二つの数の和(9)が出力されるはずだ。
解説
Python言語の主なデータの型
整数は int
実数は float
文字列は str
算術演算
+
加算
-
減算
*
積
/
実数除算
//
整数除算
%
剰余
**
べき乗
数式を記述する際の注意点
・乗算記号 * は省略できない。a*b を a b と略すことはできない。
・演算の優先度を表す際に使えるのは丸括弧のみ。a*(b+c)をa*[b+c]等と書いてはいけない。
・整数のみの演算の結果は整数値。1//2 は 0.5 ではなく 0。1/2 は 0.5。
プログラムの見所は以下のとおり:
a=int(input("整数を入力:"))
動作:"整数を入力:"と出力し待機、キーボードから入力した内容を整数に変換して変数aにセットする-
Step 1.
input("何々")
で、画面に"何々"を出力して、キーボードからのデータ入力待ちとなる。
Step 2.int(何々)
は、「何々」で表されるデータを整数(integer)型のデータに変換する働きをする。
Step 3.a=データ
は、データ(数値等)を、変数 a にセットする(データに a というラベルをつける)。
a=int(input("整数を入力:"))
は、上記の3ステップを1行にまとめて表現したものである。
-
b=int(input("整数を入力:"))
動作:上と同様に整数値をbにセット - 代入先が変数bになっている他は、上と全く同様。
s=a+b
動作:計算と代入-
変数 a の内容と b の内容を加算して、結果を変数 s に代入する(結果の数値データに s というラベルをつける)。
ここで、
=
は代入操作を表しており、等号ではない点を十分意識すること。 数学的な計算に使う記号(演算子)には、+
(加算)のほかに、-
(減算)、*
(乗算)、/
(除算)、//
(整数の除算)、%
(剰余)などがある。 また、計算順序は、通常の数式と同様、乗除が優先され、丸括弧( )
を使ってコントロールすることができる。 基本的に、数式は数学の教科書のように記述できるが、乗算記号*
は省略できない点に注意。 例えばPythonの計算式としてs=(a+b)(c+d)
は誤り(括弧の間に*
が必要)である。
print("合計=",s)
動作:結果の出力-
print(何々)
の「何々」の中身には、コンマで区切りながら、複数の項目(文字列や変数、式)を並べることができる。 変数や式を書くと、その「値」がプリントされる。
このプログラムの一連の動作を図で示すと,以下のようになる:
例題2の動作の流れ
変数の使用
プログラミングにおいて、変数を的確に操作できるようになるのはとても重要である。 変数とは、データの入った「箱」に付けたラベルのようなものである。 Pythonでは、この箱のことをオブジェクト(object)と呼ぶことがある。 箱とラベルは同一視して構わない場合が殆どであるが、区別が必要なケースもある。 ここでは、箱とラベルの比喩に沿って、変数の使い方と動作について今一度確認しておこう:
- 箱の中身のデータには、整数(int)、実数(float)、文字列(str)等の基本的なタイプ(型)がある(これらを組み合わせたより複雑なデータを格納することもできる)。
- 演算結果の代入
x = 式
は、式の計算結果がデータとして入った箱に、ラベル x を付ける操作。 - 変数同士の代入
x = y
は、ラベル y の箱に、さらに x というラベルを貼り付ける操作(見かけ上、y のデータを x に移すのと等価。その結果、箱には x と y という2つのラベルが貼られる)。 - 代入操作
x = x + 1
は、箱 x の中身の値に1を加えた値の入った、新調した箱 にラベル x を付け直す操作(古いほうの箱はその時点で廃棄される)。
変数名(ラベル名)の付け方は自由なので、その働きや意図に応じて、わかりやすい名前を決めるとよい。 言い換えると、例題プログラムの中の a が a である必然性は無く、x でも y でも addr_1 でも hensuu でも構わない (例題の a のところが、何故 a なのかを悩んだとしても、その答えは無い)。 ただし、数字で始まる 123_x や、記号を含む pi% などは、変数名として不可である。
練習:べき乗の計算
Pythonにはべき乗演算**
が用意されているので、
$x^n$ は x**n
で計算できる。
ここでは、アルゴリズムの学習のため、この機能を使わないでべき乗の計算をしてみる。
ある実数を8乗した値を、以下の手順で求めたい。この手順を「素直に」Pytnonコードに翻訳し、動作を確認してみなさい。
Input: 実数x
Output:x
を8乗した値 1: 実数型の変数x
を用意する 2:x
に、キーボードから実数値をセットする 3:x
の二乗(x*x
)を計算し、その結果を改めてxにセットする(x
には、入力値の2乗がセットされた) 4:x
をさらに二乗し、その結果を改めてx
にセットする(x
には、入力値の4乗がセットされた) 5:x
をさらに二乗し、その結果を改めてxにセットする(x
には、入力値の8乗がセットされた) 6:x
の値(答え)を出力する
x
の8乗を求めるには、7回のかけ算(x*x*x*x*x*x*x*x
)を行うのが愚直な
計算方法と言えるが、上の手順ではこれが3回のかけ算に「節約」できている。変数を用いて、中間的な結果を使いながら
計算を進めるところがポイントだ。
ヒント
例題2(ex2.py)をひな形にして作業をはじめるのが良いだろう。
この場合は実数で計算したいので、入力データは実数(float
)に変換する必要がある。
実数(float)型のデータ入力
実数型のデータを変数x
にキーボードからセットするには、x = float(input("実数値="))
のように記述する。
練習:三角形の面積
三角形の三辺の長さ(ここでは$a, b, c$としよう)を入力すると、その面積を計算して画面に表示するプログラムを作成しなさい。
ヒント
ヘロンの公式(Heron's formula)によれば、 $s=(a+b+c)/2$ とすると、三角形の面積 S は$S = \sqrt{s (s-a) (s-b) (s-c)}$ で与えられる。この公式を活用しよう。
面積は実数値を取るので、整数(int)を使った計算では不十分であため、実数型(float型)で計算する必要がある。変数 $a$ に実数値をセットするには、a=float(input("aの値="))
とすればよい。
変数にひとつずつ値をセットするのは煩わしいので、3つの変数にまとめて値をセットする方法も可能である:
-
a,b,c=map(float,input("a,b,cを入力:").split())
と書くと、例えば、キーボード入力が3 4 5 Enter
の場合、aには3、bに4、cに5がそれぞれセットされる。その際、数値と数値の間はスペースで区切る。
この文の動作が気になる人への補足情報:"3 4 5"という文字列が split()の作用で ["3","4","5"]という3つの文字列のリストに変換され、map()の作用で、それぞれの文字列にfloatを作用させて実数のリスト[3.0,4.0,5.0]が得られる。a,b,c=で、リストの要素の値がそれぞれの変数に代入される。 -
Python 2の場合は
a,b,c=map(float,raw_input("a,b,cを入力:").split())
と記述する。input() ではなくraw_input( )を使用する点に注意。
平方根(square root)を計算するには、Pythonに標準の追加機能として用意されているmath.sqrt( )
関数を使う。例えば、z = math.sqrt(x*x + y*y)
と記述すると、x*x+y*y(xの二乗とyの二乗の和)の平方根がzに代入される。(math.sin(), math.cos(), math.tan(), math.exp(), math.log()
なども同様に使用可能)。
数学関数を使う場合は、宣言部に import math
と記述しておくこと。
まずは、以下のプログラムのひな形から出発してみなさい:
# coding: utf-8 import math a,b,c=map(float,input("3辺の長さa,b,cを入力:").split()) ????? ????? ?????
練習:桁の入れ替え
以下の動作を行なうプログラムを、Pythonでコーディングしなさい(参考書の例題2.1に対応):
- 10進で2桁の自然数$n$を入力する
- $n$ の10の位と1の位を入れ替えた数を出力する(例えば$n=19$ならば、$91$を出力する)。
ヒント
1の位の数値は『10で割った余り(剰余)』で得られる。
Pythonで整数の剰余を求める演算子は %
である。
『nを10で割った余りを変数oneに代入する』という動作は、Python言語では
となる。
2桁目の数字(34なら3)は、(整数同士の計算として)n
を10で割れば得られる。
ひな形
# coding: utf-8 n=int(input("2桁の自然数:")) ???? ???? ???? print("入れ替え後の数=",n)
亀場で練習:三角形の描画
3辺の長さa,b,cを与えると、辺がちょうどその長さになっている三角形を亀場に描くプログラムを作成しなさい。
ヒント:
基本的な手順は
- (方向はともかく)距離aだけ進む。
- $\pi$から辺ab間の角度を引いた角度だけ左に回転する。
そうすると、回転角度は $\theta_1 = \pi - \arccos\left(\frac{a^2+b^2-c^2}{2ab}\right)$ラジアン。 - 距離bだけ前進する。
- $\pi$から辺bc間の角度を引いた角度だけ左に回転する。
そうすると、回転角度は $\theta_2 = \pi - \arccos\left(\frac{b^2+c^2-a^2}{2bc}\right)$ラジアン。 - 距離cだけ前進する。
逆余弦関数は、math.acos( )
を用いる。
亀を回転させる際には、角度は(ラジアンではなくて)度で指定する必要がある点にも注意
(ラジアン値*180.0/math.pi
のように計算すればよい。ここで、math.pi
には円周率3.141592...があらかじめセットされている)。
「亀場」のタートルグラフィックスのコーナーも参照のこと。 Pythonプログラムと同じ場所にファイルturtle3.pyをダウンロードしておくことを忘れずに。 (Python 2の場合はturtle.py)
ひな形として、長さa,b,cの辺を120度ずつ左回りしながら描くプログラム例を示す。 このプログラムでは、辺の長さが等しい場合のみ三角形が構成される。
# coding: utf-8 from turtle3 import Turtle t = Turtle("localhost") t.clr() t.rst() a,b,c=map(float,input("a,b,c:").split()) print("a,b,c=",a,b,c) t.pd() t.fd(a) t.lt(120.0) t.fd(b) t.lt(120.0) t.fd(c)