Python♪基本:if文を使って「もしも~だったら」

いよいよ、中学生のゆうちゃんとの勉強会もif文に突入しました。if文は状況によって命令の内容を変化させる命令文です。例えば、2つのデータを比較して、どちらが大きいかによって、その後の命令を変化させます。命令文の形はシンプルなので、「習うより慣れよ」です。例文をいくつか読めば、使い方がわかってくると思います。

ゆうちゃんとのPython勉強会は継続していますが、中間や期末テストがあったりして、あっというまに時間が過ぎていきます。友達と遊ぶのにも忙しいようだし、覚えるのも早いけれど、忘れるのも早いのが中学生です。一進一退ではありますが、継続することが1番です。早く、プログラミングが面白いと思えるところまで、引き上げてあげたいと思います。やっぱり、if文、for文、配列までは進まないと、面白いことを見つけるのが大変ですね~。

0.ゆうちゃんとPythonシリーズ

この記事は「ゆうちゃんとPythonシリーズ」の記事です。一連の記事は、以下のリンク集を参照してください。

中学生のゆうちゃんとPythonシリーズ

なお、それぞれの記事は、シリーズの中でそれまでに習った文法を使ってサンプルコードを考えています。実際には、もっと、効率のよい書き方があるかもしれませんが、ご了承ください。

1.if文の概要

コード01は、3行目で2をxで割っていますが、x = 0なので、2 ÷ 0は計算できず、オーバーフローを起こしてエラーになります。このように、数行のプログラムならエラーになるのはすぐにわかりますが、複雑なプログラムでは、想定外のことで分母がゼロになり、システムがシャットダウンすることも考えられます。

#コード01
x = 0
print('2 / x =', 2 / x)

そんな場合には、コード02のようなif文を入れるのも解決法の1つです。このプログラムでは、3行目のif文により、もし(if)、xがゼロ(x == 0)ならば、4~5行目の命令を実行します。ここで、if文の影響範囲である4~5行目は、文の始まりが他の行よりも下がっていることに注意してください。xがゼロの時だけ実行されるのは4~5行目であり、6行目はif文の影響範囲ではありません。つまり、6行目はxの値がゼロであっても、なくても実行されます。なお、文の始まりを他の行よりもさげることを字下げ(インデント)と言います。

つまり、コード02は、xがゼロのとき、そのことを4行目のprint文で出力し、プログラム利用者に想定外のことが生じたことを知らせます。そのうえで、5行目でゼロを0.000001に置き換えることで、ゼロで割ることを防ぎ、計算を続行することができます。

#コード02
x = 0
if x == 0:
    print('x = 0なので、x=0.000001にしました。')
    x = 0.000001
print('2 / x =', 2 / x)
#出力01
x = 0なので、x=0.000001にしました。
2 / x = 2000000.0

if文は、以下のような書式になっており、「条件式」が正しいときにだけ、その後のコードを実行します。そして、「条件式が正しいときに実行する命令文」の範囲は、行の始めに半角スペースを挿入し、字下げ(インデント)します。

if 条件式:
    条件式が正しいときに実行する命令文(複数行でも可)

if文を記述するときの注意点は以下のとおりです。

(a) 条件式のあとにコロン(:)をつける。
(b) 条件文が正しい時に実行する範囲は字下げ(インデント)しますが、字下げ幅(インデント幅)がバラバラではダメです。インデント幅をそろえなければなりません。ただし、後述しますが、コード04のように、if文の中にif文があるといった場合には、インデント幅が更に下がる部分があっても問題ありません。
(c) インデントには半角スペースとタブを使うことができますが、全角スペースを使うことはできません。
(d) インデントには半角スペースを4つ使うことが推奨されており、タブの使用は推奨されていません。

2.比較演算子

コード02の4行目では、「if x == 0:」となっています。「x == 0」の部分が条件式ですが、「x = 0」ではなく、「x == 0」となっています。これは、間違えて2回イコールを記述したのではありません。この「==」は、左辺の「x」と右辺の「0」を比較する演算子なので、「比較演算子」と言います。

ゆうちゃんも、ついつい、「if x = 0:」としてしまい、苦労しています。エラーに格闘しているときに「いつものやつ、いつものやつ」と言うと気が付き、「わかってたもんね~」と負け惜しみを言いながら修正します。文末の「:」と「==」は、慣れるまで大変です。

(1) trueとfalse

#コード03の2行目の「x = 0」は、右側の0を左側のxに代入する「代入演算子」ですが、3~4行目の「==」は比較演算子です。比較演算子で比較されている式は、正しいときには「True」(トゥルー)、誤りの場合は「False」(フォールス)を返します。したがって、コード03の出力は出力03になります。「x == 0」という「式」をprint()で出力すると、Trueという「値」が出力されるのがおもしろいですね。

#コード03
x = 0
print(x == 0)
print(x == 1)
#出力03
True
False

つまり、if文は「条件式がtrueの場合には、if文直後のインデントされた範囲を実行し、falseならば、実行しない」という命令文なのです。

(2) 比較演算子の種類

2つの値の比較を行い、真偽値(True, False)を返す演算子を比較演算子といいます。比較演算子は、下表の他にもいくつかありますが、まずは以下の6種類で十分です。

a == baとbが等しい
a != baとbが異なる
a < baがbよりも小さい
a > baがbよりも大きい
a <= baがb以下である
a >= baがb以上である

比較演算子を使う場合の注意点は以下のとおりです。

(a) 「==」は「=」と間違えないようにしましょう。
(b) 「!=」「<=」「>=」が正解です。「=!」「=<」「=>」のように「=」を左にするとエラーになります。※Python♪の神様式暗記法として、「=」を箸(はし)にみたて、「箸は右手で持つ」と覚えましょう。
(c) 数学の知識ですが、上表の「bよりも小さい」「bよりも大きい」はbが入りません。一方、「b以下」「b以上」はbが入ります。

3.論理演算子

「xが3よりも大きい」という条件式は、「3 < x」とすればよいですが、「xが3よりも大きく、かつ、6以下」という条件式はどの様にすればよいのでしょうか。

(1) if文の中にif文を記述する方法

2つ以上の条件を組み合わせる方法として、if文の中にif文を記述する方法があります。まず、具体例を見た方が分かりやすいと思いますのでコード04を見てください。コード04は、3行目のif文において「1 < x」の場合に4行目を実行します。更に4行目のif文により、「x < 4」のときに5行目を実行します。つまり、「1 < x」かつ「x < 4」の場合に5行目を実行することができます。

なお、3行目のif文の影響範囲は、3行目よりもインデント幅が大きい4~5行目です。また、4行目のif文の影響範囲は、4行目よりもインデント幅が大きい5行目です。

このように、if文の中にif文があるようなコードは、内側のif文「if x < 4:」の影響範囲も示す必要がありますので、その部分はさらにインデント幅を大きくする必要があり、4行目と5行目はインデント幅がそろいません。

#コード04
x = 3
if 1 < x:
    if x < 4:
        print('1 < x < 4')
#出力04
1 < x < 4

(2) 論理演算子を用いる方法

2つ以上の条件を組み合わせるもう1つの方法として、論理演算子を用いる方法があります。コード05では、2つの条件式「3 < x 」と「x <= 6」を「and」でつなげ、「3 < x and x <= 6」と記述しています。「and」は日本語では「かつ」です。つまり、「3< x and x <= 6」は、日本語なら「3< x かつ x <= 6」となります。

なお、比較演算子「<」「>」は、論理演算子「and」よりも優先順位が高く、先に計算されるため、「(3 < x) and (x <= 6)」のようにカッコをつける必要はありません。

#コード05
x=3
if 1 < x and x < 4:
    print('1 < x < 4')
#出力05
1 < x < 4

更に条件式を増やし、「1 < x かつ x < 4 かつ x != 2」とする場合には、コード05やコード06のようになります。

#コード06
x = 3
if 1 < x:
    if x < 4:
        if x != 2: 
            print('1 < x < 4, x != 2')
#コード07
x = 3
if 1 < x and x < 4 and x != 2:
    print('1 < x < 4, x != 2')

(a) and, or, notのベン図

さて、覚える必要がある論理演算子はnot, and, orの3つです。ベン図にすると以下のようになります。

「条件A and 条件B」は論理積と呼ばれ、下図の左側のように、条件A、条件Bの両方の条件を満たす黄色の部分がTrueとなります。同様に「条件A or 条件B」は「条件A または 条件B」の意味であり、条件Aと条件Bのどちらか一方でも満たせばTrueになります。「not 条件A」は「条件Aではない」ときにTrueとなります。ベン図は高1で習う内容ですが、イメージしやすい(?)ので、先取りしちゃいましょう。

(b) 論理積 and

「A and B and C」→ 「A かつ B かつ C」
A, B, Cがすべて正しい(True)の場合はTrue。1つでも誤りがあるとFalse。
AやBやCは、条件式ですので、実際に使うときには「x != 2 and 0 < x and x < 4」のような使い方をします。そして、x=3のとき「0 < x and x < 4 and x != 2」はTrueになります。

(c) 論理和 or

「A or B or C → A または B または C」
A, B, Cの内、1つでも正解(True)がある場合はTrue。全て誤りの場合はFalse。

(d) 否定 not

「not A」→「AがTrue」なら「AがTrueではない」つまり「False」になります。また、「AがFalse」なら、 「AがFalseではない」つまり、「True」になります。
notは、TrueとFalseを逆にします。例えば、「x = 1」のときに 「not  x == 1」は「Trueの反対」で「 False 」になります。

(3) 論理演算子の優先順位

2つ以上の論理演算子を使う場合の優先順位はnot→and→orとなります。
※Python♪の神様式暗記法として、頭文字をとって「Naoちゃん」と覚えましょう。

つまり、例えば「A or B and C」や「not A and B」のような場合に、どのような順番で計算するのか注意する必要があります。正しい計算順序と、誤った計算順序を以下に示します。

A or B and C →正しい順序: A or (B and C)、 誤った順序: (A or B) and C
not A and B  →正しい順序: (not A) and B、  誤った順序: not (A and B)

論理演算を行う場合は、文法的にはつける必要がなくても、カッコをつけた方が分かりやすいことが多いと思います。状況に応じて、読みやすいコードの記述に心がけましょう。

4.まとめ

「if else」については、次の記事で説明したいと思いますので、ここまでの内容をまとめたいと思います。

(1) if文の書式

if文の書式は以下の通りです。条件式がTrueの場合に、if文の後の字下げされた部分を実行します。条件式がFalseの場合には、if文の後の字下げされた部分は実行されません。

if 条件式:
    条件式が正しいときに実行する命令文(複数行でも可

(a) 条件式のあとにコロン(:)をつける。
(b) 条件文が正しい時に実行する範囲は字下げ(インデント)しますが、字下げ幅(インデント幅)がバラバラではダメです。インデント幅をそろえなければなりません。 ただし、コード04のように、if文の中にif文があるといった場合には、インデント幅が更に下がる部分があっても問題ありません。
(c) インデントには半角スペースとタブを使うことができますが、全角スペースを使うことはできません。
(d) インデントには半角スペースを4つ使うことが推奨されており、タブの使用は推奨されていません。

(2) 比較演算子

2つの値の比較を行い、真偽値(True, False)を返す演算子を比較演算子といいます。比較演算子は、下表の他にもいくつかありますが、まずは以下の6種類で十分です。

a == baとbが等しい
a != baとbが異なる
a < baがbよりも小さい
a > baがbよりも大きい
a <= baがb以下である
a >= baがb以上である

(a) 「==」は「=」と間違えないようにしましょう。
(b) 「!=」「<=」「>=」が正解です。「=!」「=<」「=>」のように「=」を左にするとエラーになります。※Python♪の神様式暗記法として、「=」を箸(はし)にみたて、「箸は右手で持つ」と覚えましょう。
(c) 上の表の「bよりも小さい」「bよりも大きい」はbが入りません。一方、「b以下」「b以上」はbが入ります。

(3) 論理演算子

複数の条件式を組み合わせて、より複雑な条件式を記述するには論理演算子を使います。覚える論理演算子はnot, and, orの3つです。ベン図にすると以下のようになります。

2つ以上の論理演算子を使う場合の優先順位はnot→and→orとなります。※Python♪の神様式暗記法として、頭文字をとって「Naoちゃん」と覚えましょう。
また、比較演算子は論理演算子よりも計算の優先順位が高くなります。

5.例題

以下のようなプログラムを組んでみましょう。

(1) 例題1 点数の評価

ランダムに0~100の整数を発生させ、その点数を出力する。次に、その点数が50点よりも小さい場合にだけ、点数が0点以上、50点未満であることを示し、悪い点であったことを出力する。出力の書式は、出力例1、出力例2を参照すること。

出力例1(点数が17点だった場合)

点数: 17
0 ≦ 点数 < 50
悪い点でした。

出力例2(点数が50点だった場合)

点数: 50
解答を表示する

3行目のrandint(0, 100)は、0~100までの整数の乱数を発生させる関数です。4行目は点数にかかわらず、出力されますが、6~7行目は、点数が50より低いときにだけ出力されます。

#コード08
import random
ten = random.randint(0, 100)
print('点数:', ten)
if ten < 50:
    print('0 ≦ 点数 < 50')
    print('悪い点でした。')

(2) 例題2 モンスターガチャ

例題1が、あまりにもつまらないので、例題2では、モンスターガチャのプログラムを作ってみましょう。このプログラムに過度の期待をしてはいけませんが、「ゆうちゃん」いわく、「超クソゲーなのに、なぜか楽しいプログラム」だそうです。

さて、モンスターの能力値として「体力」「攻撃力」「スピード」があり、それぞれ、0~100の整数で表されるゲームがあるとします。

プログラムでは、それぞれの能力値をランダムに決め、まず、その能力を出力します。そして、次に3つの能力値の合計が50以下の場合は、「ちょっと、弱すぎますね・・・」と出力し、250以上の場合は、「超レア!リセマラ完了」と出力します。「超レア」がでるまで、ひたすらプログラムの実行を繰り返すというゲーム(?)です。

あなたのモンスターの能力です
体力: 68
攻撃力: 17
スピード: 39
あなたのモンスターの能力です
体力: 6
攻撃力: 18
スピード: 5
ちょっと、弱すぎますね・・・
あなたのモンスターの能力です
体力: 97
攻撃力: 57
スピード: 98
超レア!リセマラ完了
解答を表示する

プログラムのコードは以下の通りです。例題1の行数が少しだけ多くなっただけなので、難しくないのではないでしょうか。

#コード09
import random
tairyoku = random.randint(0, 100)
kougeki = random.randint(0, 100)
speed = random.randint(0, 100)

print('あなたのモンスターの能力です')
print('体力:',tairyoku)
print('攻撃力:', kougeki)
print('スピード:', speed)

if tairyoku + kougeki + speed >= 250:
    print('超レア!リセマラ完了')
if tairyoku + kougeki + speed <= 50:
    print('ちょっと、弱すぎますね・・・')

意外に「超レア」が出ないので、ガチャを引いている気分になれます。ひたすらモンスターの能力値を出力するだけのプログラムですが、5分ぐらいは楽しめました。ゆうちゃんも「クソゲー、クソゲー」と連呼しながらも、すごく楽しそうでした。例題1の「テストの点数」を「モンスターの能力値」にするだけで、わくわく感が変わるのが不思議です。

ちなみに、「超レア」が出る確率は、以下の通りです。計算内容の詳細説明は省略します。

能力値のすべてのパターンは、101 × 101 × 101 = 1030301通りであり、能力値の合計が250以上となる組み合わせは、53C3 =(53 × 52 × 51)/(3 × 2 × 1)= 23426通りです。つまり、「超レア」になる確率は、23426 ÷ 1030301 × 100 = 2.2737 %です。(計算あってるかな・・・。不安)

2.3 %なら、なかなか、「超レア」が出ないのも納得できます。

私が実際に購入した教材のご紹介

以下、私が実際に購入したPythonの教材をまとめてみました。 Pythonを学習する上で、少しでもお役に立つことができればうれしいです。

Python♪私が購入したPythonの書籍のレビュー

UdemyのPythonの動画講座を書籍を買う感覚で購入してみた