コンピュータ演習II 第03回 条件分岐の基礎¶

この回では、値によって処理を変える 条件分岐 を学びます。条件分岐は if 文で表し、「もし〜ならば〜する」という判断をプログラムにさせるしくみです。第02回で学んだ変数・型・演算と、値どうしの比較が土台になります。 第02回と同じように、Colab で実際にコードを書いて実行しながら読み進めてください。

1. if 文¶

1.1 if 文の基本¶

世の中の多くのプログラムは、変数などの値によってその後の処理を変えることで、さまざまな機能を実現しています。このような処理を 条件分岐 と呼び、if 文によって表します。 if 文は「もし〜ならば〜を実行する」という処理を表す命令です。 まず、ある整数を持った変数を用意します。

In [1]:
a = 10

この変数a の値によって、画面に表示する文字列を変えるプログラムを書いてみます。

In [2]:
if a >= 10:         # 変数 a が 10 以上であるかどうか
    print("big")    # 10 以上のときに実行される処理
big

このプログラムは、変数a が10 以上のときにbig と表示します。変数a には10 が代入されているので、big と表示されます。 (なお# から右に書いた文字列は コメント と呼ばれ、プログラムの動作には影響しません。説明やメモを残すために使います。)

if 文の構造を図にすると、次のようになります。

if 文の構造。if のあとに条件式を書き、行末にコロンを付ける。次の行はインデントしてブロックを書き、条件式が真のときだけ実行される

if 文は、次の要素でできています。

  • 条件式:if のあとに書く式(上の例では a >= 10)。この式が成り立つかどうかを判定します。
  • コロン(:):条件式の終わりに必ず書きます。忘れるとエラーになります。
  • インデント:次の行の先頭に入れる空白(通常は半角スペース4 つ)。
  • ブロック:インデントした行のまとまり。条件式が成り立つときだけ実行されます。

条件式が成り立つことを「真(しん)」、成り立たないことを「偽(ぎ)」といいます。 a >= 10 の>= は、左辺と右辺を比べる記号で 比較演算子 と呼びます(次の項でくわしく説明します)。

本当に条件によって動作が変わるのか、確かめます。今度は変数a に10 より小さい値を入れて、同じプログラムを実行してください。

In [3]:
a = 5
if a >= 10:
    print("big")    # 変数 a は 10 未満なので、この行は実行されない

今度は何も表示されません。これは条件式a >= 10 が偽(成り立たない)であり、ブロックの中のprint("big") が実行されなかったためです。 このようにif 文を使うと、条件が真のときだけ処理を行う、という分岐ができます。

練習: if 文を書いてください¶

変数a に7 を代入し、「a が5 以上のとき ok と表示する」プログラムを書いてください。if、コロン(:)、インデントを正しく使ってください。

In [ ]:
a = 7

# a が 5 以上のとき ok と表示する if 文を書いてください

発展: 条件を変えてください¶

変数a に3 を代入し、「a が5 未満のとき small と表示する」プログラムを書いてください。比較演算子< を使います。

In [ ]:
a = 3

# a が 5 未満のとき small と表示する if 文を書いてください

1.2 比較演算子¶

if 文の条件式では、左辺と右辺の値を 比較演算子 で比べます。比較演算子には次のものがあります。

比較演算子 意味 例
== 左辺と右辺が等しい a == 10
!= 左辺と右辺が等しくない a != 10
< 左辺が右辺より小さい a < 10
> 左辺が右辺より大きい a > 10
<= 左辺が右辺以下(小さいか等しい) a <= 10
>= 左辺が右辺以上(大きいか等しい) a >= 10

ここで特に注意してほしいのが、「等しい」を表す==(イコール2 つ)です。第02回で学んだ代入の=(イコール1 つ)とは まったく別の意味 なので、混同しないでください。

  • = は 代入:右辺の値を左辺の変数に入れる。
  • == は 比較:左辺と右辺が等しいかを調べ、真か偽を返す。
左は = による代入操作。変数 a に値 10 を代入する。右は == による比較演算子。変数 a と値 10 が等しいかを比較し、True か False を返す

比較演算子による比較の結果は、値として取り出すこともできます。試しに、比較の結果をそのままprint してください。

In [4]:
print(10 >= 5)
print(10 == 5)
True
False

True(真)とFalse(偽)と表示されます。このTrue、False は 真偽値(しんぎち) と呼ばれる値で、その型をbool(ブール)型といいます。if 文は、条件式の結果がTrue のときにブロックを実行している、と考えるとわかりやすいです。 実際に、比較の結果の型を確認してください。

In [5]:
print(type(10 >= 5))
<class 'bool'>

<class 'bool'> と表示され、比較の結果がbool 型であることがわかります。

なお、比較できるのは数値同士だけではありません。文字列同士の比較もすることができます。試しに次のような比較を行ってみましょう。

In [5]:
s1 = "Hello"

print(s1 == "Hello")
print(s1 == "Hello")
True
False

二つの文字列を== で比較した場合、全く同じ文字列であれば、Trueとなり、文字列が異なるとFalse とななります。この例ではコンピュータが全角文字列と半角文字列を区別していることがよくわかると思います。

なお、比較演算子で比べる左辺と右辺は、基本的に 同じ型どうし にします。たとえば文字列型と整数型を比べようとすると、意図しない結果やエラーの原因になります。数値は数値どうし、文字列は文字列どうしで比べる、と覚えておいてください。

比較の結果を保存する¶

True や False は値なので、数値や文字列と同じように 変数に代入 できます。たとえば「a が 10 以上か」という判定の結果を、変数 is_big に入れてみます。

In [ ]:
a = 12
is_big = (a >= 10)   # a >= 10 の結果(True か False)を is_big に入れる
print(is_big)

a が 12 なので a >= 10 は成り立ち、is_big には True が入ります。a に 10 より小さい値を入れて実行すると、今度は False が入ります。 このように、比較の結果をそのまま変数に入れておくと、あとで if 文の条件に使ったり、判定結果を持ち運んだりするのに便利です。

練習: 学籍番号が偶数か判定する条件式¶

第02回で学んだ%(剰余)を使うと、整数が偶数か奇数かを判定できます。整数を2 で割った余りが0 なら偶数です。 自分の学籍番号後半5 桁を変数sid に代入し、「sid が偶数のとき even と表示する」プログラムを書いてください。条件式はsid % 2 == 0 です。

In [ ]:
sid = 60000   # ← 学籍番号後半5 桁(整数)に書き換えてください

# sid が偶数のとき(2 で割った余りが 0 のとき) even と表示する if 文を書いてください

発展: しきい値で判定する¶

学籍番号後半5 桁を変数sid に代入し、「sid が61100 以上のとき big と表示する」プログラムを書いてください。

In [ ]:
sid = 60000   # ← 学籍番号後半5 桁(整数)に書き換えてください

# sid が 61100 以上のとき big と表示する if 文を書いてください

2. if...else¶

1.1 では、条件が真のときに処理を行うプログラムを書きました。では、条件が 偽のときにも別の処理をしたい 場合はどうすればよいでしょうか。 たとえば次のプログラムでは、if の条件が真でも偽でも、最後の行はいつも実行されてしまいます。

In [6]:
a = 10
if a == 10:                  # 変数 a が 10 と等しいかどうか
    print("a は 10 です")

print("a は 10 ではありません")
a は 10 です
a は 10 ではありません

出力を見ると、a が10 であるにもかかわらず「a は 10 ではありません」まで表示されてしまい、これでは正しくありません。

このような「条件が真のときは処理 A、偽のときは処理 B」という分岐にはelse を使います。else は「それ以外」という意味です。

In [7]:
a = 10
if a == 10:                  # 変数 a が 10 と等しいかどうか
    print("a は 10 です")
else:                        # 上の条件式が偽のとき
    print("a は 10 ではありません")
a は 10 です

else は「それ以外」を表すので条件式は書かず、else の直後にコロン(:)を書きます。else のブロックは、if の条件式が偽のときだけ実行されます。 本当にelse が働いているか、変数a に10 以外の値を入れて確かめてください。

In [8]:
a = 11
if a == 10:
    print("a は 10 です")
else:
    print("a は 10 ではありません")
a は 10 ではありません

今度はa が10 と等しくない(条件が偽である)ため、「a は 10 ではありません」と表示されました。if とelse を使うと、真のときと偽のときの処理をきれいに分けられます。

練習: 偶数か奇数かを表示する(if...else)¶

学籍番号後半5 桁を変数sid に代入し、sid が 偶数なら even、奇数なら odd と表示するプログラムをif...else で書いてください。

In [ ]:
sid = 60000   # ← 学籍番号後半5 桁(整数)に書き換えてください

# sid が偶数なら even、奇数なら odd と表示する if...else 文を書いてください

発展: 大小で表示を変える(if...else)¶

学籍番号後半5 桁を変数sid に代入し、sid が61100 以上なら big、そうでなければ small と表示するプログラムをif...else で書いてください。

In [ ]:
sid = 60000   # ← 学籍番号後半5 桁(整数)に書き換えてください

# sid が 61100 以上なら big、そうでなければ small と表示する if...else 文を書いてください

3. if...elif...else¶

次に、3 つ以上に分岐 させる方法を考えます。たとえば、変数a が10 未満ならsmall、10 以上20 未満ならmedium、20 以上ならlarge と表示したいとします。 まず、if 文を3 つ並べて書いてみます。

In [9]:
a = 15

if a < 10:
    print("small")
if a < 20:
    print("medium")
if a >= 20:
    print("large")
medium

a が15 のときはmedium だけが表示され、うまくいっているように見えます。しかし、a に小さい値を入れると問題が起きます。

In [10]:
a = 5

if a < 10:
    print("small")
if a < 20:
    print("medium")
if a >= 20:
    print("large")
small
medium

a が5 のときはsmall とmedium の両方が表示されてしまいました。5 は「10 未満」でもあり「20 未満」でもあるため、独立した2 つのif 文をどちらも満たしてしまうのです。 このように、いくつかの条件のうち どれか1 つだけ を選びたいときはelif を使います。elif はelse if の略で、「ひとつ前の条件が偽だったときに、次の条件を判定する」という意味です。

In [11]:
a = 5

if a < 10:            # 条件1
    print("small")
elif a < 20:          # 条件2(条件1 が偽のときだけ判定する)
    print("medium")
else:                 # それ以外(条件1 も条件2 も偽のとき)
    print("large")
small

今度はsmall だけが表示され、想定どおりに動きました。if...elif...else は、上から順に条件を判定し、最初に真になったブロックだけ を実行します。どれか1 つが実行されると、残りの条件は判定されません。 ためしに、a の値を 5・15・30 と変えたとき、それぞれの条件が真(True)/偽(False)/判定されない、のどれになるかを次の図で見てみましょう。

a を 5・15・30 と変えたときに、if a < 10・elif a < 20・else の各条件が True・False・判定せず のどれになるかを並べた表。どの値でも、最初に True になった行までが判定され、それより下の条件は判定されない

最後のelse は「それ以外」なので条件式は書きません。elif は必要なだけいくつでも並べることができます。

練習: 学籍番号の下1 桁で分類(if...elif...else)¶

学籍番号後半5 桁を変数sid に代入します。その 1 の位(sid % 10 で求められます)を変数last に入れ、次のように分類して表示するプログラムをif...elif...else で書いてください。

  • last が3 未満なら low
  • last が3 以上7 未満なら mid
  • それ以外(7 以上)なら high
In [ ]:
sid = 60000   # ← 学籍番号後半5 桁(整数)に書き換えてください
last = sid % 10

# last の値で low / mid / high に分類して表示する if...elif...else 文を書いてください

発展: 3 で割った余りで分類(if...elif...else)¶

学籍番号後半5 桁を変数sid に代入します。sid を3 で割った余り(sid % 3)を変数r に入れ、次のように表示するプログラムをif...elif...else で書いてください。

  • r が0 なら A
  • r が1 なら B
  • それ以外(2)なら C
In [ ]:
sid = 60000   # ← 学籍番号後半5 桁(整数)に書き換えてください
r = sid % 3

# r の値で A / B / C に分類して表示する if...elif...else 文を書いてください

4. 乱数を使ってみよう¶

ここまでは、条件式で比べる値を自分であらかじめ決めていました。それだと結果がわかりきっていて、if 文のありがたみが感じられません。そこで、実行するたびに値が変わる 乱数 を使ってみます。 (この節と次の節は、if 文を実感するための体験です。提出課題では学籍番号を使うので、ここは気軽に試してください。)

Python では、random という ライブラリ(よく使う機能をまとめたもの)を使って乱数を作ります。

In [12]:
import random                 # 乱数の機能を使えるようにする

a = random.randint(0, 10)     # 0 から 10 までの整数をランダムに 1 つ作る
print(a)
8

import で始まる行は、ライブラリを呼び出す命令です。いまは「おまじない」だと思って構いません。random.randint(0, 10) は、0 以上10 以下の整数をランダムに1 つ返します。このセルを何回か実行して、毎回ちがう値が出ることを確かめてください。 乱数とif 文を組み合わせると、結果が予測できないプログラムになります。

In [13]:
import random

a = random.randint(0, 30)     # 0 から 30 までの乱数

if a < 10:
    print(a, "は小さい数です")
elif a < 20:
    print(a, "は中くらいの数です")
else:
    print(a, "は大きい数です")
21 は大きい数です

実行するたびに、a の値とメッセージが変わります。乱数とif 文を使えば、たとえばゲームで相手(CPU)の行動をランダムに決める、といったことができます。

練習: サイコロで当たり判定(乱数 × if...else)¶

1 から6 までの乱数(サイコロ)を変数dice に作り、出た目が4 以上なら あたり、そうでなければ はずれ と表示するプログラムを書いてください。サイコロはrandom.randint(1, 6) で作れます。何回か実行して、結果が変わることを確かめてください。

In [ ]:
import random

dice = random.randint(1, 6)
print("出た目:", dice)

# dice が 4 以上なら あたり、そうでなければ はずれ と表示する if...else 文を書いてください

発展: コイントス(乱数 × if...else)¶

0 か1 の乱数を変数coin に作り(random.randint(0, 1))、0 なら 表、1 なら 裏 と表示するプログラムを書いてください。

In [ ]:
import random

coin = random.randint(0, 1)

# coin が 0 なら 表、1 なら 裏 と表示する if...else 文を書いてください

5. 値を入力してみよう(input 関数)¶

今度は、プログラムを実行した人に 値を入力してもらう 方法を学びます。これにはinput 関数を使います。

In [14]:
a = input()      # キーボードからの入力を待ち、入力された値を a に入れる
print(a)
10

このセルを実行すると、入力待ちの状態になります。何か入力して Enter キーを押すと、その値が表示されます。 ここで、入力した値で条件分岐をさせてみます。4. のプログラムの先頭をinput に変えて、数値を入力してみてください。

In [15]:
a = input()      # 数値を入力してみる

if a < 10:
    print(a, "は小さい数です")
elif a < 20:
    print(a, "は中くらいの数です")
else:
    print(a, "は大きい数です")
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[15], line 3
      1 a = input()      # 数値を入力してみる
----> 3 if a < 10:
      4     print(a, "は小さい数です")
      5 elif a < 20:

TypeError: '<' not supported between instances of 'str' and 'int'

たとえば10 と入力すると、TypeError という赤いエラーが出てしまいます。10 という数字を入力したのに、なぜエラーになるのでしょうか。 実は、input 関数が返す値は、見た目が数字でも 文字列(str 型) だからです。文字列の"10" と数値の10 を< で比べようとして、エラーになっているのです。型を確認してみましょう。

In [16]:
a = input()      # 10 と入力してみる
print(a, type(a))
10 <class 'str'>

10 <class 'str'> と表示され、確かにstr 型になっています。第02回で学んだ キャスト を使い、int(input()) のように書けば、入力された文字列を整数に変換できます。

In [17]:
a = int(input())   # 入力された文字列を整数に変換する
print(a, type(a))
10 <class 'int'>

今度はint 型になりました。これを使えば、入力された数値で正しく条件分岐できます。

In [18]:
a = int(input())

if a < 10:
    print(a, "は小さい数です")
elif a < 20:
    print(a, "は中くらいの数です")
else:
    print(a, "は大きい数です")
10 は中くらいの数です

int(input()) の形は今後もよく使います。ただし、int に変換できない値(アルファベットや全角の文字など)を入力するとエラーになる点には注意してください。 入力した値が文字列であることを忘れるとTypeError が起きます。エラーは「悪いこと」ではなく、原因を教えてくれる手がかりです。赤いエラーが出たら、最後の行(エラーの種類と原因)を読む習慣をつけましょう。

練習: 入力した数の偶奇を判定(input × if...else)¶

int(input()) で整数を1 つ入力してもらい、それが偶数なら 偶数です、奇数なら 奇数です と表示するプログラムを書いてください。入力された値は文字列なので、int でキャストするのを忘れないでください。

In [ ]:
n = int(input())   # 整数を 1 つ入力してもらう

# n が偶数なら 偶数です、奇数なら 奇数です と表示する if...else 文を書いてください

発展: 入力した点数で評価(input × if...elif...else)¶

int(input()) で点数(0 から100)を入力してもらい、次のように評価を表示するプログラムをif...elif...else で書いてください。

  • 60 未満なら 不可
  • 60 以上80 未満なら 可
  • それ以外(80 以上)なら 優
In [ ]:
score = int(input())   # 点数(0 から 100)を入力してもらう

# score の値で 不可 / 可 / 優 に分類して表示する if...elif...else 文を書いてください

6. 演習: 大小ゲーム¶

最後に、この回で学んだことを全部使ったミニゲームを作ってみましょう。ルールは次のとおりです。

  • CPU は1 から10 までの数をランダムに1 つ決めます(あなたには見えません)。
  • あなたは1 から10 の数を1 つ入力します。
  • あなたの数が CPU より大きければ Win、小さければ Lose、同じなら Draw と表示します。

乱数(CPU の数)・input(あなたの数)・int へのキャスト・if...elif...else(勝敗の判定)と、今回学んだ要素がすべて登場します。

まずは材料をそろえます。CPU の数を乱数で作り、あなたの数を入力で受け取ります。input の返り値は文字列なので、int でキャストして数値にします。

In [ ]:
import random

cpu = random.randint(1, 10)    # CPU の数(1 から 10 の乱数)
you = int(input())             # あなたの数(1 から 10 を入力)

print("あなた:", you, "  CPU:", cpu)

あとは、you(あなたの数)とcpu(CPU の数)を比べて、勝敗を表示するだけです。if...elif...else を使って、次のセルを完成させてください。

  • you がcpu より大きいなら Win
  • you がcpu より小さいなら Lose
  • それ以外(同じ)なら Draw
In [ ]:
import random

cpu = random.randint(1, 10)
you = int(input())

print("あなた:", you, "  CPU:", cpu)

# you と cpu を比べて、Win / Lose / Draw を表示する if...elif...else 文を書いてください

完成したら何回か実行して、勝ったり負けたりすることを確かめてください。うまく動いたら、次のような改造にも挑戦してみましょう。

  • CPU の数の範囲を1 から100 に広げる。
  • 勝った差(you - cpu)も一緒に表示する。
  • 引き分けのときだけ、表示するメッセージを変える。

ここまでできれば、条件分岐の基礎はばっちりです。

まとめ¶

この回では、条件によって処理を変えるif 文を学びました。

  • if 文:条件式が真のときだけブロックを実行する。コロン(:) と インデント を忘れない。
  • 比較演算子:==, !=, <, >, <=, >=。代入の= と比較の== を混同しない。
  • if...else:条件が偽のときの処理も書ける。
  • if...elif...else:3 つ以上に分岐する。上から順に判定し、最初に真になった1 つだけを実行する。
  • 乱数(random.randint) と 入力(input):input の返り値は文字列なので、数値として使うときはint(input()) のようにキャストする。

次回以降の課題でもif 文は何度も登場します。コロンとインデント、== と= の違いに気をつけながら、しっかり慣れていきましょう。