011. Booleans
Two-state logic gates for decisions
011. Booleans
Aryan’s RAM monitor is getting a “kill” feature: it can terminate a process if memory is critically high. But he wants safeguards — the kill should only proceed if ALL conditions are met:
- Memory usage is above the threshold (
used_percent >= 90) - The process is NOT system-critical (
not is_critical) - The user has confirmed the action (
user_confirmed)
He writes the condition with or instead of and, mixing up the operators from his C days (|| vs &&). The function now allows killing a process if ANY single condition is true — including killing critical processes whenever memory is high.
The wrong operator turns a safety gate into a security hole.
💡 Fun fact: In Python, True and False are actually subclasses of int — True == 1 and False == 0. This means True + True == 2 and sum([True, False, True]) == 2. Python inherited this from its early days when boolean types did not exist and 1/0 were used for true/false.
⚠️ Watch out: Confusing and with or is the single most dangerous boolean mistake in security-sensitive code. Using or where and is required makes conditions too permissive — any one condition being true is enough to open the gate.
🤔 Think about it: Python’s and and or do not always return True or False — "hello" or "world" returns "hello", and "" or "world" returns "world". How might this behaviour be useful, and when could it cause a surprise?
Learning objectives
- Use True/False boolean values
- Combine conditions with and, or, not
- Use parentheses to control operator precedence
Key concepts
- bool
- logical operators
- and or not
Try it
Concept detail
Python booleans are True and False (capital T and F — they are not strings). They are a subtype of int: True == 1, False == 0. This means True + True == 2, and bool values can be used in arithmetic.
Logical operators: and: both operands must be True → returns the first falsy value or the last value or: at least one must be True → returns the first truthy value or the last value not: inverts → not True == False
The broken_code bug: ‘age >= 18 or has_ticket or is_vip’ returns True as soon as any one condition is True. An adult without a ticket passes (age >= 18 is True). A child with a ticket also passes. The OR is too permissive.
Operator precedence: ‘not’ binds tighter than ‘and’, which binds tighter than ‘or’. ‘A or B and C’ means ‘A or (B and C)’. Use parentheses when mixing them to make intent explicit and avoid subtle precedence bugs.
Short-circuit evaluation: in ‘A and B’, if A is False, B is never evaluated. In ‘A or B’, if A is True, B is never evaluated. This matters for performance (avoid expensive B if A already determines the result) and for side effects.
Solution
def can_enter(age, has_ticket, is_vip):
return (age >= 18 and has_ticket) or is_vipTests
def test_adult_with_ticket():
assert can_enter(21, True, False) == True
def test_adult_no_ticket():
assert can_enter(21, False, False) == False
def test_minor_with_ticket():
assert can_enter(16, True, False) == False
def test_vip_no_ticket_minor():
assert can_enter(15, False, True) == True
def test_vip_overrides_all():
assert can_enter(10, False, True) == True
def test_nobody_qualifies():
assert can_enter(15, False, False) == False