Practice predicting, tracing, and building programs using Python’s environment model: frames, name lookup, and closures with local state.
**Predict the output** (without running) using the environment model.
```python
def make_adder(n):
def adder(x):
return x + n
return adder
add_three = make_adder(3)
n = 100
print(add_three(10))
print(n)
```
1) What does it print?
2) In one sentence: which `n` does `adder` use, and why?This exercise is about **how many frames exist over time**.
Consider these two factorial implementations:
```python
def factorial_rec(n):
if n == 0:
return 1
return n * factorial_rec(n - 1)
def factorial_loop(n):
product = 1
k = 1
while k <= n:
product *= k
k += 1
return product
```
**Trace prompts (write answers as comments):**
A) For `factorial_rec(4)`, list each call frame created (in order), and the `n` bound in that frame.
B) For `factorial_rec(4)`, list the return values as the recursion unwinds.
C) For `factorial_loop(4)`, how many *function call frames* are created total for the computation (not counting `while` loop “iterations” as frames)? Explain briefly.Implement a **message-passing** bank account using closures.
You will write `make_account(balance)` that returns a `dispatch` function.
- `dispatch('withdraw')` should return a function that takes `amount` and withdraws if possible.
- `dispatch('deposit')` should return a function that takes `amount` and deposits.
Then **extend** it:
- `dispatch('balance')` should return a *zero-argument* function that returns the current balance.
Finally, **predict** (before running) what the prints produce:
```python
acc = make_account(50)
print((acc('deposit'))(40)) # ?
print((acc('withdraw'))(60)) # ?
print((acc('balance'))()) # ?
acc2 = make_account(100)
print((acc2('withdraw'))(10)) # ?
print((acc('balance'))()) # ?
```
Your implementation should keep `acc` and `acc2` state **distinct** (two different enclosed frames).