
武蔵野個別指導塾の特徴
高校情報I 条件分岐の境界—条件を区間に分けて抜けと重なりを直す|武蔵野個別指導塾

温度帯の表示で閾値の前後と不正入力を試し、重複を防ぐ焦点は条件分岐の境界です。
よくあるのは、高校生が独立したifを並べ、1つの温度に対して表示を重複させる場面です。例えば、低い温度の条件と高くない温度の条件が両方成り立つと、両方の表示が実行されます。どちらか1つを選びたいなら、境界だけでなく、条件どうしの関係と実行順も設計します。
どの境目で表示が変わるか
条件分岐の問題には、区間の説明から条件式を作る型、コードを追って出力を求める型、境界の入力で誤りを見つけて直す型があります。いずれも先に入力の範囲と出力の形を決めます。今回の温度は整数の摂氏温度とし、表示は文字列1個です。温度の測定方法や実際の安全基準を決める問題ではありません。
自作の表示規則を、0以上40以下の入力について、15未満は「低」、15以上25未満は「中」、25以上は「高」とします。0と40も有効です。この範囲外、整数でない値、値の欠落は「入力エラー」とし、温度帯として扱いません。入力を読む道具が時間切れになった場合も値が得られなかったものとし、勝手に0を代入せず「入力エラー」にします。以下の関数は、読み取れた値または欠落を表すNoneを受け取る設計です。
条件を作った後は、各境界の直前・一致・直後を試します。整数の入力なら15の前後は14、15、16です。25についても24、25、26を選びます。範囲の端である0と40だけでなく、その外の-1と41も確かめます。範囲の外に出力を与えるかどうかは、問題の仕様によって変わるため、ここではエラーと明記しました。
区間を切り、順番をつける
比較演算子の < は右側を含まず、<= は右側を含みます。>= は右側以上です。区間表の「15以上25未満」では15を含み、25を含みません。境界の値を両隣に入れたり、どちらにも入れなかったりしないように、境目ごとに所属先を決めます。
図1のように、まず有効な範囲を3つの区間に分けます。矢印は温度が大きくなる方向です。15は中央に、25は右に入ります。図1の区間を言葉で読み直すと、どの有効な整数にも表示先があり、同じ値が2区間に入ることはありません。

Pythonのifは条件が真ならその下の処理を実行します。elifは直前までのifやelifがいずれも偽だった場合に試し、elseはそれらがすべて偽だった場合に実行します。同じまとまりでは最初に真になった枝を選ぶため、後の条件を試す時点で前の条件が偽であることが使えます。
例えば有効な整数に対し、最初に15未満かを調べ、次に25未満かを調べます。2番目に到達した値は15未満ではないので、25未満なら15以上25未満です。最後に残るのは25以上です。独立したifを3つ書けば、それぞれが別に判定されます。条件を重ねた場合は複数の処理が動くので、elifの代わりにはなりません。
基本例題:表示を1個返す
次の関数を作り、14、15、24、25を渡してください。期待する戻り値を順に「低」「中」「中」「高」とします。また、0、40、-1、41、文字列、Noneについても、上の入力規則に従う戻り値を求めます。真偽値はPythonでは整数として扱われることがありますが、この問題では温度の整数に含めません。
def band(t):
if type(t) is not int:
return "入力エラー"
if t < 0 or t > 40:
return "入力エラー"
if t < 15:
return "低"
elif t < 25:
return "中"
else:
return "高"
for value in [14, 15, 24, 25, 0, 40, -1, 41, "15", None]:
print(repr(value), band(value))
1行目で温度を受け取る関数を定義します。2行目は型を調べ、整数でなければ3行目でエラーを返して関数を終えます。4行目は有効範囲の外を調べ、5行目で同様に終えます。これで後の比較は有効な整数に限られます。6行目は15未満を判定し、真なら7行目を返します。8行目に来たときは15以上なので、25未満なら9行目を返します。残りは10行目のelseから11行目の「高」です。最後の2行は入力を順に渡し、元の入力と結果を表示します。reprは文字列と数値の違いを表示上も見分けるために使います。
図2のように15は最初の判定を通過し、次の判定で「中」になります。25は2つ目も通過し「高」です。図2に示した4つは、それぞれ元の区間表に戻しても所属先が一致します。

実行環境はPython 3.15.0です。入力、手で求めた期待値、実際の出力は次のとおり一致しました。
14 低
15 中
24 中
25 高
0 低
40 高
-1 入力エラー
41 入力エラー
'15' 入力エラー
None 入力エラー
15と25の直前・一致・直後は、さらに16が「中」、26が「高」です。0と40は範囲に含み、-1と41は含みません。文字列の「15」は数として比較せずエラーです。値が欠落したNoneもエラーなので、後段にもっともらしい温度帯を渡しません。これらは具体例の確認であり、一般の正しさは区間が全範囲を漏れなく重なりなく覆うことと、各枝の判定順から説明します。
次の追加試験では、成功6件と失敗6件を同数ずつ扱います。期待値と実行値は、成功側が14、15、16、24、25、26に対して順に「低」「中」「中」「中」「高」「高」、失敗側が-1、41、空文字、壊れた文字列、None、Trueに対していずれも「入力エラー」です。空文字と壊れた文字列は数へ変換せず、Trueも温度の整数から除きます。取得時の例外と時間切れは後の例題で別に試します。
標準例題:順序を入れ替える
同じ規則を高い側から判定します。有効な整数について25以上なら「高」、そうでなく15以上なら「中」、残りを「低」とします。入力と出力の条件は基本例題と同じです。次のコードは先ほどのband関数の定義に続けて実行します。
def band_high_first(t):
if type(t) is not int:
return "入力エラー"
if t < 0 or t > 40:
return "入力エラー"
if t >= 25:
return "高"
elif t >= 15:
return "中"
else:
return "低"
for value in [14, 15, 16, 24, 25, 26, -1, 41]:
print(value, band(value), band_high_first(value))
最初の4行で型と範囲を守る点は同じです。25以上なら「高」を返し、それ以外で15以上なら「中」を返します。最後に到達するのは15未満です。反復の各回はリストから1個ずつ取り出し、有限の8個を処理すると終了します。各回の2つの戻り値を比較すると、期待値と実際の出力は次のとおりです。
14 低 低
15 中 中
16 中 中
24 中 中
25 高 高
26 高 高
-1 入力エラー 入力エラー
41 入力エラー 入力エラー
順序を変えても区間を同じにすれば結果は一致します。ただし、低い側からの条件をそのまま高い側の順に並べ替えると、広い条件に先に入る値が生じます。たとえば t < 25 を先にすると14も「中」となり、後の t < 15 には到達しません。条件式と順序を一組として考えます。
発展例題:読めない値を区別する
入力装置からの応答を想定し、正常に得られた値はそのまま、欠落はNone、装置の例外や時間切れもNoneに置き換えてからbandへ渡します。ここでの装置は自作の関数で、実際の測定器を操作しません。空文字や壊れた文字列は整数へ変換せず、入力エラーにします。例外を握りつぶして前回の値を再利用すると、古い温度を現在の値として表示するため危険です。
def read_sample(mode):
if mode == "ok":
return 20
elif mode == "broken":
return "20度"
elif mode == "timeout":
raise TimeoutError
else:
raise ValueError
def checked_read(mode):
try:
value = read_sample(mode)
except (TimeoutError, ValueError):
value = None
return band(value)
for mode in ["ok", "broken", "timeout", "other"]:
print(mode, checked_read(mode))
read_sampleはモードに応じて値を返すか例外を起こします。checked_readは読み取りを試み、指定した例外を受けた場合にNoneを設定します。最後にbandが型と範囲を検査します。期待値と実際の出力は順に「中」「入力エラー」「入力エラー」「入力エラー」です。
ok 中
broken 入力エラー
timeout 入力エラー
other 入力エラー
正常値20は15以上25未満に戻せます。壊れた文字列、時間切れ、その他の読み取り失敗では温度帯を返しません。この小さな例で扱う例外は2種類に限定し、あらゆる装置の故障を捕捉できると主張するものではありません。実装時は装置の仕様に合わせ、どの失敗を受け取るか決めます。
重なった条件を修正して再実行する
次の誤った関数は、基本例題と同じ有効な整数を受け取るものとします。リストに入った表示を順に返すため、意図せず複数になったことを観察できます。
def wrong(t):
result = []
if t < 15:
result.append("低")
if t < 25:
result.append("中")
if t >= 25:
result.append("高")
return result
for value in [14, 15, 25]:
print(value, wrong(value), band(value))
14の期待は表示1個の「低」ですが、実際の誤った結果は「低」と「中」の2個です。15では「中」、25では「高」となり、一部の値だけを試すと欠陥を見逃します。図3のように14は2つの独立した条件を満たすため、2回追加されます。原因は比較の計算ではなく、枝が別々であることです。

修正には、基本例題のようにif、elif、elseを1組にし、最初の該当先からreturnします。再実行では右端が修正後の結果です。
14 ['低', '中'] 低
15 ['中'] 中
25 ['高'] 高
図3の修正後は14が最初の枝で終了し、次の条件へ進みません。15と25も元の区間に戻して所属を確かめます。誤りを直した後は、失敗した14だけでなく、以前正しかった15と25も再実行します。範囲外や壊れた入力については、有効値専用のwrongに無理に渡さず、入力検査を含むbandで試します。
練習:別の境界で考える
各問は独立した自作条件です。整数を扱い、求める表示は文字列1個とします。入力の取得に失敗したときは「エラー」とします。
- 作品の乾燥時間を0以上30以下の整数分で受け、8未満を「短」、8以上20未満を「中」、20以上を「長」とします。7、8、9、19、20、21の表示を順に答えてください。
- 1の規則で、0、30、-1、31、文字列「8」、欠落の表示を順に答えてください。文字列と欠落はエラーです。
- 植木の水量を0以上12以下の整数で受け、4未満を「少」、4以上9未満を「適」、9以上を「多」とします。低い側から判定するif、elif、elseの条件を順に答えてください。
- 3の規則で独立した
if x < 4とif x < 9を使い、それぞれ「少」と「適」を追加しました。xが3のときの実際の表示と、期待する表示を答え、原因を述べてください。 - 3の規則で、入力の取得が成功して値が9のとき、取得が時間切れのとき、壊れた文字列「九」のときの表示を順に答えてください。時間切れと文字列はエラーとします。
練習の答えと照合
-
「短」「中」「中」「中」「長」「長」です。7は8未満、8と9と19は8以上20未満、20と21は20以上です。各値を元の時間の区間に戻すと、境界の8は中、20は長に入ります。
-
「短」「長」「エラー」「エラー」「エラー」「エラー」です。0と30は両端を含む条件を満たします。-1と31は範囲の外、文字列と欠落は整数ではないため、いずれも時間の区間に入れません。時間切れも欠落と同じエラーにします。
-
型と範囲の検査後、
if x < 4、elif x < 9、elseです。2番目に進むのは4以上なので、9未満なら適です。最後は9以上12以下になり、元の3区間のいずれにも重複せず入ります。 -
実際は「少」と「適」の2個、期待は「少」1個です。3は両方の条件を満たし、独立したifが両方動くためです。後のifをelifに直し、さらに残りをelseにすれば、1つの経路で1個を返せます。
-
「多」「エラー」「エラー」です。9は多の区間の最初の値です。時間切れから数値を作ることはできず、文字列も整数という入力条件に合いません。失敗のときに以前の値を残して表示しないことも確かめます。
練習の数値は、区間の大小関係を別に列挙する単純な処理で照合しました。境界前後の6値と範囲端・範囲外の4値、重複する3と境界の9を元の条件に戻しています。型の不一致や取得失敗は数値比較へ渡さずエラーにするという仕様も確認しました。
覚えておくこと
境界値を含む側を決めて区間表にします。
ifとelifとelseの順序を区間表に対応させます。
直前・一致・直後と有効範囲の端を試します。
不正値や取得失敗も出力を決めて試します。
修正後は以前の正常例と失敗例を再実行します。
どこで迷ったかを確かめる
境界で誤る場合は、まず「以上」と「未満」を本人の言葉で読み替え、境界の値に印を付けます。条件式が正しく見えても重複する場合は、各ifが独立か、同じ組のelifかを処理表に書き分けます。入力がない場合に古い結果が残るなら、取得から表示まで、値が作られた箇所とエラーへ移る箇所を追います。
個別指導では、1つの値に対してどの条件が評価され、どこで処理が終わるかを口頭で説明してもらいます。続いて境界とその両隣、範囲外、型違い、読み取り失敗を本人が選び、期待値を実行前に書きます。表示を1個にする設計は、区間の境界を明確にするところから始まります。
読んで終わりにするか、ここから変えるか。
武蔵境駅徒歩30秒、講師1人に生徒1人の完全1対1。授業のあいだ、先生は隣を離れません。いまの詰まりを、無料相談でそのまま話してください。
まず15分だけ電話で話したい方は、無料電話相談(15分)から。塾からお電話を差し上げます。
本気になった日が、入塾の日。
お子様の教育、迷ったら「丸投げ」してください。必ず、期待以上の結果で返します。武蔵野で育む、武蔵境で学ぶ。
電話は年中無休。365日、24時間、お電話可能。




