Exercises#
Predict the output of this program without executing it. It is a good idea to draw diagrams and/or tables rather than trying to do this in your head.
globals = ["Jupiter", "Mars"]
galactics = ["Andromeda", "Milky Way"]
locals = ["Portland", "Medford"]
def mess(x: list[str], y: list[str]) -> list[str]:
    """Gonna mess with your data!"""
    x[1] = "Venus"
    galactics = ["Triangulum", "Pinwheel" ]
    z = y
    y = ["Corvallis", "Salem"]
    return z
towns = mess(globals, locals)
print(f"Globals is {globals}")
print(f"Galactics is {galactics}")
print(f"Locals is {locals}")
print(f"Returned {towns}")
Predict what this program prints without executing it.
countdown = []
def launch(n: int):
    countdown.append(n)
    if n > 0:
        launch(n-1)
    else:
        print(countdown)
        print("Blast off!")
launch(5)
This program will not work. What error do you expect?
countdown = []
n = 10
def launch():
    countdown.append(n)
    if n > 0:
        n = n - 1
        launch()
    else:
        print(countdown)
        print("Blast off!")
launch()
Solutions to exercises#
Predict the outcome of this program without executing it.
globals = ["Jupiter", "Mars"]
galactics = ["Andromeda", "Milky Way"]
locals = ["Portland", "Medford"]
def mess(x: list[str], y: list[str]) -> list[str]:
    """Gonna mess with your data!"""
    x[1] = "Venus"
    galactics = ["Triangulum", "Pinwheel" ]
    z = y
    y = ["Corvallis", "Salem"]
    return z
towns = mess(globals, locals)
print(f"Globals is {globals}")
print(f"Galactics is {galactics}")
print(f"Locals is {locals}")
print(f"Returned {towns}")
Globals is ['Jupiter', 'Venus']
Galactics is ['Andromeda', 'Milky Way']
Locals is ['Portland', 'Medford']
Returned ['Portland', 'Medford']
Do any of those surprise you?
Passing
globalsas argumentxcausesxto become an alias ofglobals, i.e., another reference to the same list. Settingx[1]to"Venus"modifies the second element of that list, which is still the list thatglobalsis bound to.The assignment to
galacticswithin the function creates a new local variable calledgalactics, distinct from the global variable calledgalactics. It therefore has no effect outside the function.We passed
localsas argumenty, soyis initially an alias tolocalswithin the function. When we assignzthe value ofy, we have three names (locals,y, andz) for the same list. But then we change the local (withinmess) binding ofyto a new list["Corvallis", "Salem"]. This has no effect on the bindings oflocalsorz.We return
z, which is bound to the same list aslocals.townsthen becomes an alias forlocals.
When mess begins execution, bindings look like this:
The local variables x and y are references that have been copied
from globals and locals, respectively.  When mess is just
about to return, bindings look like this:
Only globals has been changed in the global namespace.
galactics is unchanged in the global namespace because the new
assignment to galactics was to a local variable in the scope of
function mess.
Predict what this program prints without executing it.
countdown = []
def launch(n: int):
    countdown.append(n)
    if n > 0:
        launch(n-1)
    else:
        print(countdown)
        print("Blast off!")
launch(5)
[5, 4, 3, 2, 1, 0]
Blast off!
This program will not work. What error do you expect?
countdown = []
n = 10
def launch():
    countdown.append(n)
    if n > 0:
        n = n - 1
        launch()
    else:
        print(countdown)
        print("Blast off!")
launch()
---------------------------------------------------------------------------
UnboundLocalError                         Traceback (most recent call last)
Cell In[3], line 13
     10         print(countdown)
     11         print("Blast off!")
---> 13 launch()
Cell In[3], line 5, in launch()
      4 def launch():
----> 5     countdown.append(n)
      6     if n > 0:
      7         n = n - 1
UnboundLocalError: cannot access local variable 'n' where it is not associated with a value
Because of the assignment n = n - 1, n will be a local variable
in the scope of launch.  But n is referenced in the call to
append and also in the if statement, before it has been given a
value.  These references will break (exception UnboundLocalError)
even though there is another variable n in the global scope.