if文は「もしも~だったら」という条件分岐を指定する命令文です。単純なif文については勉強しましたが、ここでは、「if…else」「if…elif…else」の使い方も覚えましょう。これだけ覚えれば、これらを組み合わせて、どんな条件分岐のプログラムにも対応することが可能です。
0.ゆうちゃんとPythonシリーズ
この記事は「ゆうちゃんとPythonシリーズ」の記事です。一連の記事は、以下のリンク集を参照してください。
なお、それぞれの記事は、シリーズの中でそれまでに習った文法を使ってサンプルコードを考えています。実際には、もっと、効率のよい書き方があるかもしれませんが、ご了承ください。
1.勉強を始める前に
実は、中1のゆうちゃんとのPython勉強シリーズが前の記事から半年もたってしまいました。勉強会は継続してやっているので、記事ネタを書き留めたノートは内容が増えているのですが、ホームページ作成が追いついていません。ゆうちゃんから「僕の記事、楽しみにしてるんだけど。最近、更新しないね。」と言われます。「いそがしそうだから無理しないでね。」とも言ってくれます。あんなに喜んでくれていたのに、ごめんね~。
ということで、ネタ帳を元に、少しずつでも記事を進めていきたいと思います。早いもので、ゆうちゃんも、もう、中2になりました。記事の中では中1ですが、再開したいと思います。
さて、今回は「if...else」「if...elif...else」の使いかたがテーマです。そして、なにか遊べるプログラムを作りたい。そこで、ゆうちゃんに「if文を覚えたから、おみくじプログラムとか、じゃんけんゲームとかは作れるけど作ってみる?」と聞いてみましたが、さすがに反応が薄い。悩んだ末に、「ゆうちゃん、次までにどんなプログラム作りたいか考えといて」と、ゆうちゃんに無茶ぶりしてしまいました。
ということで、本日、勉強会なのですが「考えてきたよ~」と教えてくれた案が、「夕食決定プログラム」
→ 私:「???」目が点
実は、 ゆうちゃんママから、ゆうちゃんに 「今日の晩御飯なにがいい~」と、聞かれることがあるらしく、その時にズバッと、プログラムで解決してあげたいらしい。お~、なんてかわいいboyなの。それ、いいじゃない。私では絶対に思いつかないプログラムだわ。(プログラムのネーミングがいまいちだけど・・・)
2.「if...」シンプルなif文
前回までに習った単純なif文を使って、コードを記述してみます。わかりにくい場合は、以下の記事を確認してください。
(1)夕食決定プログラムの最初の一歩
作成途中のプログラムを見せてもらうと以下のとおり。なるほど、おもしろいプログラムね。出力01aのような結果が出てきたら、うれしくて泣けるかも。でも、今のままでは、出力01bのような出力になる場合もあるから、あと、もう少しだね。
#コード01
import random
ten = random.randint(0, 100)
print('今日の気分は', ten, '点です')
if ten <= 10:
#条件式 ten <= 10 を満たす場合に実行
print('今日は疲れてるね。')
print('外食にしようよ。')
#出力01a
今日の気分は 4 点です
今日は疲れてるね。
外食にしようよ。
#出力01b
今日の気分は 85 点です
まずは、コード01について、簡単にその構成を見てみましょう。コード01では2行目でランダムな整数を0以上100以下の範囲で生成し、変数tenに代入します。一方、5行目のif文の条件式は「ten <= 10」となっているので、変数tenが10以下の場合にだけ、下図の赤で囲んだ部分を実行します。
if文の条件を満たす場合(条件式ten <= 10がtrueの場合)に実行する範囲は、インデントすることによって示します。 「インデント」とは、行の最初にに空白を挿入して、文字開始位置を標準の位置よりも下げることであり、「字下げ」ともいいます。
コード01では、5行目のten <= 10を満たすときに、6~8行目を実行します。6~8行目は他の行よりも下がっているだけではなく、インデント幅をそろえます。
なお、コードを記述するときの注意点は以下の通りです。
・6~8行目のインデント幅はそろえる必要があります。
・インデントには半角スペースかタブが使えますが、全角スペースは使えません。
・インデントには半角スペースを4つ使うことを推奨されています。
・インデントにタブの使用は推奨されていません。
・ 5行目の最後のコロン(:)を忘れないようにしましょう。
(2) 出力のパターンを2つに増やしてみよう
コード02は、今日の気分の点数(ten)が10よりも大きいときは、「カレーが食べたい」と出力されます。今まで勉強した内容でコードを記述するとこのようになりますが、普通は、コード02のような書き方はせず、この後に説明する「if...else」という書き方をします。
#コード02
import random
ten = random.randint(0, 100)
print('今日の気分は', ten, '点です')
if ten <= 10:
print('今日は疲れてるね。')
print('外食にしようよ。')
if 10 < ten:
print('外食もいいけれど・・・')
print('やっぱり、お母さんのカレーが食べたい!')
#出力02
今日の気分は 64 点です
外食もいいけれど・・・
やっぱり、お母さんのカレーが食べたい!
3.「if...else」 を使った条件分岐
今までのif文は、「条件式を満たす場合」だけ実行するコードでしたが、「if...else」(イフ...エルス)を用いると、「条件式を満たす場合」と「条件式を満たさない場合」のそれぞれについて実行する内容を記述することができます。
(1) 「if...else」を使ってみよう
実際のコードを見た方が分かりやすいと思います。コード02を「if...else」を使って書き換えるとコード03のようになります。コード02は「ten <= 10」「10 < ten」の部分で条件判定を2回行っていますが、コード03は条件判定の回数が「ten <= 10」の1回だけでよいので、計算の無駄がありません。「if...else」を使うことができる場合は、できるだけ「if...else」を使いましょう。
ちなみにelse(エルス)とは、「それ以外の」という意味の英語です。意味の通り、if文に与えられた条件以外の場合に実行する内容を指定できます。
#コード03
import random
ten = random.randint(0, 100)
print('今日の気分は', ten, '点です')
if ten <= 10:
#条件式 ten <= 10 を満たす場合に実行
print('今日は疲れてるね。')
print('外食にしようよ。')
else:
#条件式 ten <= 10 を満たさない場合に実行
print('外食もいいけれど・・・')
print('やっぱり、お母さんのカレーが食べたい!')
コード03の条件分岐の状況を下図に示します。条件式ten <= 10を満たす場合は、6~8行目を実行し、満たさない場合は10~12行目を実行します。
条件を満たした場合と、満たさない場合の対応を両方記述でき、どちらかのコードを必ず実行するので、コード02のような書き方よりも想定外のことが起こりにくく、安心感があります。
インデントの方法を下図に示します。if文の条件式がtrueの場合の影響範囲(6~8行目)と、else(エルス)の影響範囲(10~12行目)をそれぞれインデントします。
また、5行目の条件式の後や、9行目のelseの後のコロン(:)を、ついつい、忘れてしまいますので、注意しましょう。
コロンが最後についた命令文では、その後に命令文が影響を与える行が続きます。ですから、for文などでも同様に行末にコロンが使われます。
(2) 文法的な余談
余談になりますが、実はコード04でもエラーにはなりません。これは、文法的には、以下のようなことが許容されているからです。
・#によりコメントアウトした部分は、インデント幅の規定にしばられないので、実は6. 10行目のコメント文のインデント幅はいくらでもよい。
・7, 8行目のインデント幅はそろえる必要があり、11, 12行目のインデント幅はそろえる必要がありますが、「7, 8行目のインデント幅」と「11, 12行目のインデント幅」をそろえる必要はありません。
しかし、文法的には記述できても、読みやすいコードにするためには、コード03のように、6~8, 10~12行目はすべてインデント幅をそろえるべきです。また、インデントには必ず半角スペースを4つ使いましょう。
#コード04
import random
ten = random.randint(0, 100)
print('今日の気分は', ten, '点です')
if ten <= 10:
#条件式 ten <= 10 を満たす場合に実行
print('今日は疲れてるね。')
print('外食にしようよ。')
else:
#条件式 ten <= 10 を満たさない場合に実行
print('外食もいいけれど・・・')
print('やっぱり、お母さんのカレーが食べたい!')
4.入れ子の「if...else」で条件分岐を増やす
「if...else」で条件分岐できるのは、「条件を満たす場合(true)」と「条件を満たさない場合(false)」の2つだけです。「夕食決定プログラム」も、カレーと外食だけでは、ちょっと、さびしいですね。
そこで、2つ以上の条件分岐にも対応するために「if文の中にif文を記述する」つまり、if文を入れ子にします。コード05は、5~18行目の「if...else」の中に、10~18行目 の「 if...else 」を記述したものです。
なお、12~14, 16~18行目のインデントは半角スペース×8個です。入れ子にした場合には、インデントの数を4個ずつ増やします。
実はどんな複雑な条件分岐も、「if...else」を入れ子にすることで対応できますので、色々なプログラムに挑戦して、「if...else」の使いかたに慣れましょう。
#コード05
import random
ten = random.randint(0, 100)
print('今日の気分は', ten, '点です')
if ten <=10:
#条件式 ten <= 10 を満たす場合に実行
print('今日は疲れてるね。')
print('外食にしようよ。')
else:
#条件式 ten <= 10 を満たさない場合に実行
if ten <= 70:
#条件式 ten <= 70 を満たさない場合に実行
print('外食もいいけれど・・・')
print('やっぱり、お母さんのカレーが食べたい!')
else:
#条件式 ten <= 70 を満たさない場合に実行
print('気分がのりのり。餃子にしようよ。')
print('お父さんのビール買ってこようか?')
以下、コード05のif文の影響範囲を図示したものです。ここで注意するのは、10~18行目の「ten <= 70を判定するif文」は、5~18行目の「ten <= 10を判定するif文」のelseの中に入っているので、10~18行目は、「ten <= 10 を満たさない」ことが前提になっていることです。そのことに注意して、コード05を解読すると、以下のようになります。
ten≦10 → 外食
10<ten≦70 → カレー ※ten <= 10 を満たさないことが前提
70<ten → 餃子 ※ ten <= 10 を満たさないことが前提
5.「if...elif...else」を使った条件分岐
「if...else」だけで、どんな複雑な条件分岐も可能といったのに、また、難しそうなのが出てきたと思うかもしれませんが、 「if...elif...else」(イフ...エルスイフ...エルス)は、入れ子の「if...else」の表記を一部省略しただけなので、びっくりする必要はありません。
コード05では、さらに条件分岐が増えると内側の「if...else」が増え、どんどん、インデント幅が大きくなってしまいます。そこで、「 if...elif...else 」を使ってコード05を省略するとコード06になります。これはコード05の9行目と11行目を、くっつけただけです。書き方が違うだけなので、コードの意味は変わりません。くっつけた分だけ行が減りますし、その後のインデント幅が大きくなりませんので、コードが見やすくなります。
ただし、コード05では9行目と11行目の間にあるのはコメントだけなので、省略できましたが、この間に省略できない重要なコードがある場合には、省略できません。つまり、入れ子の「if...else」であれば、どんな場合でも「 if...elif...else 」に書き換えられるわけではありません。
なお、後述のコード08のように、elifの部分を複数設けることが可能であり、最後のelseは省略することが可能です。
#コード06
import random
ten = random.randint(0, 100)
print('今日の気分は', ten, '点です')
if ten <=10:
#条件式 ten <= 10 を満たす場合に実行
print('今日は疲れてるね。')
print('外食にしようよ。')
elif ten <= 70:
#条件式 ten <= 10 を満たさない場合に実行
#条件式 ten <= 70 を満たす場合に実行
print('外食もいいけれど・・・')
print('やっぱり、お母さんのカレーが食べたい!')
else:
#条件式 ten <= 10 を満たさない場合に実行
#条件式 ten <= 70 を満たさない場合に実行
print('気分がのりのり。餃子にしようよ。')
print('お父さんのビール買ってこようか?')
下図は、if文の影響範囲を示す図です。注意すべきなのは、コード05の時と同様に、10~13, 15~18行目の部分は「ten <= 10を満たさない」ことが前提になっていることです。
6.あまり、お勧めしない記述方法
コード05、コード06は、コード07のようにも書き換えられます。一見、わかりやすくて、よいように見えますが、コード02のところでも説明しましたように、条件分岐の計算回数が多く、「if...else」「if...elif...else」を使った方がよいと思います。
個人的な好みの問題かもしれませんが、このような記述はあまり見られないような気がします。できるだけ、 「if...else」の使い方に慣れるようにした方がよいと思います。
#コード07
import random
ten = random.randint(0, 100)
print('今日の気分は',ten,'点です')
if ten <= 10:
print('今日は疲れてるね。')
print('外食にしようよ。')
if (10 < ten) and (ten <=70):
print('外食もいいけれど・・・')
print('やっぱり、お母さんのカレーが食べたい!')
if 70 < ten:
print('気分がのりのり。餃子にしようよ。')
print('お父さんのビール買ってこようか?')
7.「if...elif...elif...elif...else」を使った条件分岐
さて、コード08aが「夕食決定プログラム」の完成版です。ゆうちゃんママへの愛情がつまっていて、ほっこりします。あとは、プログラムのネーミングだけ考え直そうね。
後日談ですが、家に戻って、ゆうちゃんママにプログラムを何回か回して見てもらった後、2行目の「ten = random.randint(0, 100)」の部分を「ten = random.randint(0, 10)」に書き直して、使ったそうです。当然、結果は「外食にしようよ。」となります。
「ゆうちゃん、ちょっと、ずるくない(笑)」というと、「いいんだよ、このプログラムに頼るときは、きっと、疲れてるんだから。」「それに、あとで、種明かししたもんね~」と言われました。
ゆうちゃん、なかなか、やりますね・・・。
#コード08a
ten = random.randint(0, 100)
print('今日の気分は', ten, '点です')
if ten <= 10:
print('今日は疲れてるね。')
print('外食にしようよ。')
elif ten <= 30:
print('たまには気分転換も必要だよ')
print('ビデオ借りて、ピザでも頼もう!')
elif ten <= 50:
print('チャーハンならつくれるから')
print('僕が作ってあげるよ。')
elif ten <= 70:
print('外食もいいけれど・・・')
print('やっぱり、お母さんのカレーが食べたい!')
elif ten <= 90:
print('気分がのりのり。餃子にしようよ。')
print('お父さんのビール買ってこようか?')
else:
print('90点を超えるなんて、超ラッキー。')
print('手巻きでお祝いしよう!')
念のため、コード08aの各部分がどのような条件の時に実行されるかについて、コード08b にコメントを加えました。コード08aが、少しわかりにくい人は参考にしてみてください。
#コード08b
ten = random.randint(0, 100)
print('今日の気分は', ten, '点です')
if ten <= 10: #条件1
#ten <= 10の時に行
print('今日は疲れてるね。')
print('外食にしようよ。')
elif ten <= 30: #条件2
#「条件1以外」かつ「ten <= 30」の時に実行
#つまり、10 < ten かつ ten <=30の時に実行
print('たまには気分転換も必要だよ')
print('ビデオ借りて、ピザでも頼もう!')
elif ten <= 50: #条件3
# 「条件1, 2以外」かつ「ten <= 50」の時に実行
# つまり、30 < ten かつ ten <= 50 の時に実行
print('チャーハンならつくれるから')
print('僕が作ってあげるよ。')
elif ten <= 70: #条件4
# 「条件1, 2, 3以外」かつ「ten <= 70」の時に実行
# つまり、50 < ten かつ ten <=70 の時に実行
print('外食もいいけれど・・・')
print('やっぱり、お母さんのカレーが食べたい!')
elif ten <= 90: #条件5
# 「条件1, 2, 3, 4以外」かつ「ten <= 90」の時に実行
#つまり、70 < ten かつ ten <= 90 の時に実行
print('気分がのりのり。餃子にしようよ。')
print('お父さんのビール買ってこようか?')
else:
#上の、どの各条件式にも、あてはまらない場合に実行
#つまり、90 < ten の時に実行
print('90点を超えるなんて、超ラッキー。')
print('手巻きでお祝いしよう!')
8.if文の学習を進める上での余談
さて、プログラムが完成した直後に言うことではありませんが、コード08a, 08bのように、elifがたくさん続くコードというのは、実際には少ないかもしれません。この方法で、例えば夕食の種類を50種類に増やすような場合には、elifの部分を増やせばよいのですが、ちょっと大変です。詳しい説明はしませんが、例えば、for文 と「リスト」を使い、できるだけメニューを追加しやすいコードを考える方が実用的です。これについては、後日、「リスト」を勉強したときに考えてみましょう。
プログラムを学習する上で、まずは「if...」「if...else」の使い方をしっかりと身につけましょう。入れ子構造のif文を自由自在に使いこなせることは非常に重要です。また、記述を簡素化できるならば、「if...elif...else」 も積極的に使いましょう。ただ、elifが多くなりすぎるときには、もっと、簡単な方法がないか考えてみましょう。
9.まとめ
以下、if文による条件分岐を簡単にまとめました。
(1) 「if...」シンプルなif文
if 条件式:
条件式がtrue(トゥルー)の場合に実行する
(2)「if…else」 を使った条件分岐
if 条件式:
条件式がtrue(トゥルー)の場合に実行する
else:
条件式がfalse(フォールス)の場合に実行する
(3)「if…elif…else」を使った条件分岐
if 条件式1:
条件式1がtrue(トゥルー)の場合に実行する
elif 条件式2:
条件式1がfalse、かつ、条件式2がtrueの場合に実行する
elif 条件式3
条件式1、2がfalse、かつ、条件式3がtrueの場合に実行する。
else:
条件式1~3がfalseの場合に実行する
※elif は、いくつでも増やせる。
※elseの部分は省略できる。
※条件式やelseのあとにはコロン(:)を忘れない。
※条件式で等しいことを表す記号は「=」ではなく「==」
10.例題
「大吉、吉、中吉、小吉、末吉、凶」の6種類の結果がでるおみくじプログラムを作りましょう。それぞれの結果がでる確率は同じであるとします。
実は、ゆうちゃんが作りたいプログラムの案を持ってくる前に私が考えていた例題です。(おもしろくない。つまらない。ありきたり。だめだ~。)
解答の表示・非表示の切り替え (Google Chrome推奨)
==============(解答表示start)==============
以下、解答例です。他にも色々な書き方があると思いますので、自分の思った通りに動けば正解です。
#コード09
import random
ten = random.randint(1,6)
if ten == 1:
print('大吉')
print('今日は最高')
elif ten == 2:
print('吉')
print('吉は中吉よりもいいんだよ。大吉の次だよ。')
print('でも、神社によっては小吉の次という場合もあるよ')
elif ten == 3:
print('中吉')
print('普通より、ちょっといいね')
elif ten == 4:
print('小吉')
print('小がつくけど、悪くないよ。ごく普通の運です。')
elif ten == 5:
print('末吉')
print('吉のなかの末っ子です。')
else:
print('凶')
print('占いなんて、いい時だけ信じればいい')
==============(解答表示end)===============
私が実際に購入した教材のご紹介
以下、私が実際に購入したPythonの教材をまとめてみました。 Pythonを学習する上で、少しでもお役に立つことができればうれしいです。
・Python♪私が購入したPythonの書籍のレビュー
・UdemyのPythonの動画講座を書籍を買う感覚で購入してみた
その他
液晶ペンタブレットを買いました
(1) モバイルディスプレイを買うつもりだったのに激安ペンタブレット購入
以下、私が光回線を導入した時の記事一覧です。
(1) 2020年「光回線は値段で選ぶ」では後悔する ←宅内工事の状況も説明しています。
(2) NURO光の開通までWiFiルーターを格安レンタルできる
(3) NURO光の屋外工事の状況をご紹介。その日に開通!
(4) 光回線開通!実測するとNURO光はやっぱり速かった
(5) ネット上のNURO光紹介特典は個人情報がもれないの?