Skip to content

Tracing Logic by Hand

Instructions

  • Work in pairs or groups of 3–4 students
  • For each example:
    • Predict the output first (on paper) before running the code
    • Step through the code using Thonny's debugger as needed
    • Then expand the question below and discuss your answer

Code Snippets

Example 1

hat = "fedora"

if hat == "fedora":
    print("A")
else:
    print("B")

print("C")
Question

Exactly one of A and B is printed, but C is printed no matter what. How can you tell which lines belong to the if statement and which come after it?

Example 2

x = 10

if x < 100:
    print("A")
elif x < 50:
    print("B")
else:
    print("C")

print("D")
Question

x is less than 50, so why doesn't B print? Is there any value of x that makes this program print B?

Example 3

x = 10

if x < 100:
    print("A")
if x < 50:
    print("B")

print("C")
Question

This is Example 2 with elif changed to if, and it prints something different. Which values of x print two letters here, but only one in Example 2?

Example 4

x = 10
hat = "fez"

if x > 100 or hat == "fez":
    print("A")
    if x < 50:
        print("B")
    else:
        print("C")
else:
    print("D")
    if hat == "fedora":
        print("E")
print("F")
Question

x > 100 is False, so why does A print? Which if does each else belong to, and what would you change to make E print?

Example 5

x = 1.0
y = 0.0
b1 = x > 0 and y > 0
b2 = not x <= 0 or y <= 0
b3 = not (x <= 0 or y <= 0)
print(b1, b2, b3)
Question

b2 and b3 are built from the same two comparisons, but they don't agree. Where would you add parentheses to b2 to show the order Python actually uses?

Example 6

x = 0

if x != 0 and 10 / x > 1:
    print("A")
else:
    print("B")

if x == 0 or 10 / x > 1:
    print("C")
else:
    print("D")
Question

Neither condition crashes, even though x is zero. Why not? What happens if you swap the two sides of each and/or?

Example 7

x = 5
y = 10

print(x + 1 == y - 4)
print(0 < x < y)
print(x < y < 0)
print(not x == 5)
print(x < y == True)
Question

Add parentheses to each line to show the order Python uses. The last one surprises most people — which is why you should never write == True or == False.

Example 8

count = 0
name = ""
score = 0.0
text = "0"

if count:
    print("A")
if name:
    print("B")
if score:
    print("C")
if text:
    print("D")
if not count and not name:
    print("E")
Question

Sort the four variables into "truthy" and "falsy". What rule do the falsy ones follow, and why isn't text one of them?

Example 9

# Version 1
temp = 75

if temp > 60:
    print("Warm")
    if temp > 90:
        print("Hot")
    print("Enjoy!")
# Version 2
temp = 75

if temp > 60:
    print("Warm")
if temp > 90:
    print("Hot")
    print("Enjoy!")
Question

Only the indentation changed. Which lines belong to which if? Find a value of temp for which both versions print the same thing.

Example 10

score = 85
grade = "F"

if score >= 90:
    grade = "A"
if score >= 80:
    grade = "B"
if score >= 70:
    grade = "C"

print(grade)
Question

Track the value of grade after each if statement. Fix the code so that an 85 earns a B — in two different ways.

Bonus Questions

These topics won't be on the next quiz, but they're good to know!

Float error

if 0.1 + 0.1 + 0.1 == 0.3:
    print("yeah!")
else:
    print("nay.")
Question

Print 0.1 + 0.1 + 0.1 in the shell to see what Python actually computed. If == can't be trusted on floats, how should you compare two of them?

is operator

a = 1
b = 1.0

if a == b:
    print("A")
if a is b:
    print("B")
Question

a == b is True, but a is b is False. What is == comparing that is is not?

in operator

print("Bowl" in "Fez, Fedora, Bowler")
print("Feed" in "Fez, Fedora, Bowler")
Question

Every letter of "Feed" appears in the string, yet the answer is False. What exactly does in look for?

Comparing strings

print("Fez" == "fez")
print("Fez".lower() == "fez")
print("apple" < "banana")
print("Zebra" < "apple")
Question

Strings compare character by character. Why does "Zebra" come before "apple"?

and and or don't return booleans

print(0 or "fez")
print("fez" and "")
print(None or 0 or "hat")
Question

Each operator returns one of its operands, not True/False. Which one does it return, and why is that consistent with Example 8?

Conditional expressions

x = 7
label = "even" if x % 2 == 0 else "odd"
print(label)
Question

Rewrite this as a normal if/else statement. When is the one-line version easier to read?

De Morgan's laws

Rewrite each of these without using not, so that it always gives the same answer:

not (x > 0 and y > 0)
not (hat == "fez" or hat == "fedora")
Question

Check your answers by trying several values for x, y, and hat. What happens to and and or when you move the not inside the parentheses?