And, or, not in Python: combine conditions into rules
Real rules are rarely one test. "Free shipping over $75, or for members." "A credit if you returned an item and spent $30." Three keywords cover all of it.
The big idea
and is true when both sides are true, or when at least one is, and not inverts a boolean.
See it in code
or needs only one side to be true. A member with a small order still ships free:
order_total = 50
free_shipping_min = 75
is_member = True
ships_free = order_total >= free_shipping_min or is_member
print("Ships free:", ships_free)Ships free: True
The first test was false (50 is under 75), but is_member was true, and one true side is enough for or.
and is stricter: both sides must hold. The recycling credit applies only to customers who returned an item and met the minimum:
credit_min = 30
returned_item = True
order_total = 90
print("Gets credit:", returned_item and order_total >= credit_min)
returned_item = True
order_total = 20
print("Gets credit:", returned_item and order_total >= credit_min)Gets credit: True Gets credit: False
Both customers returned an item. Only the first also spent at least $30, so only the first satisfies and.
not inverts a boolean, and the three operators combine. Without parentheses, not binds tightest, then and, then or:
order_total = 50
is_member = False
returned_item = False
free_shipping_min = 75
credit_min = 30
if not returned_item:
print("Tip: send back a worn-out item for $5 off your next order")
vip = is_member or order_total >= free_shipping_min and returned_item
print("VIP perks:", vip)Tip: send back a worn-out item for $5 off your next order VIP perks: False
The last rule reads as is_member or (order_total >= 75 and returned_item), because and is evaluated before or. Writing those parentheses yourself costs nothing and removes all doubt.
Python also short-circuits: in a and b, if a is false it never evaluates b. That lets you guard a risky check, like testing that a list isn't empty before reading its first item.
Try it yourself
Set is_member = True and re-run; vip flips to true whatever the other values are. Then rewrite the rule so a customer needs to be a member and have either a $75 order or a returned item.
The common mistake
Writing order_total == 40 or 75 and expecting it to test both. Python reads that as (order_total == 40) or 75, and 75 counts as true, so the whole thing is always true. Repeat the comparison: order_total == 40 or order_total == 75.
What it unlocks
Each side of a rule is a comparison, and the finished rule goes inside an if or keeps a while loop running.