第5回 条件分岐#
この授業で学ぶこと#
第4回までで、プログラミングの材料と道具にあたるデータと関数・メソッドについて学んだ。ここまでの知識で、与えられたデータに対して毎回同じ処理を行うプログラムを作成することができる。
しかし、より実用的なプログラムを作るには、データに合わせて処理を変えることが必要不可欠である。そのためにプログラミングではデータに対する条件式をたて、それが成立するかしないかをもとに処理を二分させる方法をとる。
この授業では、まず条件式の成立・不成立を表すデータ型であるブール型について学ぶ。そしてブール値をもとに処理を分岐させる構文であるif文について学ぶ。
ブール型#
ブール型(bool)は True もしくは False の2種類の真偽値(ブール値)をとり、それぞれ真か偽かを表す。
type(True)
ブール型は、主に条件式の成立・不成立を表すのに使われる。 例えば、次の比較演算子を使うことで数値の大小関係を判定する条件式を作ることができるが、その結果はブール型で表される。
比較演算子 |
意味 |
|---|---|
|
(左の値は右の値より)大きい |
|
以上 |
|
未満 |
|
以下 |
|
等しい |
|
等しくない |
2つの値が等しいかどうかは = ではなく == という記法を使うことに注意する。
実際にいくつかの例を見てみよう。
10 > 1
10 == 1
10 != 1
3 == 3.0
0.1 * 3 == 0.3
最後の結果は、浮動小数点数のもつ誤差によるものである(0.1 * 3 が 0.3 と等しいかどうか、誤差も加味して比較を行うにはどうしたら良いだろうか?)
もちろんブール型のデータも、変数に代入することができる。
a = (10 == 1)
a
ブール型の現れる他の例として、in演算子がある。これはリストや文字列の中に特定の要素が存在するかを調べる演算子である。
例えば、B をリストとして A in B と書くとき、データ A が B に含まれるかどうかを判定して、真偽値を返す。
使用例を以下に示す。
2 in [1, 3, 5, 7, 9]
4 in [2, 4, 6, 8]
if文#
データに合わせて処理を変えるための構文がif文である。 そのためにプログラミングではデータに対する条件式をたて、それが真か偽かをもとに処理を二分させる。
最初にブロックが1つだけの最も基本的な場合の書き方を説明する。
Fig. 8 if文の書き方#
if文はヘッダーとブロックの2つから成る。ヘッダーに if 条件式: と書くと「条件式が真のとき以下のブロックを実行する」という意味になる。ifと条件式の間には空白文字を1つ以上入れることと、最後にコロン : を入力することに注意する。
ヘッダーに続くブロックは、インデントという空白文字による字下げをすることで表現する。空白文字の数はいくつでもよいが、ブロック中はインデントの大きさを揃える必要がある。この授業ではTab文字(Tabキーを1回押す)で入力することを推奨する[1]。Google Colabなどのエディターでは、コロン : のあと改行すると自動でインデントが入力されるので、それを利用すればよい。
例えば、数値 x が正のときのみ "正の値" と出力するプログラムは以下のように書ける。
x = 3
if x > 0:
print("正の値")
練習1
数値 x が与えられるとき、x が負のときのみ "負の値" と print するコードを作成しなさい。
# xの一例
x = -1
# 以下にコードを作成し、以下の部分のみ提出する
if x < 0:
print("負の値")
練習2
整数 x が与えられるとき、x が0のときのみ "zero" と print するコードを作成しなさい。
# xの一例
x = -1
# 以下にコードを作成し、以下の部分のみ提出する
if x == 0:
print("zero")
練習3
整数 x が与えられるとき、x が偶数のときのみ "偶数" と print するコードを作成しなさい。
ヒント: 2で割った余りが0かどうかで判定できる。
# xの一例
x = 2
# 以下にコードを作成し、以下の部分のみ提出する
if x % 2 == 0:
print("偶数")
elif節・else節#
条件式が真のときに特定の処理を行う方法を解説したが、条件式が真でないとき(すなわち偽のとき)にも特定の処理を行わせたい場合がある。また処理の分岐を3つ以上に増やしたい場合もある。このようなときにelif節やelse節を使う。
Fig. 9 if文の書き方#
elif 条件式: と書くと処理の分岐を増やすことができ、「もしここまでのブロックを実行しておらず、条件式が真ならば」という意味になる。else: は「もしここまでのブロックを実行していないならば」という意味になる。elif 条件式:、else: の行もヘッダーと呼ばれ、最初のif文のヘッダーと左端をそろえる必要がある。
elif節とelse節は必要に応じて追加し、必ずif、elif、elseの順番にする。 elif節は好きなだけ追加できるが、else節は1つまでである。 この授業ではif文という言葉を、if、elif、else を含む条件分岐の総称として用いることにする。
上図のelif節とelse節が1つずつの場合の条件分岐の流れをフローチャートで表現すると次のようになる。
Fig. 10 条件分岐の流れ#
例として、BMI指数を計算して、その値に応じてメッセージを出力するプログラムを作成してみよう。BMIとは、身長と体重の関係から算出される肥満度を表す指数である。 身長を \(a\) cm、体重を \(b\) kgとすると、BMIは \(10000 b / a^2\) と定義される。
a = 193 # 大谷選手の身長、体重
b = 95
bmi = 10000 * b / a ** 2
bmi
BMIは18.5未満のとき「低体重」、18.5以上25未満のとき「普通体重」、25以上のとき「肥満」とされる。BMIの値に応じて、これらの情報を出力したい。これは以下のif文により実現できる。
if bmi < 18.5:
print("低体重")
elif bmi < 25:
print("普通体重")
else:
print("肥満")
BMIが18.5未満のとき最初の bmi < 18.5 が真となるため、if文以下の print("低体重") が実行される。
BMIが18.5以上25未満のとき次の bmi < 25 で初めて真となるため、elif文以下の print("普通") が実行される。
BMIが25以上のとき bmi < 18.5 と bmi < 25 のどちらも偽となるため、else文以下の print("肥満") が実行される。
練習4
数値 x が与えられる。x が正の値のとき "正の値" 、そうでないとき "0以下の値" と print するコードを作成しなさい。
# xの一例
x = 0
# 以下にコードを作成し、以下の部分のみ提出する
if x > 0:
print("正の値")
else:
print("0以下の値")
練習5
正の整数 x が与えられる。x が1桁の整数(つまり1〜9)のとき "1桁"、2桁の整数(つまり10〜99)のとき "2桁"、3桁以上の整数(つまり100〜)のとき "3桁以上" と print するコードを作成しなさい。
# xの一例
x = 10
# 以下にコードを作成し、以下の部分のみ提出する
if x < 10:
print("1桁")
elif x < 100:
print("2桁")
else:
print("3桁以上")
式と文
Pythonプログラムは主に式と文の二つの要素から構成される。
式とは、値を生み出す要素である。例えば
1 + 2のような計算やprint("hello")のような関数の呼び出しがこれに当たる。文とは、プログラムの動きを制御する要素である。例えば、変数への代入
x = 5や、条件分岐や繰り返しを行う「if文」や「for文」などがこれに当たる。
論理演算子#
複数の条件をもとに条件分岐を行いたい場合がある。
そんなときに用いられるのが論理演算子である。
論理演算子には and、or、not の3種類がある。
それぞれの意味は名前のとおりではあるが、一通り解説する。
and は、両方の条件が満たされる場合に真を返す。
2つの条件式 A、B があったとして、それぞれの真偽と A and B の真偽の関係は次のようになる。
A |
B |
A and B |
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
or は、少なくとも一つの条件が満たされる場合に真を返す。2つの条件式 A、B があったとして、それぞれの真偽と A or B の真偽の関係は次のようになる。
A |
B |
A or B |
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
not は、真偽を反転する。条件式 A があったとして、その真偽と not A の真偽の関係は次のようになる。
A |
not A |
|---|---|
|
|
|
|
論理演算子により条件式を組み合わせていくと、算術演算子のときと同じようにどの順で実行するかが問題になる場合がある。 例として、雨が降っているかどうか、傘を持っているかどうかの組み合わせに対して、雨に濡れるかどうかを判定するプログラムを次に示す。
is_rainy = True
has_umbrella = True
if not is_rainy or has_umbrella:
print("雨に濡れません")
else:
print("雨に濡れます")
条件式の not is_rainy or has_umbrella は (not is_rainy) or has_umbrella と not (is_rainy or has_umbrella) のどちらの意味だろうか。上の実行結果をもとに考えてみよう。このように論理演算子の実行順序がわかりにくい場合には、() をつけてわかりやすい記述を心がけた方がよい。
練習6
天気を表す文字列 weather と気温を表す整数 temp が与えられるとき、以下の条件にもとづいて適切なメッセージを print するコードを作成しなさい。
weatherが"晴れ"かつtempが25以上なら"暑い日ですね"weatherが"晴れ"かつtempが25未満なら"快適な日ですね"weatherが"雨"なら"傘を持っていきましょう"
ヒント: weather が "晴れ" かどうかを判定する条件式は weather == "晴れ" と書ける。
# weather, tempの一例
weather = "晴れ"
temp = 17
# 以下にコードを作成し、以下の部分のみ提出する
if weather == "晴れ" and temp >= 25:
print("暑い日ですね")
elif weather == "晴れ" and temp < 25:
print("快適な日ですね")
elif weather == "雨":
print("傘を持っていきましょう")