The Scope of Things

Jed Rembold

October 1, 2025

Announcements

  • Did Wordle get submitted?
  • Midterm on Friday!!
    • Testing accommodations? You need to make arrangements with AES today (ideally yesterday)!
    • Bring your (charged) laptop!
    • Both practice exams and solutions now posted
    • Version of the practice exam on Canvas, which is how you will actually take the exam on Friday
      • Please take the time to take it to familiarize yourself with how things will appear and how you’ll submit solutions
    • Resources to ensure you can pull up rapidly that you can use on the exam:
      • The Python summary
      • The textbook
      • The class slides, section slides
      • Your notes, handwritten or in electric form
      • Your past work on GitHub (problem sets, section materials, projects, etc)
  • Attend your sections this week. They are all about reviewing for the exam.
  • No TechBytes tomorrow
  • Polling: polling.jedrembold.prof

Review Question!

What would be the printed value of z at the end of the code to the right?

  1. 19
  2. 25
  3. 27
  4. None of the above
def f(x,y=0):
    z = (x + 3) ** 2
    return y + z

w = 1
z = w + f(y=w,x=2)
print(z)

Scoping out Variables

Opinion Poll!

def Vegas(x):
    y = 2
    for i in range(5):
        x += y
    return x

x = 3
z = Vegas(x)
print('z =', z)
print('x =', x)

Consider the code to the left. When the final value of x is printed, what will its value be?

  1. 3
  2. 5
  3. 13
  4. None

Stacks and Scopes

  • Functions really do work as self-contained little boxes or environments!
    • “What happens in Vegas stays in Vegas
  • Whenever Python enters a new function, you can envision that it gets out a fresh new board to keep track of that function’s variables
    • What happens on that board does NOT affect whatever might have been defined or happened on other boards
    • Each board is commonly called a stack frame
  • When Python finishes with a function and returns, the board or stack frame for that function is thrown away!

Taking a Walk through Vegas

We’ll annotate the stack frames by hand as the earlier code runs:

def Vegas(x):
    y = 2
    for i in range(5):
        x += y
    return x

x = 3
z = Vegas(x)
print('z =', z)
print('x =', x)

Summary of a Function Call

  1. Evaluate the arguments in the context of the caller
  2. Reserve space for the function in a new stack frame
  3. Copy each positional argument to the corresponding parameter variable
  4. Copy each keyword argument to the parameter with that name
  5. For parameters with default values, if not already assigned, assign those values
  6. Evaluate statements in the function body, using current stack frame to look up values of local variables
  7. On encountering a return, compute the return value and substitute that value in place of the function call
  8. Remove the stack frame
  9. Return to the caller, continuing from just after the function call

Name Resolution and Scope

  • When Python encounters a variable name in a program, it looks for where the variable was defined in an expanding search:
    1. Local - The local context is all the variables defined within the current function. This includes variables appearing as a parameter!
    2. Enclosing - The enclosing context consists of the names defined in a function enclosing the current one.
    3. Global - The global context consists of names defined outside of any function or imported into the current module.
    4. Built-in - The last place Python looks is in the names of any built-in functions, like abs, str, print, etc.
  • The part of a program in which a name is defined in called its scope

Scoping Example

def func1(x,y):
    return z + func2(x,y)

def func2(x,y):
    def func3(x):
        return (y + x) ** 2

    z = x - func3(y)
    return z - y

z = 1
print(func1(2,z))

Local Variables

  • In Python, assigning any value to a variable means that the variable is assumed to be local

    • This generally makes sense, as you would not want more specific functions overriding variables in other areas
  • Can lead to issues though:

    def increment():
      x = x + 1
    
    x = 0
    increment()
  • There are a few ways to address this, but we’ll focus on one in particular when it comes to PGL

Closures and Functions as Arguments

First Class Functions

  • Functions in Python are treated as data values just like anything else!
    • We will need to take advantage of this to write listener functions.
  • You can assign a function to a variable, pass it as a parameter, return it as a result, etc
  • Functions treated like any other data value are called first-class functions
  • To work with a function itself, you leave off the (). Including the parentheses is how you call the function!

A First Class Example

import math

def evaluate_numbers(func):
    print(func)
    print(func(0))
    print(func(2))
    print(func(10))

evaluate_numbers(math.sqrt)
evaluate_numbers(math.exp)

Closures

Consider the code to the right.

  • Why does the line 12 not error?
  • Python Tutor
  • f2 must also keep track of any local variables!
  • The local variables that are included as part of a function are called its closure
b = 1
def f1(a):
    print(a)
    print(b)

    def f2():
        c = a + b
        return c * 3
    return f2 

f2 = f1(10) 
c = f2()
// reveal.js plugins