024. Logical Operators
Compose boolean conditions with and/or/not
024. Logical Operators
RAM Manager — Kill Decision Logic
Aryan’s RAM manager has a should_kill(process) function that decides whether to terminate a process. The rules are:
- Auto-kill: RSS memory > 500 MB AND the process is marked as
killable - Safe to skip: The process name is
"system"OR it haspid == 1
He writes both functions, but swaps and for or in the auto-kill check. Now a process with 600 MB RSS is killed even if it is not marked killable (because or only needs one condition to be true). Critical system processes get killed.
The lesson:
andrequires both conditions;orrequires at least one. In security and resource management, usingorinstead ofandalmost always means you are too permissive — and the consequences can be severe.
💡 Fun fact: Python uses and, or, not as keywords rather than C’s &&, ||, !. Guido van Rossum chose English words to make code read like prose. Additionally, Python’s logical operators use short-circuit evaluation — False and expensive_call() never evaluates expensive_call(), which can be used deliberately to avoid unnecessary computation.
⚠️ Watch out: Replacing and with or in a multi-condition check is the classic security mistake — it makes your gate too permissive. A password validator that uses or instead of and will accept any string that has at least one good property, not all of them.
🤔 Think about it: not has higher precedence than and, which has higher precedence than or. So not a or b and c parses as (not a) or (b and c). How would you rewrite this expression with explicit parentheses to make the intended meaning unambiguous?
Learning objectives
- Use and for “all conditions must be true”
- Use or for “at least one condition must be true”
- Use not to invert a boolean
Key concepts
- logical operators
- and
- or
- not
Try it
Concept detail
Logical operators: and (all True), or (at least one True), not (invert). Short-circuit evaluation: ‘False and anything’ → False (skips right side). ‘True or anything’ → True (skips right side). Truth table: and needs both True; or needs at least one True. not True == False, not False == True, not 0 == True, not “” == True. All non-zero, non-empty objects are truthy in Python.
Solution
def is_valid_password(password):
has_length = len(password) >= 8
has_digit = any(c.isdigit() for c in password)
has_upper = any(c.isupper() for c in password)
return has_length and has_digit and has_upper
def is_locked_out(attempts, last_attempt_mins_ago):
return attempts >= 3 and last_attempt_mins_ago <= 30Tests
def test_valid_password():
assert is_valid_password("Secure123") == True
def test_too_short():
assert is_valid_password("Ab1") == False
def test_no_digit():
assert is_valid_password("SecurePass") == False
def test_no_upper():
assert is_valid_password("secure123") == False
def test_locked_out():
assert is_locked_out(3, 10) == True
def test_not_locked_few_attempts():
assert is_locked_out(2, 5) == False
def test_not_locked_old_attempt():
assert is_locked_out(5, 60) == False