In Python, what does `False and some_function()` evaluate to, assuming Python uses short-circuit evaluation?
AThe return value of some_function(), because AND always evaluates both operands to determine the result
BFalse, and some_function() is never called
CTrue, because short-circuit evaluation optimizes compound expressions to True when possible
DAn error, because False cannot be the first operand in an AND expression
With AND short-circuit evaluation: if the first operand is False, the overall result must be False regardless of the second operand, so the second operand is never evaluated. This means some_function() is never called. This has practical consequences: if some_function() has side effects or could raise an error, short-circuit evaluation silently prevents them. The classic guard pattern `if x is not None and x.value > 0` relies on this — when x is None, the right side is skipped entirely.
Question 2 Multiple Choice
Which expression is equivalent to `a OR b AND c`, following standard operator precedence?
A`(a OR b) AND c`
B`a OR (b AND c)`
C`(a AND c) OR b`
D`NOT(NOT a AND NOT b) AND c`
AND binds more tightly than OR, just as multiplication binds more tightly than addition in arithmetic. So `a OR b AND c` is parsed as `a OR (b AND c)`. The difference matters: if a=True, b=False, c=False, then `a OR (b AND c)` = True OR False = True, but `(a OR b) AND c` = True AND False = False. When combining multiple logical operators, use parentheses to make intent explicit and avoid precedence surprises.
Question 3 True / False
The boolean expression NOT (x AND y) is logically equivalent to (NOT x) AND (NOT y).
TTrue
FFalse
Answer: False
This is a common misapplication of De Morgan's laws. NOT (x AND y) is equivalent to (NOT x) OR (NOT y) — you flip AND to OR when distributing NOT across the expression. To verify: if x=True and y=False, then NOT (True AND False) = NOT False = True; but (NOT True) AND (NOT False) = False AND True = False. De Morgan's other law: NOT (x OR y) = (NOT x) AND (NOT y). Many bugs in complex conditions come from incorrectly negating compound expressions.
Question 4 True / False
In Python, the expression `len(lst) > 0 and lst[0] == target` is safe to use when lst might be empty, because short-circuit evaluation prevents accessing lst[0] when the list is empty.
TTrue
FFalse
Answer: True
When lst is empty, `len(lst) > 0` evaluates to False. Due to AND short-circuit evaluation, the second operand `lst[0] == target` is never evaluated — Python skips it entirely. If it were evaluated on an empty list, it would raise an IndexError. This guard pattern (check safety condition first, then access) is idiomatic in many languages and depends specifically on short-circuit evaluation being guaranteed. In a hypothetical language that always evaluated both operands, this pattern would not be safe.
Question 5 Short Answer
Explain how short-circuit evaluation in AND makes the pattern `if collection is not empty and collection[0] == value` safe to use without a separate nested check.
Think about your answer, then reveal below.
Model answer: With AND short-circuit evaluation, if the first operand evaluates to False, the second operand is never evaluated at all. When the collection is empty, the first condition (not empty) is False, AND short-circuits, and the index access in the second condition is never reached. This prevents the index-out-of-bounds error that would occur if the interpreter always evaluated both operands.
Short-circuit evaluation transforms what would otherwise require nested if statements into a single compound condition. Without it, you would need: `if len(lst) > 0:` then `if lst[0] == value:`. With it, `len(lst) > 0 and lst[0] == value` is both safe and readable. The same logic applies to null checks: `if x is not None and x.attribute > 0` ensures the attribute access only happens on non-None objects. This pattern is so common that languages without short-circuit evaluation must provide other mechanisms (like the null-conditional operator) to achieve the same safety.