条件分岐を行う。if~(elif)~else文について説明します。
if~else文
条件分岐が2つの場合です。
例題_2_1(if~else文)
ここで次の様なコードを書いてみましょう。
a に整数を代入します。この整数(**)が偶数の場合は「**は偶数です」と出力し、奇数の場合は「**は奇数です」という出力させます。
偶数か奇数かの判定は、a%2(aを2で割った余り)が0(偶数)か1(奇数)かで判断します。
まず、文章で表現してみます。
a に任意の整数(例えば15)を代入します。
もし、a%2 が 0 に等しいなら、
「15は偶数です」を出力
それ以外は
「15は奇数です」を出力
上の文章をそのままpythonの構文に合わせてコード化して、実行したものが以下となります。
a = 15
if a%2 == 0: #ifの後に条件文を置き、最後にコロン(:)
print(a, 'は偶数です') #条件文がTrueの時の処理内容は4文字分のインデントを入れる
else: #elseはそれ以外の意味で、最後にコロン(:)
print(a, 'は奇数です') #elseの処理内容も4文字分のインデントを入れる
15 は奇数です
a が偶数かどうかは、if の後の条件文 a%2 == 0 がTrueかどうかで判断します。条件文がTrueの場合に、その下の半角空白4個分のインデント(字下げ)のコードを実行します。今回はprint文の一行のみですが同様のインデントをつければ複数行を記載することも可能です。
条件文 a%2 == 0 がFalseの時は else: の下のインデントをつけたコードが実行されます。
#の後のコメント文にも記載しましたが、if~else文の書き方のルールは以下の2点で、これに違反するとSyntaxError(構文エラー)となります。
- if + 条件文の後にはコロン(:)、elseの後にもコロン(:)を入れる。
- それぞれの条件を満たす場合の処理文は半角空白4個分のインデント(字下げ)を入れる
jupyter labではコロン(:)の後でEnter(Windows)、Return(MAC)を打つと自動的にインデントが入る設定になっています。
Tabキー(1回)でも同じく4文字分のインデントが入ります。反対にShift+Tabでインデントが戻ります。
また本来半角空白4個分であるべきインデントが多かったり少なかったりしても最近ではエラーが出ない場合がありますが、見易さの点からも半角4文字空白もしくはTabによるインデントを守りましょう。
if文で起きやすいエラー
SyntaxError: invalid syntax
- 条件文の == が = になっている
- if+条件文の後のコロン(:)がセミコロン(;)になっている、又はコロン(:)が無い。
SyntaxError: invalid character in identifier
- 全角スペースが使われている
- if+条件文の後のコロン(:)が全角コロン(:)になっている
IndentationError: expected an indented block
- 期待されたインデントブロックが無い
IndentationError: unindent does not match any outer indentation level
- インデントの戻しが前のインデントに一致していない
確認
コードを書いてエラーが出なくなったら、必ず確認作業をします。何を確認するべきか自分で考える習慣をつけましょう。この場合では少なくとも以下の2点は確認する必要があります。実際に確認して下さい。
- aに偶数を入力して、「**は偶数です」が出力されること
- aに奇数を入力して、「**は奇数です」が出力されること
練習問題_2_1(if~else文)
weight という変数に体重(kg)を、heightという変数に身長(m)を、それぞれ任意の値を入力します。
体重と身長の値を出力すると共に、(体重)➗(身長の2乗)で計算されるBMIの値を出力し、BMIが24以上の場合「要注意」24未満の場合「肥満ではありません」のメッセージをBMIの値の右側に出力するコードを作成してください。
BMIの値は round関数を使って小数点以下2桁まで表示して下さい。
練習問題_2_2(if~else文+ブール演算)
以下の図は横軸にを参考に拡張期血圧(最低血圧)、縦軸に収縮期血圧(最高血圧)を使用して、「高値血圧」の領域を示したものです。
max_pressureという変数に収縮期血圧(最高血圧)を代入、min_pressureという変数に拡張期血圧(最低血圧)を代入して以下の様な出力をするコードを作成して下さい。
最高血圧: *** 最低血圧: *** 判定: 分類名(高値血圧 又は その他)
境界線上は外側に分類されることにします。(例:最高血圧130、最低血圧80の場合は高値血圧)
練習問題_2_3(if~else文+四角い的)
シューティングゲームのプログラムを作成しています。
矢が下記画面のどこかに当たると仮定します。0.0 <= x <= 120.0, 0.0 <= y <= 80.0
x, y 座標を代入し、中央の色付きの四角内にその点があれば点数(score)は10点、それ以外の白い領域にある場合は0点と出力するプログラムをif文を使って作成してください。
練習問題_2_4(if~else文+丸い的)
同じくシューティングゲームのプログラムを作成しています。
矢が中央の色付きの丸内(半径10)にあれば点数(score)は10点、それ以外の白い領域にある場合は0点と出力するプログラムをif文を使って作成してください。
if~elif~else文
条件分岐が3つの場合です。
例題_2_2(if~elif~else文)
blood_pressureという変数に、測定後の最高血圧を整数で代入します。この値を判定して以下のメッセージを出力します。(***は代入した整数値を表します)
- 130以上の場合:「最高血圧:*** 高血圧症の可能性があります」を出力
- 100以上130未満の場合:「最高血圧:*** 正常の範囲です」を出力
- 100未満の場合:「最高血圧:*** 低血圧症の可能性があります」を出力
これもはじめに構文に沿った文章で考えてみます。
blood_pressure に任意の整数(***)を代入します。
もし、blood_pressure が 130 以上なら、
「最高血圧:*** 高血圧症の可能性があります」を出力
それ以外でもし、blood_pressure が 100 以上かつ 130 未満なら、
「最高血圧:*** 正常の範囲内です」を出力
それ以外(blood_pressure が 100 未満)は
「最高血圧:*** 低血圧の可能性があります」を出力
上記真ん中の「それ以外でもし」のところで、else + if を表す elif を使用します。
使い方は if と同じく elif + 条件文 + コロン(:)でその下にインデントをつけた処理文を記載します。 この条件文は blood_pressure が100以上かつ130未満ですので、(blood_pressure >= 100) and (blood_pressure < 130)を使用します。
blood_pressure = 120
if blood_pressure >= 130:
message = '高血圧症の可能性があります'
elif (blood_pressure >= 100) and (blood_pressure < 130):
message = '正常の範囲内です'
else: # blood_pressure < 100
message = '低血圧の可能性があります'
print('最高血圧:', blood_pressure, message)
最高血圧: 120 正常の範囲内です
今回はif, elif, else それぞれの処理ブロックには message という文字型変数の代入文を入れ、最後にprint文を入れて message を出力するようにしました。理由はコードの見やすさのためです。
ただし、重要な点は最後のprint文はインデントを ifや elif, elseと同じ位置まで戻さなければいけません。print文にインデントの位置を直前のmessage代入文の行と同じ位置に記載すると、elseの処理ブロックに属することになり、‘低血圧症の可能性があります’の時以外print出力されない状態となりますので、気をつけなければなりません。この様な間違いはエラーコードが出ない、いわゆる隠れエラーとなります。一般的にこの隠れエラーこそが厄介者で、見逃さないためには確認を色々な場合に分けて丹念に実施する必要があります。
else: の後にコメントでelseで想定している条件を記載しています。これは必ず必要というものではありませんが、後からコードを見たときに理解し易くするためです。
確認
blood_pressureの値を色々と変えてみて、それぞれのメッセージが出力されるかどうかを確認して下さい。今回は特に境界値である130や100についてもそれぞれ130→‘高血圧症の可能性があります’、100→‘正常の範囲内です’となるかどうかも確認して下さい。
if文に含まれるブール演算機能
if文は上から順番に条件文の判定を行うために、自動的に以下の様にブール演算機能が働きます。
# if ~ else の場合
if X:
X の処理
else:
not X の処理
上記 if ~ else の場合は分かり易いのですが、elif が入ると少し複雑になります。
# if ~ elif ~ elif ~ else の場合
if X:
X の処理
elif Y:
Y and not X の処理
elif Z:
Z and not X and not Y の処理
else:
not X and not Y and not Z = not (X or Y or Z)の処理
この機能を使えば上記例題_2_2は少しだけ簡単になります。
blood_pressure = 120
if blood_pressure >= 130:
message = '高血圧症の可能性があります'
elif blood_pressure >= 100:
message = '正常の範囲内です'
else: # blood_pressure < 100
message = '低血圧の可能性があります'
print('最高血圧:', blood_pressure, message)
ただしこの場合、if の条件と elif の条件の順番を変更できないことに注意する必要があります。
後々のデバッグのために、順番変更の自由度を確保しておきたい場合は上記の最初に紹介したコードを用いる必要があります。
練習問題_2_5(if~elif~else文+ブール演算)
下図は協会けんぽのサイトに掲載されている血圧の分類MAPです
max_pressureに収縮期血圧(最高血圧)を代入、min_pressureに拡張期血圧(最低血圧)を代入して練習問題_2_2と同様に分類名を出力をするコードを作成して下さい。今度は分類名は6種類となります。
最高血圧: *** 最低血圧: *** 判定: 分類名(正常血圧、正常高値血圧など)
練習問題_2_6(if~elif~else文+ブール演算 四角い的)
シューティングゲームのプログラムを作成しています。
矢が当たった色の領域によって以下の点数を出力するプログラムをif文を使って作成してください.
- 紺色の内にあれば点数(score)は30点
- 青色の内にあれば点数(score)は20点
- 水色の内にあれば点数(score)は10点
- 白色は0点
境界線は点数の高い方の点を与えます。それぞれの正方形の中心は x, y = 60, 40になります。
練習問題_2_7(if~elif~else文+ブール演算 丸い的)
以下のシューティングゲームのプログラムを作成しています。
図のように的はそれぞれ中心が(60, 30), (45, 50), (75, 50)で半径が3つとも同じ r = 20 の3つの円から構成されています。
点数は赤字で示した様に、矢が3つの円内にあるときは50点、2つの円内にあるときは30点、1つの円内のときは10点、どの円内にも入っていないときは0点とします。
if文を使って点数を出力するプログラムを作成してください。
ネストしたif文
ifの処理文の中にさらにif文を入れ子にすることができます。これをネストしたif文と言います。
例題_2_3(ネストしたif文)
例題_2_1 の応用で、 %2 を使った偶数/奇数の判定の前に組み込み関数isinstance(オブジェクト, 型)を使って a が int であることを確認してみましょう。
a が int でない場合は、「整数を入力してください」というメッセージを出力させます。
この時のコードは以下の通りです。
# a が int であることを判定するコード
a = 'abc'
if isinstance(a, int):
pass # pass は何もしないという文です
else:
print('整数を入力してください')
上記 pass の箇所に埋め込む例題_2_1 のコードは以下の通りです。
# 例題_2_1 のコード
a = 12
if a % 2 == 0:
print(a, 'は偶数です')
else:
print(a, 'は奇数です')
実際に使用する箇所は if ~ else の後半の4行です。それを上記 pass のところに埋め込むとき注意すべき点は入れ子になった if文全体をインデントすることです。
# int判定のコードのPassのところに偶数/奇数判定のコードを入れ込みます。
a = 10.0
if isinstance(a, int):
if a % 2 == 0: # インデント1回分(空白4個分)
print(a, 'は偶数です') # インデント2回分(空白8個分)
else: # インデント1回分(空白4個分)
print(a, 'は奇数です') # インデント2回分(空白8個分)
else:
print('整数を入力してください')
整数を入力してください
int 以外を入力した場合「整数を入力してください」というメッセージが出力されることを確認してください。また整数を入力した場合は偶数/奇数の判定を行うことを確認してください。
練習問題_2_8(ネストしたif文)
以下の様に西暦(seireki)を入力すると元号が出力されるコードを作成してください。
- 西暦(seireki)は 1926 以上 2024 以下の整数であることを判定し、それ以外の時は「 1926 以上 2024 以下の整数を入力してください」と表示
- 1926 -> 大正 15 年/昭和元年
- 1927 ~ 1988 -> 昭和 2 年 ~ 昭和 63 年
- 1989 -> 昭和 64 年/平成元年
- 1990 ~ 2018 -> 平成 2 年 ~ 平成 30 年
- 2019 -> 平成 31 年/令和元年
- 2020 ~ 2024 -> 令和 2 年 ~ 令和 6 年
if ~ else文でbool演算子を作成
ここでは、if ~ else文を使ってbool演算子の and, or, not を作成してみましょう。
例題_2_4(if~else文で not を作る)
はじめに一番簡単な not です。
以下の内容で if ~ else文を作成してみます。
- a には bool, int, float, strの何れかが代入される
- a がTrueの時 not_a にFalse、aがFalseの時は not_a にTrueを代入する
a = ''
if a:
not_a = False
else:
not_a = True
not_a
True
上記では a に strの ” (==False) を代入しています。a が Trueの場合は not_a に Falseを代入し、そうでない場合は not_a に Trueを代入しています。反対に a = ‘abc’ (==True) を代入すると、not_a は False となります。代入する値をいろいろ変えてみて確認してください。
練習問題_2_9(if~else文で and と or を作る)
それでは練習問題として and と or を作成してください。
以下の条件で if ~ else文を使用してください。但し結果の変数である and_ab と or_ab には、a もしくは b のどちらかを代入してください。
and の作成
- a と b には bool, int, float, strの何れかが代入される
- if ~ else 文を1回だけ使用
- and を表す and_ab には a または b のどちらかを代入する
- bool(and_ab) は bool(a) and bool(b) と等しい
or の作成
- a と b には bool, int, float, strの何れかが代入される
- if ~ else 文を1回だけ使用
- or を表す or_ab には a または b のどちらかを代入する
- bool(or_ab) が bool(a) or bool(b) と等しい
ちなみに前章で触れた通り、bool以外の int, float, strではそれぞれ 0, 0.0, ” がFalseで、それ以外はTrueです。
bool演算の補足
実際にbool演算は上記の様な形で評価されるため、a and b and c の様に and の計算が連続する場合、最初に False が出た時点でその後の評価はしません。
0 and [] and '', 1 and [] and '', 1 and 2 and ''
(0, [], ”)
一方、a or b or c の様に or の計算が連続する場合は、最初に True が出た時点でその後の評価はしません。
1 or 2 or 3, 0 or 2 or 3, 0 or [] or 3
(1, 2, 3)