Step 1 of 8 · Reading · ~4 min
Learn
Making Decisions
Combining Conditions
You already know and, or and not on their own. This lesson is about what happens when three or four of them meet in one expression: which operator binds tightest, where parentheses change the answer, and how to convince yourself a compound condition is right before you trust it.
Precedence: not, then and, then or
An expression without parentheses is not evaluated left to right. Python groups it for you, tightest operator first: not, then and, then or.
Same three values, two different answers. The first line is read as is_member or (is_guest_day and gym_open), which says "a member always gets in, open or not". The second says "the building has to be open for anybody". One of those is the rule you meant, and Python cannot tell which. Whenever and and or appear in the same expression, write the parentheses, even when they agree with the default grouping.
Checking a compound condition by hand
A condition over three inputs has eight possible combinations, and you can walk the interesting ones. Take can_enter = (gym_open and has_pass) or is_staff:
gym_open has_pass is_staff can_enter
True True False True
True False False False
False True False False
False False True True
The last row is the one to notice: staff get in with the building shut, because or is_staff sits outside the parentheses and overrides everything to its left. If that is wrong for your building, the fix is a different grouping, not a different operator. Walking three or four rows like this catches more bugs than re-reading the expression does.
Divisibility as a condition
% gives the remainder, so n % 5 == 0 reads "n divides evenly by 5", and n % 5 != 0 is its negation.
Write the negative form as n % 7 != 0. The shorter not n % 7 happens to work, because 0 is falsy, but it reads backwards and hides the comparison from whoever reads it next.
De Morgan's laws
Two identities let you move a not across a group:
not (A and B) is the same as (not A) or (not B)
not (A or B) is the same as (not A) and (not B)
So not (is_admin or is_owner) and not is_admin and not is_owner are the same test. Pick whichever reads closer to the sentence you would say out loud.
Chained comparisons
Python lets you write a range test the way maths does:
That is exactly 0 <= score and score < 100, except that score is evaluated once. Chains are excellent for ranges and confusing for anything else.
Common mistakes
- Testing the general rule and stopping there. A rule that has an exception needs both clauses. Keep only the general part and the answer is right for ordinary inputs and wrong for precisely the values the exception was written for.
- Losing the override. When a narrow case is meant to beat an exception, it belongs in its own group,
or-ed on at the top level. Bury it inside theandgroup and every value it exists for comes out on the wrong side. if n % 3 == 0 or 5:-ordoes not distribute over==. Python reads this as(n % 3 == 0) or 5, and5is truthy, so the condition is True for every input. Repeat the comparison:n % 3 == 0 or n % 5 == 0.- Grouping by accident.
(A or C) and Band(A and B) or Care built from the same three tests and disagree on real inputs. Write the parentheses you mean instead of trusting the default.
Your exercise
A year arrives on input, and the starter already prints leap or not leap from a variable named is_leap that is hard-coded to False. Your job is that one assignment: replace False with a single boolean expression over year that is True for exactly the leap years. The likeliest mistake is an override that gets swallowed by a group, so check a year like 2000 as well as an ordinary one before you submit.
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…