Skip to main content

Lab 10 — Scoping and mutable state

Date: November 17, 2026

Problem 1​

This problem is about scope: where in the program directory a name is looked up in, and whether an assignment creates a new local name or updates an existing one. Use #level advanced for this lab: some of these programs use global, and others deliberately give a local variable the same name as a global one, which the other levels don't allow.

Part A​

balance = 50

def can_afford(price):
return price <= balance

def buy(price):
if price <= balance:
balance = balance - price
return balance
return "too expensive"

print(can_afford(30))
print(buy(30))
print(balance)
  1. What happens when this program runs? (Consider each print separately: some may never run.)
  2. Does it do what you expect / think is intended? If not, fix it.

Part B​

title = "global"

def story():
def current():
return title
print(current())
title = "local"
return current()

print(story())
print(title)
  1. What happens when this program runs? Explain in terms of which title each function refers to.
  2. Does it do what you expect / think is intended? If not, fix it.

Part C​

score = 0

def points(n: int) -> int:
global score
score = score + n
return score

def reset() -> int:
global score
score = 0
return score

points(10)
points(5)
reset()
score
  1. What is the final value of score? Trace through all changes.
  2. What happens if you remove the global score lines? Why?

Problem 2​

Part A​

Draw the program directory and heap for this scenario in Python:

@dataclass
class Student:
name: str
age: int
obj1 = Student("Alice", 25)
obj2 = Student("Alice", 25)
obj3 = obj1
obj1.age = 26

Show which variables are affected and why.

Part B​

Analyze this Python code. What do the comparisons return?

list1 = [1, 2, 3]
list2 = [1, 2, 3]
list3 = list1
print(list1 == list2)
print(list1 is list2)
print(list1 is list3)

Part C​

Trace through this Python function. What happens after each call?

def add_item(my_list, item):
my_list.append(item)
return my_list

original = [1, 2]
result1 = add_item(original, 3)
result2 = add_item(original, 4)
print(original)
print(result1)
print(result2)

Part D​

Analyze this Python code. What gets printed?

list1 = [10, 20, 30]
list2 = list1
list1[1] = 99
print(list1)
print(list2)

Part E​

Trace this Python function through multiple calls:

def make_counter():
count = 0
count = count + 1
return count

result1 = make_counter()
result2 = make_counter()
print(result1 == result2)