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.
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.
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:
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.