Lesson 10 of 26 · about 14 min
Scope and the call stack
Every function call gets its own private workspace (a frame). Calls stack up like plates, and each one disappears when it returns.
🧭 What you need first: Functions: your own instructions
Picture a busy restaurant kitchen. The head chef is making a burger and says “I need sauce,” so they hand that job to the sauce cook. The sauce cook needs chopped onions, so they ask the prep cook.
Now three people are mid-task, stacked on each other. The prep cook finishes the onions and hands them up. The sauce cook finishes the sauce and hands it up. Only then can the chef finish the burger.
Each cook also has their own cutting board. The prep cook’s mess stays on the prep cook’s board. When their job is done, the board is wiped clean.
That’s exactly how function calls work. The stack of cooks is the call stack, and each cutting board is a frame with its own local variables.
Another way: what happens in Vegas…
Variables created inside a function stay inside the function. The outside world can’t see them, and once the function returns, they’re gone.
Another way: a stack of plates
You can only take the top plate off a stack. Function calls work the same way: the most recent call is on top and has to finish before anything below it can continue.
Watch the stack grow and shrink
Step through and watch the boxes on the right. Each call adds a box (a frame); each return removes one. Notice both functions have their own total, and they never mix.
Watch the code run, one step at a time
- 1def tax(amount):
- 2 total = amount * 0.2
- 3 return total
- 4
- 5def price_with_tax(amount):
- 6 total = amount + tax(amount)
- 7 return total
- 8
- 9total = price_with_tax(50)
- 10print(total)
➜ yellow = the line about to run · ✓ = the line that just ran
The real words
- A scope is the region of code where a name is visible.
- Local names: parameters and variables assigned inside a function. Visible only inside that call.
- Global names: assigned at the top level of the program. Visible everywhere (for reading).
- Each call gets a fresh frame. Calling a function twice makes two separate frames, so local values don’t carry over between calls.
- The call stack keeps track of which calls are in progress. When a function calls another, the new frame goes on top.
returnremoves the top frame and goes back to where the call happened. - Name lookup: Python looks for a name in the current (local) frame first, then in the global frame, then in Python’s built-in names like
print. - If you assign to a name inside a function, Python treats it as local, even if a global with the same name exists. That’s why changing a global from inside a function doesn’t work the way beginners expect. The clean fix: pass values in as parameters and send results out with
return.
When an error happens deep inside nested calls, Python prints a traceback: the call stack at the moment of the crash, read from bottom (where it broke) to top (where it started).
Fix the leaky counter
This code tries to add points to score inside a function, but score stays 0. Rewrite add_points so it takes the current score and the points as parameters and returns the new score. Then use it so score ends up as 30.
Which x?
x = 1, then def f(): x = 2; return x …then print(f(), x). What prints?
Function a calls b, and b calls c. Which finishes first?
Got it?
Finish the lesson to color it in on your map and collect its concept cards.
Did this lesson click?