Session 5 of the Python Fundamentals series, covered in depth. It builds precise conditions from the comparison operators and combines them with and, or, and not. It covers truth tables, the precedence order that runs from comparisons to not to and to or, range checks, and chained comparisons such as 0 < x < 10, then finishes with the famous x == 1 or 2 trap. Every snippet was copied verbatim from CPython 3.12.
Subject: Python Fundamentals · 95 slides · code lesson
Open the interactive version of this deck · Homework for this lesson
Title
Python Fundamentals - Session 5
and / or / not - conditions that combine several checks
Objectives
Last session picked a branch from one condition. Now we make the conditions themselves smarter. By the end you can:
and, or, and not.not, then and, then or.0 <= x <= 100.x == 1 or 2 and write x == 1 or x == 2 instead.Warm-up
Discussion prompt
Before we open Session 5 - Comparisons & Logic (and / or / not): without looking back, what was the main idea of Session 4 - Conditionals (if / elif / else), and what could you do by the end of it that you could not do before?
Hint: One sentence for the idea, one for the skill. If the second one is blank, that is the part to revisit.
Answer:
That session covers if, elif, and else, blocks and indentation, the rule that the first true branch wins, and the separate-ifs trap.
Section
Part 1
Concept
Every condition evaluates to a bool - True or False. That single value is what if acts on.
So building a good condition means building an expression that comes out True exactly when you want the branch to run.
Counterexample
Discussion prompt
Every condition evaluates to a bool - True or False. That single value is what if acts on.
That is stated as though it always holds. Do one of two things: produce a case where it fails, or say precisely what rules such a case out. "It just does" is not on the menu.
Hint: Hunt at the extremes first — zero, one, negative, empty, equal. If every extreme survives, the reason they survive is the proof.
Concept
== equal, != not equal, < less, > greater, <= at most, >= at least.
Each takes two values and returns a bool. These are the atoms every condition is built from.
Analogy
Discussion prompt
Explain The six comparisons by analogy to something with no Python Fundamentals in it at all — a queue, a recipe, a map, a bank balance, whatever fits. Then say where your analogy breaks.
Hint: An analogy that never breaks is not an analogy, it is the same idea wearing a hat. Find the seam — that is the part that is actually new.
Answer:
== equal, != not equal, < less, > greater, <= at most, >= at least.
Pattern
Predict first
The table runs: 5 == 5 | True · 5 != 3 | True · 6 <= 6 | True
In Comparisons produce bools, given the rows so far: what is the next one — the row where expression is 8 >= 10?
Correct: 8 >= 10 | False
| expression | value |
|---|---|
| 5 == 5 | True |
| 5 != 3 | True |
| 6 <= 6 | True |
| 8 >= 10 | False |
Why: The relationship between the columns, not the individual numbers, is what generates the next row. Just like arithmetic yields a number, a comparison yields a bool.
Worked example
print(5 == 5)
print(5 != 3)
print(6 <= 6)
print(8 >= 10)Each comparison yields True or False
Why: Just like arithmetic yields a number, a comparison yields a bool.
Read the output
Why: Verified by execution.
| expression | value |
|---|---|
| 5 == 5 | True |
| 5 != 3 | True |
| 6 <= 6 | True |
| 8 >= 10 | False |
Discrimination
Sort into buckets
Sort these by value, from memory, without looking back at Comparisons produce bools. Telling them apart on the spot is the skill; the table is only where the answer happens to be written down.
Intuition
Think of each comparison as a little light: on for True, off for False.
and, or, and not are wiring that combines those lights into one final on/off answer. This session is all about that wiring.
Explain it
Discussion prompt
Explain Bools are the fuel for logic to a student a year behind you. No notation, no jargon they have not met — and it still has to be true.
Hint: If your explanation needs a symbol they have never seen, you are describing the notation rather than the idea.
Answer:
Think of each comparison as a little light: on for True, off for False.
Section
Part 2
Concept
A and B is True only when both A and B are true. If either side is false, the whole thing is false.
Use it when several requirements must all be met at once.
Explain it to yourself
Discussion prompt
In A tournament gate this move is made:
Read the output
Why is that legal? Name the rule or definition it rests on before you read on.
Hint: If you can only say "because that is what you do", the rule is the thing to go and find.
Answer:
Verified by execution: prints You can enter. If either check failed, it would say Not eligible.
Worked example
age = 13
rank = 40
if age >= 12 and rank <= 50:
print("You can enter.")
else:
print("Not eligible.")Both checks must pass
Why: age >= 12 is True and rank <= 50 is True, so the whole condition is True.
Read the output
Why: Verified by execution: prints You can enter. If either check failed, it would say Not eligible.
| age >= 12 | rank <= 50 | and |
|---|---|---|
| True | True | True |
Error analysis
Annotate
Walk the callouts on A tournament gate. Each one is a place this is easy to get subtly wrong.
Concept
There are only four combinations, and only one gives True: both sides true.
Worked example
print(True and True)
print(True and False)
print(False and True)
print(False and False)Only the first line is True
Why: and needs both sides true; any False drags the result to False.
Read the output
Why: Verified by execution.
| A | B | A and B |
|---|---|---|
| True | True | True |
| True | False | False |
| False | True | False |
| False | False | False |
Comparison
Comparison matrix
From Every case of and: refill the B column from what you know. The rest of the table is as it appeared.
| A | B | A and B |
|---|---|---|
| True | True | True |
| True | False | False |
| False | True | False |
| False | False | False |
Anomaly
Predict first
A student writes this, and it looks reasonable:
Free shipping for members OR big orders, written with and. member is False, total is 200.
It is wrong. Say what breaks — and say it before you turn the page.
Correct: member is False, so the whole condition is False even though the $200 order should have earned free shipping.
'Either qualifies' is or, not and.
Why: member is False, so the whole condition is False even though the $200 order should have earned free shipping.
Trap
Free shipping for members OR big orders, written with and. member is False, total is 200.
if member and total >= 100:
print("Free shipping")and requires BOTH, so non-members never qualify
Why: member is False, so the whole condition is False even though the $200 order should have earned free shipping.
| member | total >= 100 | and | wanted |
|---|---|---|---|
| False | True | False | True |
'Either qualifies' is or, not and.
if member or total >= 100:
print("Free shipping")or is true when at least one holds
Why: The $200 order qualifies on its own. Real output: Free shipping. Match the word to the meaning: all-of = and, any-of = or.
| member | total >= 100 | or |
|---|---|---|
| False | True | True |
Break the constraint
Discussion prompt
The rule this trap just fixed:
The $200 order qualifies on its own. Real output: Free shipping. Match the word to the meaning: all-of = and, any-of = or.
Now break it on purpose. Build a case that violates it and follow the consequences until something visibly fails. Where does the failure first show up — and would you have noticed it if you had not been looking?
Hint: The dangerous rules are the ones whose violation still produces an answer. If yours fails loudly, try to find one that fails quietly.
Answer:
member is False, so the whole condition is False even though the $200 order should have earned free shipping.
Section
Part 3
Concept
A or B is True when at least one side is true. It is false only when both are false.
Use it when any one of several conditions is enough.
Fill the middle
Fill in the blanks
From Weekend or holiday — one line has had its right-hand side removed. Put it back.
is_weekend = False
is_holiday = True
if is_weekend or is_holiday:
print("Day off!")
else:
print("Work day.")
Why: is_holiday is what everything below it consumes, so the wrong expression here fails later and somewhere else. is_holiday is True, so the or is True regardless of is_weekend.
Worked example
is_weekend = False
is_holiday = True
if is_weekend or is_holiday:
print("Day off!")
else:
print("Work day.")Either one being true is enough
Why: is_holiday is True, so the or is True regardless of is_weekend.
Read the output
Why: Verified by execution: prints Day off!
| weekend | holiday | or |
|---|---|---|
| False | True | True |
Blank canvas
Draw it
Draw what Weekend or holiday just did — the shape of it, not the line-by-line working. One picture, labels only where you need them. Then check it against the steps: anything you could not draw is a step you followed rather than understood.
Concept
The mirror image of and: only one combination is False - when both sides are false.
Sorting
Sort into buckets
These are the pieces of Session 5 - Comparisons & Logic (and / or / not), out of order. Put each one back under the part of the lesson it belongs to.
Worked example
print(True or True)
print(True or False)
print(False or True)
print(False or False)Only the last line is False
Why: or needs just one true side; only all-false gives False.
Read the output
Why: Verified by execution.
| A | B | A or B |
|---|---|---|
| True | True | True |
| True | False | True |
| False | True | True |
| False | False | False |
Trade off
Comparison matrix
From Every case of or: every row here is a choice with a cost. Fill the A or B column, then say which row you would actually pick and what you give up for it.
| A | B | A or B |
|---|---|---|
| True | True | True |
| True | False | True |
| False | True | True |
| False | False | False |
Anomaly
Predict first
A student writes this, and it looks reasonable:
Requiring a password AND a code, but written with or. Only the password is right.
It is wrong. Say what breaks — and say it before you turn the page.
Correct: If either check passes, access is granted - so a right password with a wrong code still gets in.
'Both required' is and.
Why: If either check passes, access is granted - so a right password with a wrong code still gets in. That is a security hole.
Trap
Requiring a password AND a code, but written with or. Only the password is right.
if pw_ok or code_ok:
print("Access granted")or lets a single correct field in
Why: If either check passes, access is granted - so a right password with a wrong code still gets in. That is a security hole.
| pw_ok | code_ok | or | wanted |
|---|---|---|---|
| True | False | True | False |
'Both required' is and.
if pw_ok and code_ok:
print("Access granted")and demands every check pass
Why: Now a wrong code blocks access even with the right password. Real result: access denied unless both are correct.
| pw_ok | code_ok | and |
|---|---|---|
| True | False | False |
Section
Part 4
Concept
not A flips the bool: not True is False, not False is True.
It reads naturally: not done means 'not finished yet'.
Worked example
print(not True)
print(not False)
print(not (5 > 3))not reverses whatever follows it
Why: not True is False; not False is True; 5 > 3 is True, so not (5 > 3) is False.
Read the output
Why: Verified by execution.
| expression | value |
|---|---|
| not True | False |
| not False | True |
| not (5 > 3) | False |
Pattern
Step through it
Step through Flipping a bool one row at a time. What is driving the change, and what would the row after the last one be?
Concept
Wrap a condition in parentheses and negate it: not (0 <= x <= 5) is true when x is outside that range.
Handy for 'reject the invalid ones' checks.
Worked example
x = 7
print(not (0 <= x <= 5))Inner check first, then flip
Why: 0 <= 7 <= 5 is False, and not False is True - because 7 really is outside 0..5.
Read the output
Why: Verified by execution: True (it is out of range).
| 0 <= x <= 5 | not (...) |
|---|---|
| False | True |
Intuition
Picture not as a mirror held up to a light: on becomes off, off becomes on.
If a condition is hard to phrase positively ('the input is not empty'), phrasing it with not is often clearer than inventing the opposite comparison.
Section
Part 5
Concept
In 5 > 3 and 2 < 1, the comparisons happen first, then and combines their results.
So you rarely need parentheses around a single comparison - age >= 12 and rank <= 50 already groups the way you expect.
Worked example
print(5 > 3 and 2 < 1)Each comparison is computed
Why: 5 > 3 is True; 2 < 1 is False.
Then and combines them
Why: Verified by execution: True and False is False.
| 5 > 3 | 2 < 1 | and |
|---|---|---|
| True | False | False |
Concept
Among the logic words, not binds tightest, then and, then or (loosest).
So A or B and C means A or (B and C) - the and groups first. When in doubt, add parentheses.
Worked example
print(True or False and False)
print((True or False) and False)Line 1: and groups first
Why: False and False is False; then True or False is True.
Line 2: parentheses change the grouping
Why: Verified by execution: (True or False) is True, then and False is False. Same words, different answer.
| expression | value |
|---|---|
| True or False and False | True |
| (True or False) and False | False |
Anomaly
Predict first
A student writes this, and it looks reasonable:
Meaning '(admin or member) and active', but trusting precedence.
It is wrong. Say what breaks — and say it before you turn the page.
Correct: An admin gets in even when inactive - probably not what was intended.
Say exactly what you mean with parentheses.
Why: An admin gets in even when inactive - probably not what was intended. Precedence quietly changed the meaning.
Trap
Meaning '(admin or member) and active', but trusting precedence.
if is_admin or is_member and is_active:
grant()and groups first, so this is admin OR (member AND active)
Why: An admin gets in even when inactive - probably not what was intended. Precedence quietly changed the meaning.
| reads as |
|---|
| is_admin or (is_member and is_active) |
Say exactly what you mean with parentheses.
if (is_admin or is_member) and is_active:
grant()Parentheses make the grouping explicit
Why: Now everyone must be active. Parentheses cost nothing and remove all doubt about precedence.
| reads as |
|---|
| (is_admin or is_member) and is_active |
Section
Part 6
Concept
To test 'between', combine two comparisons: x >= 0 and x <= 100.
Both edges must hold, so and is exactly right for a range.
Worked example
x = 50
if x >= 0 and x <= 100:
print("valid")
else:
print("out of range")Both edges pass
Why: 50 >= 0 and 50 <= 100 are both True.
Read the output
Why: Verified by execution: prints valid. A value like 150 would fail the upper edge and print out of range.
| x | in 0..100? | prints |
|---|---|---|
| 50 | True | valid |
| 150 | False | out of range |
Concept
Python lets you chain: 0 < x < 10 means 0 < x and x < 10 - just like in math.
It is shorter and reads naturally, and Python evaluates x only once.
Worked example
x = 5
print(0 < x < 10)
print(0 < 15 < 10)0 < 5 < 10 holds
Why: 5 is above 0 and below 10, so True.
0 < 15 < 10 does not
Why: Verified by execution: 15 is above 0 but not below 10, so False.
| expression | value |
|---|---|
| 0 < 5 < 10 | True |
| 0 < 15 < 10 | False |
Comparison
Comparison matrix
From The math-style range: refill the value column from what you know. The rest of the table is as it appeared.
| expression | value |
|---|---|
| 0 < 5 < 10 | True |
| 0 < 15 < 10 | False |
Anomaly
Predict first
A student writes this, and it looks reasonable:
Trying to check 'x is 1 or 2'. x is 7.
It is wrong. Say what breaks — and say it before you turn the page.
Correct: x == 1 is False, but 2 on its own is truthy, so the whole condition is always True.
Repeat the variable on each side of or.
Why: x == 1 is False, but 2 on its own is truthy, so the whole condition is always True. It prints matched for every x - a silent, very common bug.
Trap
Trying to check 'x is 1 or 2'. x is 7.
x = 7
if x == 1 or 2:
print("matched")This reads as (x == 1) or (2)
Why: x == 1 is False, but 2 on its own is truthy, so the whole condition is always True. It prints matched for every x - a silent, very common bug.
| expression | value |
|---|---|
| x == 1 or 2 | 2 (truthy -> always matches) |
Repeat the variable on each side of or.
x = 7
if x == 1 or x == 2:
print("matched")Each side is a full comparison
Why: x == 1 is False and x == 2 is False, so nothing prints for 7 - correct. (Or use x in (1, 2), coming in later sessions.)
| x | x == 1 or x == 2 |
|---|---|
| 7 | False |
| 2 | True |
Two truths and a lie
Sort into buckets
Some of these hold up and some are the exact mistakes this lesson is built to prevent. Sort them.
bool - True or False. That single value is what if acts on.; == equal, != not equal, < less, > greater, <= at most, >= at least.; Think of each comparison as a little light: on for True, off for False.Concept
Every side of and/or must be a complete condition. x == 1 or x == 2, never x == 1 or 2.
Say the condition out loud - 'x equals one, or x equals two' - and write each 'x equals' fully.
Worked example
choice = 3
if choice == 1 or choice == 2 or choice == 3:
print("valid option")
else:
print("pick 1-3")Each option is a full comparison
Why: choice == 3 is True, so the or is True.
Read the output
Why: Verified by execution: prints valid option. Every branch repeats choice ==.
| choice | prints |
|---|---|
| 3 | valid option |
| 9 | pick 1-3 |
Intuition
Every and you add makes the condition harder to satisfy (fewer things pass). Every or makes it easier (more things pass).
If too much is getting through, you probably want and. If too little, you probably want or.
Faded example
Fill in the blanks
Combining with input: a login, with the scaffolding fading: two lines are gone now — fill both.
user = input("User: ")
pw = input("Password: ")
if user == "admin" and pw == "1234":
print("Welcome")
else:
print("Denied")
Why: Reproducing these unaided, rather than reading them, is what tells you the method has transferred. user == "admin" and pw == "1234" are both True, so access is granted.
Worked example
The user types admin, then 1234:
user = input("User: ")
pw = input("Password: ")
if user == "admin" and pw == "1234":
print("Welcome")
else:
print("Denied")Both must match
Why: user == "admin" and pw == "1234" are both True, so access is granted.
Read the output
Why: Verified by execution: prints Welcome. A wrong password fails the and and prints Denied.
| user | pw | and | prints |
|---|---|---|---|
| admin | 1234 | True | Welcome |
| admin | 0000 | False | Denied |
Section
Part 7
Concept
Chain as many ands (or ors) as you need: age >= 13 and grade >= 80 and consent.
With all and, every single part must hold. It reads as a checklist where nothing may be missed.
Pattern
Predict first
The table runs: age >= 13 | True · grade >= 80 | True
In An eligibility checklist, given the rows so far: what is the next one — the row where part is consent?
Correct: consent | True
| part | value |
|---|---|
| age >= 13 | True |
| grade >= 80 | True |
| consent | True |
Why: The relationship between the columns, not the individual numbers, is what generates the next row. age >= 13, grade >= 80, and consent are each True, so the and-chain is True.
Worked example
age = 16
grade = 90
consent = True
if age >= 13 and grade >= 80 and consent:
print("Eligible")
else:
print("Not eligible")All three parts must be true
Why: age >= 13, grade >= 80, and consent are each True, so the and-chain is True.
Read the output
Why: Verified by execution: prints Eligible. If any one part failed, it would print Not eligible.
| part | value |
|---|---|
| age >= 13 | True |
| grade >= 80 | True |
| consent | True |
Trade off
Comparison matrix
From An eligibility checklist: every row here is a choice with a cost. Fill the value column, then say which row you would actually pick and what you give up for it.
| part | value |
|---|---|
| age >= 13 | True |
| grade >= 80 | True |
| consent | True |
Concept
and stops at the first false part; or stops at the first true part. The rest is never evaluated.
This lets you put a safety check first: divisor != 0 and 10 / divisor > 1 never divides when divisor is 0.
Explain it
Discussion prompt
Explain Short-circuit: it stops early to a student a year behind you. No notation, no jargon they have not met — and it still has to be true.
Hint: If your explanation needs a symbol they have never seen, you are describing the notation rather than the idea.
Answer:
and stops at the first false part; or stops at the first true part. The rest is never evaluated.
Worked example
divisor = 0
print(divisor != 0 and 10 / divisor > 1)The first part is False, so and stops
Why: divisor != 0 is False, so Python never runs 10 / divisor - which would otherwise crash with a division by zero.
Read the output
Why: Verified by execution: prints False, with no error. Order the checks so the guard comes first.
| divisor != 0 | and result |
|---|---|
| False | False (second part skipped) |
Blank canvas
Draw it
Draw what A safe guard with and just did — the shape of it, not the line-by-line working. One picture, labels only where you need them. Then check it against the steps: anything you could not draw is a step you followed rather than understood.
Intuition
Because or stops at the first truthy value, name or "Guest" gives name if it has something, otherwise the fallback.
It is a tidy way to supply a default when a value might be empty.
Analogy
Discussion prompt
Explain or picks the first 'real' value by analogy to something with no Python Fundamentals in it at all — a queue, a recipe, a map, a bank balance, whatever fits. Then say where your analogy breaks.
Hint: An analogy that never breaks is not an analogy, it is the same idea wearing a hat. Find the seam — that is the part that is actually new.
Answer:
Because or stops at the first truthy value, name or "Guest" gives name if it has something, otherwise the fallback.
Fill the middle
Fill in the blanks
From A default with or — one line has had its right-hand side removed. Put it back.
name = ""
display = name or "Guest"
print(display)
Why: display is what everything below it consumes, so the wrong expression here fails later and somewhere else. name is "" (falsy), so or takes the next value, "Guest".
Worked example
name = ""
display = name or "Guest"
print(display)An empty string is falsy, so or moves on
Why: name is "" (falsy), so or takes the next value, "Guest".
Read the output
Why: Verified by execution: prints Guest. If name were "Sam", display would be "Sam".
| name | name or "Guest" |
|---|---|
| "" | "Guest" |
| "Sam" | "Sam" |
Comparison
Comparison matrix
From A default with or: refill the name or "Guest" column from what you know. The rest of the table is as it appeared.
| name | name or "Guest" |
|---|---|
| "" | "Guest" |
| "Sam" | "Sam" |
Concept
When a rule has an 'or' inside an 'and' (or vice versa), group with parentheses so the meaning is unmistakable.
(is_admin or is_owner) and is_active is clearer and safer than trusting precedence in your head.
Counterexample
Discussion prompt
When a rule has an 'or' inside an 'and' (or vice versa), group with parentheses so the meaning is unmistakable.
That is stated as though it always holds. Do one of two things: produce a case where it fails, or say precisely what rules such a case out. "It just does" is not on the menu.
Hint: Hunt at the extremes first — zero, one, negative, empty, equal. If every extreme survives, the reason they survive is the proof.
Answer:
(is_admin or is_owner) and is_active is clearer and safer than trusting precedence in your head.
Fill the middle
Fill in the blanks
From Grouped access rule — one line has had its right-hand side removed. Put it back.
is_admin = False
is_owner = True
is_active = True
if (is_admin or is_owner) and is_active:
print("Allowed")
else:
print("Blocked")
Why: is_owner is what everything below it consumes, so the wrong expression here fails later and somewhere else. (False or True) is True, and True and True is True.
Worked example
is_admin = False
is_owner = True
is_active = True
if (is_admin or is_owner) and is_active:
print("Allowed")
else:
print("Blocked")The or group decides 'privileged', then and requires active
Why: (False or True) is True, and True and True is True.
Read the output
Why: Verified by execution: prints Allowed. Drop the parentheses and precedence would change the meaning.
| (admin or owner) | and active | result |
|---|---|---|
| True | True | Allowed |
Error analysis
Annotate
Walk the callouts on Grouped access rule. Each one is a place this is easy to get subtly wrong.
Section
Part 8
Pattern
1. Write each check as a full comparison
Why: x == 1, score >= 60, name != "". Never leave a bare value like or 2.
2. Join with and (all required) or or (any is enough)
Why: and narrows, or widens. Match the word to the meaning.
3. Add parentheses when mixing and with or
Why: and binds tighter than or, so (A or B) and C needs its parentheses to mean what you say.
4. Use not or a range check to phrase the opposite
Why: not (0 <= x <= 100) is clearer than inventing x < 0 or x > 100.
Explain it to yourself
Discussion prompt
In and versus or, decided fast this move is made:
'All of these must be true' -> and
Why is that legal? Name the rule or definition it rests on before you read on.
Hint: If you can only say "because that is what you do", the rule is the thing to go and find.
Answer:
Every requirement chained with and; one failure blocks the whole thing.
Pattern
'All of these must be true' -> and
Why: Every requirement chained with and; one failure blocks the whole thing.
'Any of these is enough' -> or
Why: Options chained with or; one success passes the whole thing.
'Between A and B' -> A <= x <= B
Why: A chained comparison, which is and under the hood.
Real world
Discussion prompt
Outside this lesson: where does Session 5 - Comparisons & Logic (and / or / not) actually turn up? Name one concrete situation — a job, a piece of software someone ships, a decision somebody has to make — and say which part of and versus or, decided fast is doing the work in it.
Hint: Vague is the failure mode here. "Engineering" is not a situation; "deciding whether this build is fast enough to ship" is.
Answer:
Session 5 of the Python Fundamentals series, in depth. Building precise conditions: the comparison operators; combining them with and / or / not; truth tables; operator precedence (comparisons, then not, then and, then or); range checks and chained comparisons like 0 < x < 10; and the famous trap x == 1 or 2.
Check
Evaluate each side first.
print(5 > 2 and 3 > 9)| 5 > 2 | 3 > 9 |
|---|---|
| ? | ? |
Check your understanding
What does this print?
Answer: A
Why: 5 > 2 is True but 3 > 9 is False. and needs both true, so True and False is False. Verified by execution.
Check
Only one side needs to be true.
print(1 > 5 or 4 == 4)| 1 > 5 | 4 == 4 |
|---|---|
| ? | ? |
Check your understanding
What does this print?
Answer: A
Why: 1 > 5 is False, but 4 == 4 is True. or needs only one true side, so the result is True. Verified by execution.
Check
Compute inside first, then flip.
print(not (3 == 3))| 3 == 3 | not (...) |
|---|---|
| ? | ? |
Check your understanding
What does this print?
Answer: A
Why: 3 == 3 is True, and not flips it to False. Verified by execution.
Check
x is 8. Look closely at the condition.
x = 8
if x == 3 or 5:
print("hit")
else:
print("miss")| x == 3 | or 5 |
|---|---|
| False | 5 (truthy) |
Check your understanding
What does this print?
Answer: A
Why: This parses as (x == 3) or (5). x == 3 is False, but 5 alone is truthy, so the condition is always true - it prints hit even though x is not 3 or 5. The fix is x == 3 or x == 5. Verified by execution.
Check
Is 12 inside the range?
x = 12
print(0 <= x <= 10)| expression | value |
|---|---|
| 0 <= 12 <= 10 | ? |
Check your understanding
What does this print?
Answer: A
Why: The chain means 0 <= 12 and 12 <= 10. The first part holds, but 12 <= 10 is False, so the whole chain is False. Verified by execution.
Check
Which groups first, and or or?
print(False and True or True)| groups as | value |
|---|---|
| (False and True) or True | ? |
Check your understanding
What does this print?
Answer: A
Why: and binds tighter, so it is (False and True) or True. False and True is False, then False or True is True. Verified by execution.
Connect it up
Draw it
One page, no notation unless you need it: draw how these connect — Comparisons Recap · and: both must hold · or: at least one holds · not: flip it · Combining & Precedence · Ranges & The Big Trap. Put an arrow wherever one of them is what makes another possible, and label the arrow with why.
Recap
Combine comparisons with and (all true), or (any true), and not (flip). Precedence: comparisons, then not, then and, then or.
| You want | Write |
|---|---|
| all must hold | A and B |
| any is enough | A or B |
| the opposite | not A |
| between A and B | A <= x <= B |
| x is 1 or 2 | x == 1 or x == 2 |
Each side of and/or must be a full comparison - never x == 1 or 2. Next session we add loops, so a condition can be checked over and over.
Want this taught 1-on-1? Alexander tutors Python Fundamentals — $55/session, free consultation.