Session 5 - Comparisons & Logic (and / or / not)

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

What this lesson covers

The lesson, slide by slide

1. Comparisons & Logic

Title

Python Fundamentals - Session 5

and / or / not - conditions that combine several checks

2. What you will be able to do

Objectives

Last session picked a branch from one condition. Now we make the conditions themselves smarter. By the end you can:

  1. Build conditions with all six comparison operators.
  2. Combine checks with and, or, and not.
  3. Read a truth table and predict the result of any combination.
  1. Apply precedence: comparisons, then not, then and, then or.
  2. Write range checks like 0 <= x <= 100.
  3. Avoid the trap x == 1 or 2 and write x == 1 or x == 2 instead.

3. What survived from Session 4 - Conditionals (if / elif / else)?

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.

4. Comparisons Recap

Section

Part 1

5. A condition is a yes/no question

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.

6. Break it if you can: A condition is a yes/no question

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.

7. The six comparisons

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.

8. By analogy: The six comparisons

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.

9. Predict the next row: Comparisons produce bools

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

expressionvalue
5 == 5True
5 != 3True
6 <= 6True
8 >= 10False

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.

10. Comparisons produce bools

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.

expressionvalue
5 == 5True
5 != 3True
6 <= 6True
8 >= 10False

11. Which is which, by value

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.

True
5 == 5; 5 != 3; 6 <= 6
False
8 >= 10
g1
value is "True" for 5 == 5, 5 != 3, 6 <= 6 — that is what the table on "Comparisons produce bools" records, and it is the single property separating this group from the rest.
g2
value is "False" for 8 >= 10 — that is what the table on "Comparisons produce bools" records, and it is the single property separating this group from the rest.

12. Bools are the fuel for logic

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.

13. Teach it back: Bools are the fuel for logic

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.

14. and: both must hold

Section

Part 2

15. and: true only when both are true

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.

16. Why is this step legal: Read the output

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.

17. A tournament gate

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 >= 12rank <= 50and
TrueTrueTrue

18. Inspect it line by line: A tournament gate

Error analysis

Annotate

Walk the callouts on A tournament gate. Each one is a place this is easy to get subtly wrong.

  • age >= 12 is True and rank <= 50 is True, so the whole condition is True.
  • Verified by execution: prints You can enter. If either check failed, it would say Not eligible.

19. The and truth table

Concept

There are only four combinations, and only one gives True: both sides true.

20. Every case of and

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.

ABA and B
TrueTrueTrue
TrueFalseFalse
FalseTrueFalse
FalseFalseFalse

21. Fill in: B for Every case of and

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.

ABA and B
TrueTrueTrue
TrueFalseFalse
FalseTrueFalse
FalseFalseFalse

22. Something is wrong here: and where you meant or

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.

23. Trap: and where you meant or

Trap

The 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.

membertotal >= 100andwanted
FalseTrueFalseTrue

The fix

'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.

membertotal >= 100or
FalseTrueTrue

24. Break it on purpose: and where you meant or

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.

25. or: at least one holds

Section

Part 3

26. or: true when either side is true

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.

27. Restore the missing line: Weekend or holiday

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.

28. Weekend or holiday

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!

weekendholidayor
FalseTrueTrue

29. Draw the shape of it: Weekend or holiday

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.

30. The or truth table

Concept

The mirror image of and: only one combination is False - when both sides are false.

31. Where does each piece belong: Session 5 - Comparisons & Logic (and / or /…

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.

Comparisons Recap
A condition is a yes/no question; The six comparisons; Comparisons produce bools
and: both must hold
and: true only when both are true; A tournament gate; The and truth table
or: at least one holds
or: true when either side is true; Weekend or holiday; The or truth table
s1
Comparisons Recap is where Session 5 - Comparisons & Logic (and / or / not) puts A condition is a yes/no question, The six comparisons, Comparisons produce bools. Knowing which part of the lesson a problem belongs to is most of knowing which method to reach for.
s2
and: both must hold is where Session 5 - Comparisons & Logic (and / or / not) puts and: true only when both are true, A tournament gate, The and truth table. Knowing which part of the lesson a problem belongs to is most of knowing which method to reach for.
s3
or: at least one holds is where Session 5 - Comparisons & Logic (and / or / not) puts or: true when either side is true, Weekend or holiday, The or truth table. Knowing which part of the lesson a problem belongs to is most of knowing which method to reach for.

32. Every case of or

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.

ABA or B
TrueTrueTrue
TrueFalseTrue
FalseTrueTrue
FalseFalseFalse

33. What each one costs: Every case of or

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.

ABA or B
TrueTrueTrue
TrueFalseTrue
FalseTrueTrue
FalseFalseFalse

34. Something is wrong here: or where you meant and

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.

35. Trap: or where you meant and

Trap

The 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_okcode_okorwanted
TrueFalseTrueFalse

The fix

'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_okcode_okand
TrueFalseFalse

36. not: flip it

Section

Part 4

37. not: the opposite

Concept

not A flips the bool: not True is False, not False is True.

It reads naturally: not done means 'not finished yet'.

38. Flipping a bool

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.

expressionvalue
not TrueFalse
not FalseTrue
not (5 > 3)False

39. Watch it run: Flipping a bool

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?

  1. Step 1: expression is not True
  2. Step 2: expression is not False
  3. Step 3: expression is not (5 > 3)

40. not around a whole condition

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.

41. Outside the range

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 <= 5not (...)
FalseTrue

42. not is a mirror

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.

43. Combining & Precedence

Section

Part 5

44. Comparisons run before and/or

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.

45. Comparisons first

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 > 32 < 1and
TrueFalseFalse

46. not, then and, then or

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.

47. and binds tighter than or

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.

expressionvalue
True or False and FalseTrue
(True or False) and FalseFalse

48. Something is wrong here: relying on precedence you misremember

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.

49. Trap: relying on precedence you misremember

Trap

The 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)

The fix

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

50. Ranges & The Big Trap

Section

Part 6

51. Range check with and

Concept

To test 'between', combine two comparisons: x >= 0 and x <= 100.

Both edges must hold, so and is exactly right for a range.

52. A valid percentage

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.

xin 0..100?prints
50Truevalid
150Falseout of range

53. Chained comparisons

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.

54. The math-style range

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.

expressionvalue
0 < 5 < 10True
0 < 15 < 10False

55. Fill in: value for The math-style range

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.

expressionvalue
0 < 5 < 10True
0 < 15 < 10False

56. Something is wrong here: x == 1 or 2

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.

57. Trap: x == 1 or 2

Trap

The 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.

expressionvalue
x == 1 or 22 (truthy -> always matches)

The fix

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.)

xx == 1 or x == 2
7False
2True

58. Which of these survive contact with Session 5 - Comparisons & Logic (and / or /…?

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.

Holds up
Every condition evaluates to a 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.
Breaks
Free shipping for members OR big orders, written with and. member is False, total is 200.; Requiring a password AND a code, but written with or. Only the password is right.
sound
These are stated as this lesson states them — each one survives the edge cases Session 5 - Comparisons & Logic (and / or / not) puts it through.
flawed
Each of these is lifted from a trap in this deck: reasonable-sounding, and wrong in a way that only shows up once you rely on it.

59. Always compare the variable each time

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.

60. A menu choice check

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 ==.

choiceprints
3valid option
9pick 1-3

61. and narrows, or widens

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.

62. Finish it with less help: Combining with input: a login

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.

63. Combining with input: a login

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.

userpwandprints
admin1234TrueWelcome
admin0000FalseDenied

64. Logic in Practice

Section

Part 7

65. Three or more conditions

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.

66. Predict the next row: An eligibility checklist

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

partvalue
age >= 13True
grade >= 80True
consentTrue

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.

67. An eligibility checklist

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.

partvalue
age >= 13True
grade >= 80True
consentTrue

68. What each one costs: An eligibility checklist

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.

partvalue
age >= 13True
grade >= 80True
consentTrue

69. Short-circuit: it stops early

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.

70. Teach it back: Short-circuit: it stops early

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.

71. A safe guard with and

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 != 0and result
FalseFalse (second part skipped)

72. Draw the shape of it: A safe guard with and

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.

73. or picks the first 'real' value

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.

74. By analogy: or picks the first 'real' value

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.

75. Restore the missing line: A default with or

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".

76. A default with or

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".

namename or "Guest"
"""Guest"
"Sam""Sam"

77. Fill in: name or "Guest" for A default with or

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.

namename or "Guest"
"""Guest"
"Sam""Sam"

78. Mixing and with or, carefully

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.

79. Break it if you can: Mixing and with or, carefully

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.

80. Restore the missing line: Grouped access rule

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.

81. Grouped access rule

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 activeresult
TrueTrueAllowed

82. Inspect it line by line: Grouped access rule

Error analysis

Annotate

Walk the callouts on Grouped access rule. Each one is a place this is easy to get subtly wrong.

  • (False or True) is True, and True and True is True.
  • Verified by execution: prints Allowed. Drop the parentheses and precedence would change the meaning.

83. Patterns & Checks

Section

Part 8

84. Writing a compound condition

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.

85. Why is this step legal: 'All of these must be true' -> and

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.

86. and versus or, decided fast

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.

87. Where this shows up: Session 5 - Comparisons & Logic (and / or / not)

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.

88. Check: and result

Check

Evaluate each side first.

print(5 > 2 and 3 > 9)
5 > 23 > 9
??

Check your understanding

What does this print?

  • A. False (correct)
  • B. True
  • C. 5
  • D. Error

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.

Why B tempts people
and requires both sides true; the second comparison (3 > 9) is false.
Why C tempts people
and returns a bool here, not a number. Both operands are comparisons.
Why D tempts people
Combining two bools with and is valid - no error.

89. Check: or result

Check

Only one side needs to be true.

print(1 > 5 or 4 == 4)
1 > 54 == 4
??

Check your understanding

What does this print?

  • A. True (correct)
  • B. False
  • C. 4
  • D. Error

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.

Why B tempts people
or is false only when BOTH sides are false; here the second side is true.
Why C tempts people
or returns a bool, not the number 4.
Why D tempts people
Two bool comparisons joined by or is valid.

90. Check: not

Check

Compute inside first, then flip.

print(not (3 == 3))
3 == 3not (...)
??

Check your understanding

What does this print?

  • A. False (correct)
  • B. True
  • C. 3
  • D. not True

Answer: A

Why: 3 == 3 is True, and not flips it to False. Verified by execution.

Why B tempts people
not reverses True to False; it does not leave it True.
Why C tempts people
not returns a bool, not the number 3.
Why D tempts people
not True is computed to a bool (False); it is not left as text.

91. Check: the big trap

Check

x is 8. Look closely at the condition.

x = 8
if x == 3 or 5:
    print("hit")
else:
    print("miss")
x == 3or 5
False5 (truthy)

Check your understanding

What does this print?

  • A. hit (correct)
  • B. miss
  • C. Error
  • D. 5

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.

Why B tempts people
It would say miss only if the condition were false, but the bare 5 forces it true every time.
Why C tempts people
or 5 is valid Python (5 is truthy), so there is no error - just a logic bug.
Why D tempts people
The if does not print the 5; it evaluates the condition as true and runs the hit branch.

92. Check: range

Check

Is 12 inside the range?

x = 12
print(0 <= x <= 10)
expressionvalue
0 <= 12 <= 10?

Check your understanding

What does this print?

  • A. False (correct)
  • B. True
  • C. 12
  • D. Error

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.

Why B tempts people
12 is above 10, so it fails the upper edge; the chain is not True.
Why C tempts people
A chained comparison returns a bool, not the value of x.
Why D tempts people
Chained comparisons like 0 <= x <= 10 are valid Python.

93. Check: precedence

Check

Which groups first, and or or?

print(False and True or True)
groups asvalue
(False and True) or True?

Check your understanding

What does this print?

  • A. True (correct)
  • B. False
  • C. Error
  • D. None

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.

Why B tempts people
The trailing or True rescues it: even after False and True is False, or True makes the whole thing True.
Why C tempts people
Chaining and/or is valid, so there is no error.
Why D tempts people
Boolean operators return a bool value here, not None.

94. Connect it up: Session 5 - Comparisons & Logic (and / or / not)

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.

95. What you can do now

Recap

Combine comparisons with and (all true), or (any true), and not (flip). Precedence: comparisons, then not, then and, then or.

You wantWrite
all must holdA and B
any is enoughA or B
the oppositenot A
between A and BA <= x <= B
x is 1 or 2x == 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.

Sources

  1. Python 3 Tutorial - Boolean operations and Comparisons
  2. Python 3 Reference - Comparisons (chaining)
  3. All snippets executed and copied from CPython 3.12. — Author verification run, 2026-07-15 (Python Fundamentals series, Session 5).

Want this taught 1-on-1? Alexander tutors Python Fundamentals — $55/session, free consultation.

Book on Wyzant · Text (657) 465-8108