
武蔵野個別指導塾の特徴
高校情報I 複合条件—かつとまたはと否定の範囲を言葉と式で対応させる|武蔵野個別指導塾

参加を認めない条件の真偽表と安全な添字確認に役立つ複合条件です。
よくあるのは、高校生が「どちらでもない」という条件をorでつなぐ場面です。活動への参加を判断するとき、欠席予定でも準備不足でもない人を通したいのに、どちらか一方を満たせば通る式にしてしまいます。両方の事情を持つ人、一方だけの人、どちらも持たない人を並べると、言葉と式のずれが見えてきます。
どの形で条件を問われるか
複合条件は、複数の判定を組み合わせて1つの真偽値を作ります。たとえば「受付済みで、かつ欠席予定がない」を式にする問題では、それぞれの言葉がどの変数を指すかを決めてから、つなぎ方を選びます。答えは真偽値として返すのか、参加可否の文字を表示するのかも先に決めます。
別の形では、式を読んで通過する人を説明します。not (A or B) の否定がどこまでかかるのかを括弧で確認し、Aだけ、Bだけ、両方、どちらもない場合を言葉に戻します。さらに2つの式が同じ条件かを尋ねられたら、似た単語の並びだけで判断せず、入力の全組について結果を比べます。
ここでは参加を断る事情として欠席予定と準備不足を扱います。いずれも真偽値であり、事情があるときTrue、ないときFalseです。現実の参加判断を一般化する規則ではなく、検討するために自分で決めた条件です。数値の入力や外部サービスへの接続は必要ありません。
真偽値を組み合わせる
and は左右がともにTrueのときTrueです。or は少なくとも一方がTrueならTrueで、両方がTrueの場合も含みます。not はTrueをFalseに、FalseをTrueに反転します。「AでもBでもない」は、AがないこととBがないことの両方を要求します。したがって not A and not B と表せます。
図1のように、まずAまたはBがあるかをまとめ、その全体を否定する方法もあります。not (A or B) は、両方がないときだけTrueです。括弧を外して not A or B とすると、否定はAにしかかからず、Bがある場合は通過する可能性が生じます。括弧は見た目の飾りではなく、否定の対象を指定する道具です。

Pythonでは not、and、or の順に結びつきます。ただし優先順位の暗記に頼るより、意図したまとまりを括弧で明示すると読み手が確認しやすくなります。not (A and B) は両方がそろった状態を除くだけなので、一方だけがある人は残ります。not (A or B) とは異なります。
全組を確認するには、AとBをそれぞれFalse、Trueに変えます。2つの入力なら組は4通りです。表の各行でまずAとBを評価し、その結果に否定をかけます。式同士の結果が4行とも一致すれば、この2つの真偽値を入力とする条件として同値です。入力を別の意味や別の型に変更してよい、という意味ではありません。
基本例題:参加を認める条件
活動の準備を考えます。欠席予定をA、準備不足をBとし、いずれも真偽値で受け取ります。欠席予定も準備不足もない場合に参加可能とします。4組それぞれについて参加可能かをTrueまたはFalseで答え、2つの式が同じ結果を返すか調べてください。
図2ではTをTrue、FをFalseと表します。図2のように、まず除外の対象を A or B として求め、それを反転します。AとBが両方Falseの行では除外条件がFalseなので参加可能です。AだけTrue、BだけTrue、両方Trueの3行は少なくとも1つ事情があるため除外します。

cases = [(False, False), (False, True), (True, False), (True, True)]
for absent, unready in cases:
direct = not (absent or unready)
separate = (not absent) and (not unready)
print(absent, unready, direct, separate)
最初の行は入力の4組を格納します。次の行で1組ずつ取り出し、欠席予定と準備不足に割り当てます。3行目は除外条件全体を否定し、4行目は2つの事情をそれぞれ否定してから両方を要求します。最後の行は入力と2つの判定を順に表示します。4組を取り出し終えると反復は終わります。
Python 3.14.8での期待出力と実際の出力は次のとおりです。
False False True True
False True False False
True False False False
True True False False
手でも各行を元の条件へ戻せます。最初の行は欠席予定も準備不足もないので参加可能です。2行目は準備不足、3行目は欠席予定があるため参加不可です。4行目は両方の事情があり、やはり参加不可です。2つの出力列が全行で一致しており、この範囲では同値と確かめられます。全組を調べたことが根拠であって、たまたま1人の結果が一致したからではありません。
標準例題:受付済みという条件を加える
受付済みをRとし、先ほどのA、Bと同じ意味の真偽値を使います。受付済みで、欠席予定と準備不足のいずれもない場合に参加可能とします。R、A、BがすべてTrueの人と、RだけTrueの人について、参加可能かを真偽値で答えてください。また受付していない人についても考えます。
式は R and not (A or B) です。RだけTrueの場合、括弧内はFalseで、その否定はTrueです。受付済みの条件もTrueなので結果はTrueです。3つともTrueなら括弧内がTrueで、その否定はFalseですから参加不可です。RがFalseなら事情がなくても受付条件を満たさず、結果はFalseです。
cases = [(True, True, True), (True, False, False), (False, False, False)]
for registered, absent, unready in cases:
allowed = registered and not (absent or unready)
print(registered, absent, unready, allowed)
入力の組を準備し、各組を変数に受け取ります。次に受付済みと除外条件の否定を and で結び、最後に入力と結果を出力します。Python 3.14.8での期待出力と実際の出力は以下です。
True True True False
True False False True
False False False False
2行目の人は受付済みで両事情がないので参加可能という場面の規則を満たします。3行目は事情がないものの受付していません。ここをTrueにしてしまう式なら、除外事情の判定しか実装していないと気づけます。3つの入力に対して一般に同値か検討するときは、3例では足りず8組を比べます。
発展例題:範囲を守ってリストを見る
受付状況を先頭から並べたリスト flags に、参加者の受付済みならTrue、未受付ならFalseを入れます。整数の位置 i は0から始め、負の位置は使いません。位置が範囲内で、そこが受付済みならTrue、それ以外はFalseを返します。空のリストも受け付けます。要素は真偽値、位置は整数という前提です。
def registered_at(flags, i):
return 0 <= i and i < len(flags) and flags[i]
cases = [([True, False], 0), ([True, False], 1), ([True, False], 2), ([], 0), ([True], -1), ([True], 0)]
for flags, i in cases:
print(flags, i, registered_at(flags, i))
関数の1行目は入口を定めます。戻り値の式は左から、負でないこと、長さより小さいこと、指定位置の値を調べます。Pythonの and は左側がFalseなら右側を評価しません。したがって範囲外の場合は flags[i] に進まずFalseを返します。範囲内では最後の要素を読み、その真偽値を返します。入力一覧から各組を取り出して表示し、最後の組を処理すると反復が終わります。
Python 3.14.8での期待出力と実際の出力は次です。
[True, False] 0 True
[True, False] 1 False
[True, False] 2 False
[] 0 False
[True] -1 False
[True] 0 True
先頭のTrueは受付済み、位置1のFalseは範囲内ですが未受付です。位置2は長さ2のリストの範囲外、空のリストの位置0も範囲外です。負の位置はPythonでは別の意味を持ち得ますが、この問題の仕様では認めません。単一要素の位置0は有効です。これらの出力はいずれも位置と受付状況に戻して確認できます。
範囲確認の前に flags[i] を置くと、空リストや位置2で範囲外の参照による IndexError が起こります。整数以外の位置や真偽値以外の要素は前提外です。この関数は壊れた入力を検出する機能や外部の道具の呼出しを持ちません。前提外の値を受け付ける設計に変えるなら、型の検査とエラーの返し方を別に決める必要があります。
間違いを1行ずつ直す
参加可能を (not A) or (not B) とした誤答を考えます。AもBもFalseならTrueとなり、一見正しそうです。しかしAがFalse、BがTrueの人は、欠席予定がないという左側だけでTrueになります。準備不足の人を除くという条件に反します。
図3でもTはTrue、FはFalseです。図3のように、その行で左右の値を分けると原因が見えます。左はTrue、右はFalseで、orは一方がTrueならTrueです。修正はorをandに変えて両方の事情がないことを要求します。AだけTrueの場合も同じ誤りが現れます。両方Trueの場合は両式ともFalseなので、その行だけの試験では間違いを見落とします。

cases = [(False, False), (False, True), (True, False), (True, True)]
for a, b in cases:
wrong = (not a) or (not b)
fixed = (not a) and (not b)
print(a, b, wrong, fixed)
入力を1組ずつ取り出し、誤った式と修正した式の値を求めて表示します。Python 3.14.8で期待した再実行結果と実際の出力は一致しました。
False False True True
False True True False
True False True False
True True False False
修正後の列では、2行目と3行目も参加不可です。4行とも場面に戻し、どちらかの事情がある行を除けたことを確認します。誤答を直すときは、正しい例が引き続き通るかと、誤って通した例が除かれるかを両方調べます。
練習:条件を別の場面へ移す
次の5問はそれぞれ独立しています。真偽値はTrueかFalseで答え、言葉で答える箇所は対象となる状態を明示してください。
- 教室の照明が点灯中をL、窓が開いている状態をWとします。照明も窓も作動していない場合の式を、
notとandで書いてください。LがFalse、WがTrueのときの値も答えてください。 - 荷物が重い状態をH、壊れやすい状態をFとします。少なくとも一方に当てはまれば注意表示を出します。HとFが両方Trueのとき、
H or Fの値を答え、その理由を述べてください。 - 係の登録済みをR、休みをSとします。登録済みで休みでない人を選びます。
R and not Sとnot (R or S)は同じ条件ですか。RがTrue、SがFalseの組を使い、それぞれの真偽値を答えてください。 - リスト
[False, True, True]の位置は0から始まり、負の位置は認めません。0 <= i and i < len(flags) and flags[i]を使うとき、iが2、3、負の1の各場合に返る真偽値を答えてください。範囲外では添字を評価しないものとします。 - 雨をP、強風をQとします。屋外の作業を中止する条件が
P or Qのとき、作業を続けられる条件をnotを使った式で書いてください。PとQの4組でその値を順に示し、どの状態で続けられるか説明してください。組の順はFalseとFalse、FalseとTrue、TrueとFalse、TrueとTrueです。
練習の答えと照合
-
(not L) and (not W)です。LがFalseなら前半はTrue、WがTrueなら後半はFalseなので、結果はFalseです。窓が開いている以上、両方が作動していないという条件を満たしません。orを使うと照明が消えているだけでTrueとなり、窓の状態を見落とします。 -
Trueです。orは一方以上がTrueの場合を含むため、両方Trueでも注意表示が出ます。重く、かつ壊れやすい荷物を条件へ戻しても、注意表示の対象です。片方だけの場合に限る規則なら、別の式を設計する必要があります。
-
同じ条件ではありません。指定の組では
R and not SはTrue、not (R or S)はFalseです。登録済みで休みでない人は選ばれるべきなので、前者が場面の条件に合います。後者は登録済みであることまで否定しています。 -
順にTrue、False、Falseです。位置2は最後の要素でTrueです。位置3は長さ3以上なので範囲外、負の1も仕様上は範囲外です。後者の2つは受付状況のような要素の値にかかわらず、範囲条件がFalseになって添字の参照に進みません。
-
not (P or Q)です。順にTrue、False、False、Falseです。雨も強風もないときだけ続けます。雨だけ、強風だけ、両方の場合には中止条件が成立するので、続行の条件はFalseです。否定を括弧の内側の一方にだけかけると、元の中止条件の反対になりません。
次の検算は練習の入力をそのまま使います。p と q を切り替える部分は4組を順に調べ、組が尽きたら終了します。各表示は解答順です。Python 3.14.8における期待出力と実際の出力は一致しました。
l, w = False, True
print((not l) and (not w))
h, f = True, True
print(h or f)
r, s = True, False
print(r and not s, not (r or s))
flags = [False, True, True]
for i in [2, 3, -1]:
print(0 <= i and i < len(flags) and flags[i])
for p, q in [(False, False), (False, True), (True, False), (True, True)]:
print(not (p or q))
False
True
True False
True
False
False
True
False
False
False
各代入行は問題の状態を変数へ置き、print は該当する式の結果を表示します。位置の反復では範囲内かを先に調べ、天候の反復では中止条件をまとめて否定します。値を場面へ戻して、照明と窓、荷物、係、位置、天候の各条件に合うことも確認しました。
手元に残す要点
andは両方、orは少なくとも一方の成立を表します。- 「どちらでもない」は両方を否定してandで結ぶか、orの全体を否定します。
- 括弧で否定の範囲を示し、全入力の表で式を比較します。
- 添字の範囲を先に調べると、短絡評価で範囲外の参照を避けられます。
- 正常な場合と境界や失敗する場合の両方を、元の条件に戻して確かめます。
説明が止まったところを探す
式を見て言葉にできないときは、いきなり全体を読まず、変数がTrueとなる状態をそれぞれ説明してみてください。次に括弧内、否定後、最後の結合という順で途中の値を表に置きます。とくに両方Trueの行と、一方だけTrueの行を区別できるかを見ると、orの意味と否定の範囲を切り分けられます。
個別指導で確かめるなら、本人に「準備不足だけがある人」を指して、参加条件の各部分がどの値になるか説明してもらいます。答えが違えば、変数の意味、否定の位置、結合のいずれで変わったかを処理表でたどります。正しい行だけで終えず、誤答が紛れ込む行を自分で選べるかも確認します。条件式の確かさは、通す人と除く人の境目に表れます。
読んで終わりにするか、ここから変えるか。
武蔵境駅徒歩30秒、講師1人に生徒1人の完全1対1。授業のあいだ、先生は隣を離れません。いまの詰まりを、無料相談でそのまま話してください。
まず15分だけ電話で話したい方は、無料電話相談(15分)から。塾からお電話を差し上げます。
本気になった日が、入塾の日。
お子様の教育、迷ったら「丸投げ」してください。必ず、期待以上の結果で返します。武蔵野で育む、武蔵境で学ぶ。
電話は年中無休。365日、24時間、お電話可能。



