Skip to content

Unit 2 Review Questions

Quiz 2 is done on a computer, and its focus is writing and testing working code — not just tracing it by hand. These review questions follow that lead: most ask you to write a function or statement from a description, with just enough tracing mixed in to confirm you understand why code behaves the way it does. Questions are grouped by learning objective (Weeks 4-5).

Week 4: tracing and writing conditionals

1. Write a function named froyo_cost that takes a cup size (the string "small", "medium", or "large") and the ounces of frozen yogurt and toppings weighed on the scale, and returns the total cost using these rules:

  • Each size has a flat base fee: "small" is $3.00, "medium" is $4.50, and "large" is $6.00.
  • Every size includes up to 8 oz. Any amount over 8 oz costs an extra $0.50 per ounce, on top of the base fee.

For example, froyo_cost("medium", 6) returns 4.5, and froyo_cost("medium", 10) returns 5.5 (the $4.50 base plus $0.50 for each of the 2 extra ounces).

def froyo_cost(size, ounces):
    if size == "small":
        base = 3.0
    elif size == "medium":
        base = 4.5
    else:
        base = 6.0

    if ounces > 8:
        base += (ounces - 8) * 0.5

    return base

2. A student wants this code to print "A" for a score of 95, but it prints "D" instead. What is printed, and why doesn't it produce the grade they expected?

score = 95
if score >= 60:
    grade = "D"
elif score >= 70:
    grade = "C"
elif score >= 90:
    grade = "A"
else:
    grade = "F"
print(grade)

  D is printed. Python checks elif branches top to bottom and stops at the first True condition. Since score >= 60 is already true, the later, more specific conditions are never reached. The branches need to be ordered from most restrictive (>= 90) to least restrictive (>= 60).

Week 4: predicting boolean expressions

1. What is printed, and what does result end up holding?

def check(msg, value):
    print(msg)
    return value

result = check("first", False) and check("second", True)

  Only first is printed. Because and short-circuits, once the left side (False) is known to make the whole expression False, Python never calls check("second", True). result is False.

2. Write a function named valid_password that takes a string pw and returns True if it is at least 8 characters long and is not equal to "password" (ignoring case), and False otherwise. Use a boolean expression built from and/or/not and comparison operators — no loops.

For example, valid_password("abc") returns False (too short), valid_password("PASSWORD") returns False (the banned word, regardless of case), and valid_password("hunter22") returns True.

def valid_password(pw):
    return len(pw) >= 8 and pw.lower() != "password"

3. Assuming a = 10, what is the value of not a > 15?

  True — a > 15 is False (comparisons run before not), so not False is True.

Week 4: truthy and falsy values

1. What is printed by each if statement below?

username = ""
age = 0
guest_list = ["Sam"]

if username:
    print("Has username")
else:
    print("No username")

if age:
    print("Has age")
else:
    print("No age")

if guest_list:
    print("List has entries")
else:
    print("List empty")
No username
No age
List has entries

2. Write a single if/else statement (no loops, and don't use len()) that, given a string variable coupon, prints "Applying coupon" when coupon is non-empty and is not the string "NONE", and prints "No coupon" otherwise.

For example, coupon = "SAVE10" should print "Applying coupon", while coupon = "" or coupon = "NONE" should each print "No coupon".

if coupon and coupon != "NONE":
    print("Applying coupon")
else:
    print("No coupon")

Week 5: functions, parameters, and control flow

1. Write a function named is_even that takes an integer n and returns True if it is even and False otherwise.

def is_even(n):
    return n % 2 == 0

2. Write two functions: square(n), which returns n squared, and sum_of_squares(a, b), which calls square on each of its arguments and returns the sum of the results.

For example, sum_of_squares(3, 4) should return 25 (9 + 16).

def square(n):
    return n ** 2

def sum_of_squares(a, b):
    return square(a) + square(b)

Week 5: local and global scope

1. This code raises an error. Name the error type and explain why it happens.

total = 0
def add(n):
    total = total + n
    return total

print(add(5))

  UnboundLocalError. Because total is assigned to somewhere inside add, Python treats it as a local variable for the entire function body — including the line that reads total + n, which runs before any local total has been assigned. The read happens before the local variable exists.

2. A student wrote this code to keep a running total, but it doesn't work the way they expect:

total = 0
def add_to_total(n):
    total = total + n
    return total

add_to_total(5)
add_to_total(3)
print(total)

Rewrite add_to_total so it takes the current total as a parameter and returns the new total, without using the global keyword. Then show the calls needed to add 5 and then 3 to a running total starting at 0, and print the final result.

def add_to_total(current_total, n):
    return current_total + n

total = 0
total = add_to_total(total, 5)
total = add_to_total(total, 3)
print(total)

  The output is 8. Passing the running total in and returning the new one avoids relying on a global variable at all — each call is self-contained and the caller is responsible for keeping track of the result.

Week 5: tuples

1. Write a one-line statement that creates a tuple named point holding the coordinates 3 and 7. Then write a second statement that unpacks point into two separate variables, x and y.

point = (3, 7)
x, y = point

2. Write a function named stats that takes three numbers, a, b, and c, and returns a tuple containing the smallest and the largest of the three, in that order. Use the built-in min() and max() functions.

For example, stats(4, 9, 2) returns (2, 9).

def stats(a, b, c):
    return min(a, b, c), max(a, b, c)

3. This code raises an error. Name the error type and explain why.

coords = (1, 2)
coords[0] = 5

  TypeError — tuples are immutable, so an individual item cannot be reassigned the way a list item can. A new tuple would need to be created instead.

Week 5: informal testing with __main__

1. Write an if __name__ == "__main__": block that tests a function square(n) by calling square(4) and printing the result.

if __name__ == "__main__":
    print(square(4))

2. Given this function definition:

def cube(n):
    return n ** 3

Write an if __name__ == "__main__": driver block below it that tests cube on three sample inputs — 2, -3, and 0 — printing the result of each call on its own line.

if __name__ == "__main__":
    print(cube(2))
    print(cube(-3))
    print(cube(0))

  Running this prints 8, then -27, then 0. Trying several sample inputs like this — including an edge case such as 0 — is exactly the kind of informal testing the __main__ guard is meant for.

3. When a module is imported rather than run directly, what does its built-in __name__ equal?

  The module's own name (e.g. "shapes"), not "__main__" — which is why code inside the guard only runs when the file is executed directly.