NoSingleLogicAndObserved

& is only a bitwise AND
& for boolean operands is a logical AND
CorrectionHere is what's right.
While & can be a bitwise AND, & can also be used as a logical AND between bool operands.
That’s because in Python, booleans are actually integers: False is 0, and True is 1.
a = False
b = True
c = a and b # logical AND (short-circuit)a = False
b = True
c = a & b # logical ANDa = 1
b = 3
c = a & b # bitwise ANDNote that & is an eager logical AND. “Eager” means it always evaluates both operands before producing a value.
On the other hand, and is a short-circuit logical AND. It first evaluates the left operand; if that is False, then it does not evaluate the right operand and simply produces False. This can be very useful for conditions like the following, because it prevents ZeroDivisionError that would have been raised if the right operand had to be evaluated:
if lst != [] and sum(lst) / len(lst) > 42:
...SymptomsHow do you know your students might have this misconception?
If students claim that & is a bitwise AND, and and is a logical AND, then they probably also believe that & cannot work with bool operands.
ValueHow can you build on this misconception?
It can be instructive to think about a situation where the difference between & and and is observable. Consider the following example:
def f():
print("hi")
return FalseEvaluating f() and f() will print “hi” only once, because the second call to f() is not evaluated due to short-circuiting.
On the other hand, evaluating f() & f() will print “hi” twice, because both calls to f() are evaluated regardless of the result of the first call.