ホーム»副業»プログラミング» 【プログラミング】[独学][Python-第4回]条件に応じて処理が分かれるコードの書き方
a

【プログラミング】[独学][Python-第4回]条件に応じて処理が分かれるコードの書き方

プログラミング

前回までは、文字出力や変数コレクションを用いたデータの扱い方について紹介しました。

第4回目となる今回は、条件分岐処理(条件判定をして条件に合った処理を行う)を紹介していきます。

条件分岐処理はPythonに関わらず、プログラミングにおいて凄く重要な処理であり、必須と言われる知識です。
コードの書き方としては、IF文を主体として書きますが、入れ子(ネスト)にしたり「And」や「Or」などを用いて〇〇かつ■■といったものであったり、〇〇若しくは■■といった何れかに当てはまる場合の処理などの書き方も存在します。

<strong>Deviko</strong>
Deviko

条件分岐というコトバが難しいわね。

<strong>komori</strong>
komori

言葉自体は難しく聞こえますが、どんなものもずっと固定な状態にあるものの方が少なく、変わっていくものとして考えれば、条件分岐が如何に大切であるか考えられるでしょう。


具体例をいくつか記載すると下記ようなものと考えて頂ければ大丈夫です。

[条件分岐処理]
①信号の点灯している色の条件に応じて処理を変えるプログラム
・もし、信号が赤なら停止という文字列を表示する。
・信号が赤ではないなら、進行という文字列を表示する。

②サービス登録者数の条件に応じて処理を変えるプログラム
・登録者数が50人を超えたらメッセージを表示する。
・登録者数が100人を超えたら上記とはメッセージを表示する。

③日付を条件に提出物が出ていない人をリストアップするプログラム
・〇月〇日までに提出がない人だけを抽出し催促する。

上記については、後からそれぞれ個別にコードを書いていきます。

なお、今回の内容についても下記の本に掲載されている内容から学んでいきましょう。

条件分岐コードサンプル

先ずは冒頭に紹介した①~③のコードを書いてみます。後の説明を見なくても何となくコードから読み取れるようなシンプルな内容になっています。

①信号の点灯している色の条件に応じて処理を変えるプログラム

入力コード

#信号が赤なら停止を促し、それ以外なら通行する文字を表示するプログラム
shingou = '赤'

if shingou == '赤':
    print(f'{shingou}信号は停止してください。')
else:
    print('通行してください。')

shingou = '青'#変数shingouを青に変更する。

if shingou == '赤':
    print(f'{shingou}信号は停止してください。')
else:
    print('通行してください。')

実行結果

赤信号は停止してください。
通行してください。

②サービス登録者数の条件に応じて処理を変えるプログラム

入力コード

サービス登録者数の条件に応じて処理を変えるプログラム

tourokusya = 49
if 50 <= tourokusya < 100:#50以上100未満の場合
    print(f'登録者が{tourokusya}人に達しました。ありがとうございます!')
elif tourokusya >= 100:#100以上の場合
    print(f'登録者が{tourokusya}人に達しました。ありがとうございます!!')
else:#その他場合
    print(f'登録者が{tourokusya}人です。登録者募集中です。')
    
tourokusya = 50
if 50 <= tourokusya < 100:#50以上100未満の場合
    print(f'登録者が{tourokusya}人に達しました。ありがとうございます!')
elif tourokusya >= 100:#100以上の場合
    print(f'登録者が{tourokusya}人に達しました。ありがとうございます!!')
else:#その他場合
    print(f'登録者が{tourokusya}人です。登録者募集中です。')

tourokusya = 99
if 50 <= tourokusya < 100:#50以上100未満の場合
    print(f'登録者が{tourokusya}人に達しました。ありがとうございます!')
elif tourokusya >= 100:#100以上の場合
    print(f'登録者が{tourokusya}人に達しました。ありがとうございます!!')
else:#その他場合
    print(f'登録者が{tourokusya}人です。登録者募集中です。')

tourokusya = 100
if 50 <= tourokusya < 100:#50以上100未満の場合
    print(f'登録者が{tourokusya}人に達しました。ありがとうございます!')
elif tourokusya >= 100:#100以上の場合
    print(f'登録者が{tourokusya}人に達しました。ありがとうございます!!')
else:#その他場合
    print(f'登録者が{tourokusya}人です。登録者募集中です。')

実行結果

登録者が49人です。登録者募集中です。
登録者が50人に達しました。ありがとうございます!
登録者が99人に達しました。ありがとうございます!
登録者が100人に達しました。ありがとうございます!!
<strong>komori</strong>
komori

コードが長く見えますが、違う分岐を通るように変数tourokusyaの値を変更しているだけです。※ifブロック・elifブロック・elseブロック以降は全く同じです。

③日付を条件に提出物が出ていない人をリストアップするプログラム

入力コード

#日付を条件に提出物が出ていない人をリストアップするプログラム

staff = ['ピカチュー','フシギダネ','ポッチャマ','ヒトカゲ','ゼニガメ']
#スタッフのリストを作成

kijitu = ['1月1日','未提出','1月15日','1月8日','未提出']
#提出日のリストを作成

S_kijitu = dict(zip(staff,kijitu))
#上記2つのリストをディクショナリとして統合する

#リスト(staff)とリスト(kijitu)で作成したディクショナリ(S_kijitu)を表示する
print(S_kijitu)

#下記は"未提出"の値を持つキー(スタッフ名)の抽出方法。
#2通りで記述する(同じ結果となります)。
#---------------------------
#①for文での未提出者を抽出方法
miteisyutu = []#空のリストを作成
for k,v1 in S_kijitu.items():#for文による未提出者の抽出として辞書型のキーと値に対して繰り返す
    if v1 == '未提出':#値が'未提出'であるかの判定。
        miteisyutu.append(k)#空のリストに条件に一致した値と紐づくキーを代入する。
print(miteisyutu)

#②リスト内包表記という書き方での未提出者抽出方法
miteisyutu2 = [d for d, v2 in S_kijitu.items() if v2 == '未提出']
print(miteisyutu2)
#---------------------------

実行結果

{'ピカチュー': '1月1日', 'フシギダネ': '未提出', 'ポッチャマ': '1月15日', 'ヒトカゲ': '1月8日', 'ゼニガメ': '未提出'}
['フシギダネ', 'ゼニガメ']
['フシギダネ', 'ゼニガメ']
<strong>Deviko</strong>
Deviko

未提出者がフシギダネとゼニガメといった結果が返ってきたって事ね。でも、forとかはまだ書き方の説明を受けていないような。。。

<strong>komori</strong>
komori

サンプルコードの③は、今の段階では実例として参考程度に見てもらえば大丈夫です。今回の条件分岐処理では①と②が理解できれば大丈夫です。

条件分岐との組み合わせで非常に重要になる繰り返し(for文)については下記で説明しています。

【プログラミング】[Python-第5回]繰り返しの処理を実行してみよう

プログラムの流れ

文と制御構造

Pythonでは、1行の実行単位を文(ステートメント)と呼びます。また、文の実行順をコントロールするプログラムの構成を制御構造と呼びます。この制御構造の代表的なものが、順次・分岐・繰り返し(ループ)となります。


[構造化定理]
プログラムはこの3つだけで作られていて、これらの制御構造の組み合わせでどんな複雑なプログラムを作る事が理論上可能となっています。

<strong>Deviko</strong>
Deviko

何だか難しい話になってるような気がするけど、順次・分岐・繰り返し(ループ)が書ければどんなプログラムだって書けるようになるってこと?

<strong>komori</strong>
komori

厳密にはその他の要素も少なからず関わりますが、基本の制御構造とその組み合わせを抑えておけば難しいプログラムでも書けるようになります。

条件分岐の基本構造

if文

入力コード

name = input('ポケモンの名前をおしえてください >>')
print(f'あなたのポケモンは「{name}」さんってお名前なんですね。')
food = input(f'「{name}」さんの好きな食べ物を教えてください >>')
print(f'私も{food}が好きです。')

実行結果

ポケモンの名前をおしえてください >> ピカチュー
あなたのポケモンは「ピカチュー」さんってお名前なんですね。
「ピカチュー」さんの好きな食べ物を教えてください >> ケチャップ
私もケチャップが好きです。

上のコードに条件分岐を加えていきます。

入力コード

name = input('ポケモンの名前をおしえてください >>')
print(f'あなたのポケモンは「{name}」さんってお名前なんですね。')
food = input(f'「{name}」さんの好きな食べ物を教えてください >>')

if food == 'ケチャップ':
    print(f'{food}は最高です!')
    print(f'やはりカ〇メの{food}が最高です!')
else:
    print(f'私も{food}が好きです。')
    print(f'{food}も良いですが、ケチャップも好きです。')   

[解説]
if文の書き方は下記となります。
if 条件式:
条件が成立した時の処理(ifブロック)
else:
条件が成立しなかった時の処理(elseブロック)
末尾にコロンを付けること、処理行を記載する時は字下げ(インデント)を行う必要があります。(※ジュピターラボはTabキーを押す事で字下げ(インデント)が可能です。)
また、if配下の処理をifブロック、else配下の処理をelseブロックと呼びます。

実行結果1

ポケモンの名前をおしえてください >> ピカチュー
あなたのポケモンは「ピカチュー」さんってお名前なんですね。
「ピカチュー」さんの好きな食べ物を教えてください >> ケチャップ
ケチャップは最高です!
やはりカ〇メのケチャップが最高です!

実行結果2

ポケモンの名前をおしえてください >> ピカチュー
あなたのポケモンは「ピカチュー」さんってお名前なんですね。
「ピカチュー」さんの好きな食べ物を教えてください >> おでん
私もおでんが好きです。
おでんも良いですが、ケチャップも好きです。

ブロックとインデント

入力コード

v = int(input('ピカチューさんの電圧の数値を入力してください >>'))

if v == 100000:
    print('きみに決めた!')
    print(f'ピカチュー、{v}ボルトだ!!!')
else:
    print('きみに決めて良いのか?')
    print(f'{v}ボルト?君は本当にピカチューなのか???')

print('もう一度ピカチューをゲットするところからやり直しだ。')

[インデントに対する検証]
上記はピカチューの電圧を確認し、その数値が100,000であった場合とそうでなかった場合の分岐を書いたコードとなります。結果をそれぞれ確認してみます。

実行結果1

ピカチューさんの電圧の数値を入力してください >> 100000
きみに決めた!
ピカチュー、100000ボルトだ!!!
もう一度ピカチューをゲットするところからやり直しだ。

実行結果2

ピカチューさんの電圧の数値を入力してください >> 10
きみに決めて良いのか?
10ボルト?君は本当にピカチューなのか???
もう一度ピカチューをゲットするところからやり直しだ。
<strong>Deviko</strong>
Deviko

100,000を入力しても「もう一度ピカチューをゲットするところからやり直しだ。」の部分が表示されているけど?

<strong>komori</strong>
komori

入力コードの最後を見てみると、字下げ(インデント)していないので、elseブロックとしてみなされておらず、条件の成立・不成立に関わらず実行される処理となっています。


条件式

比較演算子

比較演算子とは下記のようなもののことです。

演算子意味
==左辺と右辺は等しい
!=左辺と右辺は等しくない
>左辺は右辺より大きい
<左辺は右辺より小さい
>=左辺は右辺より大きいか等しい
<=左辺は右辺より小さいか等しい
※等しいを表す際の==は、=としてしまいがちな点に注意が必要です。

in演算子

入力コード

name = 'ピカチュー'
food = input(f'{name}さんの好きな食べ物を教えてください。>> ')
if 'ケチャップ' in food:
    print(f'やはりカ〇メの{food}を使っているところが最高です!')
else:
    print(f'{food}も良いですが、ケチャップも好きです。')   

[解説]
2行目に入力した食べ物に’ケチャップ’という文字列が含まれているかを判定しています。
サンプルコードでは’ケチャップライス’と’オムライス’を入力していますので、それぞれの実行結果が返ってきます。

実行結果1

ピカチューさんの好きな食べ物を教えてください。>>  ケチャップライス
やはりカ〇メのケチャップライスを使っているところが最高です!

実行結果

ピカチューさんの好きな食べ物を教えてください。>>  オムライス
オムライスも良いですが、ケチャップも好きです。
<strong>Deviko</strong>
Deviko

オムライスに’ケチャップ’という文字列が含まれていないから、条件に一致しない処理になったって事ね。

入力コード

#コレクション内に要素が存在するかをチェックする。

#リスト
food = ['ケチャップ','マヨネーズ','ソース','しょうゆ','みそ']
#ディクショナリ
special = {'ケチャップ':2,'マヨネーズ':3,'ソース':1,'しょうゆ':1,'みそ':3}

if 'ケチャップ' in food:
    print('ケチャップはリスト内に入ってます。')
else:
    print('ケチャップはリスト内に入ってません。')

    
seasoning = str(input('追加する調味料を入力してください >>'))
if seasoning in special:
    print('ケチャップはディクショナリ内に入ってます。')
else:
    new = int(input('数量を入力してください >>'))
    special[seasoning] = new

print(special)

実行結果1

ケチャップはリスト内に入ってます。
追加する調味料を入力してください >> ケチャップ
ケチャップはディクショナリ内に入ってます。
{'ケチャップ': 2, 'マヨネーズ': 3, 'ソース': 1, 'しょうゆ': 1, 'みそ': 3}

リストの要素として既に’ケチャップ’が含まれているかをin演算子を用いて確認しています。
実行結果として、ケチャップは既にリスト内にあるので条件に一致した処理が結果として表示されます。

ディクショナリはキーと値を持つコレクションとなりますが、入力された文字列がキーとして既に登録されている’ケチャップ’の場合は「ケチャップはディクショナリ内に入ってます。」と表示が返ってきて新たな要素としての追加は行わない処理となります。

実行結果2

ケチャップはリスト内に入ってます。
追加する調味料を入力してください >> 砂糖
数量を入力してください >> 2
{'ケチャップ': 2, 'マヨネーズ': 3, 'ソース': 1, 'しょうゆ': 1, 'みそ': 3, '砂糖': 2}

ディクショナリ内に未登録のキーが入力された場合は、数量を入力する処理に移行し、ディクショナリに登録されます。(※サンプルでは砂糖:2が新たに登録されました。)

<strong>komori</strong>
komori

リスト内に新たに要素を追加する際のチェックが可能なので、重複しないコレクションを作りたい時に使えるコードとなります。

真偽値

TrueやFalseの値のことです。
文字列型(str)ではなく、bool型となるので「 ‘ 」や「 ” 」を付与しません。

入力コード

#真偽値とはTrueやFalseといったbool型の値のこと
favorite = input('好物を入力してください >>')
print(favorite == 'ケチャップ')
print(type(favorite == 'ケチャップ'))

実行結果1

好物を入力してください >> ケチャップ
True
<class 'bool'>

実行結果2

好物を入力してください >> ゆずこしょう
False
<class 'bool'>
<strong>Deviko</strong>
Deviko

Trueであれ、Falseであれstr型ではなく、bool型ってことで良いのよね。

<strong>komori</strong>
komori

if文の評価結果は「True」ならifブロックの処理となり、「False」ならelseブロックの処理となっています。

論理演算子

論理演算子とは下記のようなもののことを指します。

演算子意味
andかつ
orまたは
notでなければ(否定)

入力コード

new = int(input('新しいポケモンの可愛さは100点満点中、何点か入力してください >>'))
if new < 30 or new >= 80:#50よりも大きくて、80以下の数字の場合
    print(f'{new}ですか、個性的ですね!!!')
else:
    print(f'{new}ですか、かわいいですね')

上のコードの場合は、30未満と80以上の数字であった場合は「True」でifブロックの処理となります。逆に30以上80未満であった場合は「False」でelseブロックの処理が実行されることになります。

実行結果

新しいポケモンの可愛さは100点満点中、何点か入力してください >> 29
29ですか、個性的ですね!!!

notを使ったコードについても書いてみます。

入力コード

new = int(input('新しいポケモンの可愛さは100点満点中、何点か入力してください >>'))
if not(new < 30 or new >= 80):#50よりも大きくて、80以下の数字の場合
    print(f'{new}ですか、個性的ですね!!!')
else:
    print(f'{new}ですか、かわいいですね')

先のコードにnotを付けただけですが、こちらの場合は30未満と80以上の数字であった場合は「False」となり、elseブロックの処理が実行されます。
逆に30以上80未満であった場合は「Ture」でifブロックの処理が実行されることになります。

実行結果

新しいポケモンの可愛さは100点満点中、何点か入力してください >> 29
29ですか、かわいいですね

先ほどは29点で「個性的ですね」だったものが、今度は「かわいいですね」が実行されていることが分かるかと思います。

論理演算子-応用編

入力コード

pokemon = ['ピカチュー','ゼニガメ','ヒトカゲ','ポッチャマ','トゲピー']
level = [50,15,30,20,1]

#notを用いてリスト内に含まれていないかを判定するコードの書き方
new = input('新しく図鑑に登録するポケモン名を入力してください。>>')
if not new in pokemon:#notが入っているためリスト内に登録されていなければTrueとなる。
    print(f'{new}が新しく図鑑に登録されますぅ')    
else:
    print(f'{new}は既に図鑑に登録されています。')

#比較演算子で範囲を指定したコードの書き方   
hitokage = 30
if 10 <= hitokage < 50:
#hitokage >= 10 and hitokage < 50 と同じ。
    print(f'ヒトカゲのレベルは{hitokage}で、10~49の間です。')
else:
    print(f'ヒトカゲのレベルは{hitokage}で、10~49の間ではないです。')
    
#真偽値に評価されない式のコード(0かどうかの判定式)
score = 0
if score:
    print('Trueです。')#0以外ならTrueとなる
else:
    print('Falseです。')#0はFalseとなる
<strong>Deviko</strong>
Deviko

論理演算子と比較演算子を組み合わせて数値の範囲などを条件にすることも出来るわね。

実行結果

新しく図鑑に登録するポケモン名を入力してください。>> ヒトカゲ
ヒトカゲは既に図鑑に登録されています。
ヒトカゲのレベルは30で、10~49の間です。
Falseです。

分岐構文のバリエーション

3種類のif文

①if-else構文
if 条件式 :
条件式が成立した時の処理
else:
条件が成立しなかった時の処理

入力コード

pokemon = 'ピカチュー'
if pokemon == 'ピカチュー':
    print(f'変数pokemonはピカチューです。')
else:
    print(f'変数pokemonは{pokemon}です。')
    
pokemon = 'ライチュー'
if pokemon == 'ピカチュー':
    print(f'変数pokemonはピカチューです。')
else:
    print(f'変数pokemonは{pokemon}です。')

pokemon = 'ゼニガメ'
if pokemon == 'ピカチュー':
    print(f'変数pokemonはピカチューです。')
else:
    pass #elseブロックで処理を無しにする場合は、passを書かないとエラーとなる。

実行結果

変数pokemonはピカチューです。
変数pokemonはライチューです。


②ifのみの構文
if 条件式 :
条件式が成立した時の処理

入力コード

#条件に当てはまらない時の処理がないコード
pokemon = 'ピカチュー'
if pokemon == 'ピカチュー':
    print(f'変数pokemonはピカチューです。')

print(f'ピカチューが新しく図鑑に登録されますぅ')

pokemon = 'ゼニガメ'
if pokemon == 'ピカチュー':
    print(f'変数pokemonはピカチューです。')

print(f'{pokemon}が新しく図鑑に登録されますぅ')

実行結果

変数pokemonはピカチューです。
ピカチューが新しく図鑑に登録されますぅ
ゼニガメが新しく図鑑に登録されますぅ


③if-elif構文
if 条件式1 :
条件式1が成立した時の処理
elif 条件式
2:
条件式2が成立した時の処理

else :
条件が成立しなかった時の処理

入力コード

#if-elif構文の条件式に成立しない時に更に別の条件での判定が可能(多分岐)。
pokemon = 'ヒトカゲ'

if pokemon == 'ピカチュー':
    print(f'変数pokemonはピカチューです。これはifブロックです。')
elif pokemon == 'ライチュー':
    print(f'変数pokemonはライチューです。これはelifブロックです。')
elif pokemon == 'ゼニガメ':
    print(f'変数pokemonはゼニガメです。これはelifブロックです。')
else:
    print(f'変数pokemonはピカチューでもなく、ライチューでもなく、ゼニガメでもなく{pokemon}です。これはelseブロックです。')
    
print(f'{pokemon}が新しく図鑑に登録されますぅ')

実行結果1

変数pokemonはピカチューです。これはifブロックです。
ピカチューが新しく図鑑に登録されますぅ

実行結果2

変数pokemonはライチューです。これはelifブロックです。
ライチューが新しく図鑑に登録されますぅ

実行結果3

変数pokemonはゼニガメです。これはelifブロックです。
ゼニガメが新しく図鑑に登録されますぅ

実行結果4

変数pokemonはピカチューでもなく、ライチューでもなく、ゼニガメでもなくヒトカゲです。これはelseブロックです。
ヒトカゲが新しく図鑑に登録されますぅ

if文の入れ子(ネスト)

入力コード

pokemon = input('登録するポケモンの名前を入力してください >>')

if pokemon == 'ピカチュー':
    size = int(input('ポケモンの大きさを数値で入力してください? >>'))
    if size == 40:
        color = input('ポケモンの色を入力してください? >>')
        if color == '黄色':
            print(f'それは紛れもなく{pokemon}です。新しく図鑑に登録されますぅ')
        else:
            print(f'{pokemon}の色ではありません。')            
    else:
        print(f'{pokemon}の大きさではありません。')
else:
    print('登録したいポケモンはピカチューではないのですね。')

実行結果1

全てのifの条件が成立した実行結果

登録するポケモンの名前を入力してください >> ピカチュー
ポケモンの大きさを数値で入力してください? >> 40
ポケモンの色を入力してください? >> 黄色
それは紛れもなくピカチューです。新しく図鑑に登録されますぅ

実行結果2

最初のif文が成立しない場合の実行結果

登録するポケモンの名前を入力してください >> ポッチャマ
登録したいポケモンはピカチューではないのですね。

実行結果3

2段階目のif文の条件が成立しない場合の実行結果

登録するポケモンの名前を入力してください >> ピカチュー
ポケモンの大きさを数値で入力してください? >> 15
ピカチューの大きさではありません。

実行結果4

3段階目のif文の条件が成立しない場合の実行結果

登録するポケモンの名前を入力してください >> ピカチュー
ポケモンの大きさを数値で入力してください? >> 40
ポケモンの色を入力してください? >> 青色
ピカチューの色ではありません。
<strong>komori</strong>
komori

論理演算子や比較演算子と、入れ子(ネスト)を使えば複雑な条件判定をつくる事が出来ますが、多分岐で各条件が複雑になるとプログラムが読みにくくなってしまう恐れがあります。

まとめ

[文と制御構造]
・1行に記載された1つの処理が実行単位であり、1つの文である。
・文の実行順序は制御構造によってコントロールすることができ、主に順次・分岐・繰り返し(ループ)の3つがある。

[条件分岐]
・if文は、条件に従った処理を分岐させることができる。
・if文は、条件が成立したらifブロックを、不成立ならelseブロックを実行する。
・ブロックはインデント(字下げ)によって指定することが必要である。


[条件式]
・比較演算子や論理演算子を用いて分岐する条件を記述する。
・条件式は評価されると真偽値(True or False)に置き換わる。

・in演算子を使ってコレクション内の要素が存在する・しないを条件とすることができる。

[分岐構文のバリエーション]
・if-else構文・if-else構文は処理を2つに分岐させることができる。
・ifのみの構文は処理を実行するか、しないかに分岐させることができる。
・if-elif構文は処理を3つ以上に分岐させることができる。
・if文は入れ子(ネスト)できる。

次回は繰り返し処理について紹介します。

コメント

タイトルとURLをコピーしました