Unit 04 · lesson
Combining Conditions
Core path: 30 minutes
What happens when one fact is not enough to make the decision?
Real rules often depend on several pieces of state at once.
A robot may move only when the battery is healthy and no obstacle is detected.
A tournament may require a minimum level and completed training.
An administrator override may create a separate path entirely.
Python gives us and, or, and not to build those rules from smaller Boolean expressions.
and means every required condition must succeed
age = 15
skill_rating = 8
if age >= 13 and skill_rating >= 7:
print("Tournament unlocked.")
Break it into two questions:
age >= 13 ? True
skill_rating >= 7 ? True
Then combine:
True and True → True
If either part becomes false, the entire and expression becomes false.
This matches requirements containing language such as:
must satisfy both
requires X and Y
only when both conditions hold
or means at least one path is enough
role = input("Role: ").lower()
if role == "admin" or role == "moderator":
print("Access granted.")
The expression succeeds when either comparison is true.
admin? moderator? result
False False False
True False True
False True True
True True True
Do not choose or because it sounds less strict. Choose it when the requirement really means either condition is sufficient.
not reverses a Boolean result
game_over = False
if not game_over:
print("Keep playing.")
game_over is False.
not game_over becomes True.
This can read naturally when a Boolean variable already describes a state:
obstacle_detected = False
if not obstacle_detected:
print("Path clear")
Use names that make the logic readable. not x tells another developer almost nothing if x has no meaningful name.
Robot safety: translate the policy before writing the code
Requirement:
The robot may continue only when battery is above 20 percent and no obstacle is detected.
Translate the parts:
battery above 20 → battery_level > 20
no obstacle detected → not obstacle_detected
both required → and
Then:
battery_level = 18
obstacle_detected = False
if battery_level > 20 and not obstacle_detected:
print("Robot can continue.")
else:
print("Robot should stop.")
With battery 18, the robot stops even though the path is clear.
That is not a contradiction. The policy requires both safe conditions.
Parentheses can expose the intended grouping
Suppose ranked mode is available when:
the player is level 10+ and completed training, or the player is an administrator.
Write the human grouping first:
(level requirement AND training complete)
OR
administrator override
Then:
if (level >= 10 and training_complete) or is_admin:
print("Ranked mode unlocked.")
Parentheses make the policy easier to inspect even when Python's operator precedence would already define an evaluation order.
Readable logic is easier to review than clever logic.
and versus or can change a security rule completely
Suppose a rule says:
Access requires the admin role and the correct access code.
Correct shape:
role == "admin" and code == "A1337"
Accidentally use or:
role == "admin" or code == "A1337"
Now a non-admin with the correct code passes, and an admin with the wrong code also passes.
Run the same four Boolean states under both policies:
Run the code to see output.
Compare the same four states under and versus or. Use the matrix to explain exactly which unauthorized cases become True when a two-factor requirement is accidentally written with or.
The syntax is valid. The policy is broken.
That is why logical operators deserve requirement-level attention.
Impossible conditions reveal contradictory rules
age = 15
if age < 13 and age > 18:
print("Teenager")
For the branch to run, one value would have to be both below 13 and above 18 at the same time.
No input can satisfy it.
The branch is unreachable under that condition.
When a branch never runs, do not assume Python skipped it randomly. Ask whether the Boolean expression can ever become true.
Truthiness is useful, but know what you are asking
Python can interpret certain non-Boolean values in a Boolean context.
username = "admin"
if username:
print("Username exists")
A non-empty string is truthy. An empty string is falsy.
So this asks:
Does
usernamecontain a non-empty value?
It does not ask:
Is this username authorized?
Those are completely different claims.
Do not let convenient syntax blur the requirement.
Build a truth table before coding
Requirement:
A student can enter the lab when they completed safety training and the instructor enabled lab access, or when the instructor has explicitly granted an override.
Define:
training_complete = True
lab_enabled = False
override = False
Expression:
(training_complete and lab_enabled) or override
Test several states on paper before running:
| Training | Lab enabled | Override | Expected |
|---|---|---|---|
| False | False | False | False |
| True | False | False | False |
| True | True | False | True |
| False | False | True | True |
Then run the same cases.
The table is not busywork. It exposes what the rule actually permits.
Before Lesson 4
When you design a compound decision, be able to answer:
- What are the smaller Boolean questions?
- Does the requirement need all of them or only one?
- Is any condition being negated?
- Which parts should be grouped together?
- Can the condition ever be true?
- Does a truthy shortcut mean the same thing as the actual requirement?
Lesson 4 combines these ideas into access-control rules. Lesson 5 attacks the exact boundaries and operator choices where those rules usually fail.
Vocabulary lab
Flip the idea, not just the card
Explain the term before you reveal the back. Then compare your explanation with the definition, example, and warning.
Read all terms without animation
- Logical Operator
- An operator that combines or modifies Boolean expressions. Example: and, or, and not. Do not confuse it with: A comparison operator such as == or >= that creates a Boolean result from values.
- Compound Condition
- A Boolean expression built from multiple smaller conditions. Example: battery > 20 and not obstacle_detected. Do not confuse it with: One comparison such as battery > 20.
- Unreachable Branch
- A branch whose condition cannot become true under the possible program states. Example: age < 13 and age > 18 for one numeric age value. Do not confuse it with: A branch that simply was not selected for one particular input.
- Truthiness
- Python's Boolean interpretation of values that are not literally True or False. Example: A non-empty string is truthy and an empty string is falsy. Do not confuse it with: A proof that the string contains valid or authorized data.
- Truth Table
- A table showing how combinations of Boolean inputs produce an output. Example: Testing all combinations of two required conditions. Do not confuse it with: A list of random test inputs with no relationship to the rule.