12/12/2024
FUNCTIONS as OBJECTS
FUNCTION FROM LAST LECTURE
def is_even( i ):
"""
Input: i, a positive int
Returns True if i is even and False otherwise
"""
return i%2 == 0
A function always returns something
1
12/12/2024
WHAT IF THERE IS
NO return KEYWORD
def is_even( i ):
"""
Input: i, a positive int
Does not return anything
"""
i%2 == 0
Python returns the value None, if no return given
Represents the absence of a value
If invoked in shell, nothing is printed
No static semantic error generated
def is_even( i ):
"""
Input: i, a positive int
Does not return anything
"""
i%2 == 0
return None
2
12/12/2024
YOU TRY IT!
What is printed if you run this code as a file?
def add(x,y):
return x+y
def mult(x,y):
print(x*y)
add(1,2)
print(add(2,3))
mult(3,4)
print(mult(4,5))
return vs. print
return only has meaning print can be used outside
inside a function functions
only one return executed can execute many print
inside a function statements inside a function
code inside function, but code inside function can be
after return statement, executed after a print
not executed statement
has a value associated has a value associated with
with it, given to function it, outputted to the console
caller
print expression itself returns
None value
3
12/12/2024
YOU TRY IT!
Fix the code that tries to write this function
def is_triangular(n):
""" n is an int > 0
Returns True if n is triangular, i.e. equals a continued
summation of natural numbers (1+2+3+...+k), False otherwise """
total = 0
for i in range(n):
total += i
if total == n:
print(True)
print(False)
FUNCTION SCOPE
4
12/12/2024
UNDERSTANDING FUNCTION
CALLS
How does Python execute a function call?
How does Python know what value is associated with a variable
name?
It creates a new environment with every function call!
Like a mini program that it needs to complete
The mini program runs with assigning its parameters to some inputs
It does the work (aka the body of the function)
It returns a value
The environment disappears after it returns the value
ENVIRONMENTS
Global environment
Where user interacts with Python interpreter
Where the program starts out
Invoking a function creates a new environment (frame/scope)
5
12/12/2024
VARIABLE SCOPE
Formal parameters get bound to the value of input parameters
Scope is a mapping of names to objects
Defines context in which body is evaluated
Values of variables given by bindings of names
Expressions in body of function evaluated wrt this new scope
def f( x ):
x = x + 1
print('in f(x): x =', x)
return x
xxy = 3
z = f( x )
VARIABLE SCOPE
after evaluating def
This is my “black box”
def f( x ):
Global scope
x = x + 1
function
Some
print('in f(x): x =', x) f object
code
return x
x = 3
z = f( x )
6
12/12/2024
VARIABLE SCOPE
after exec 1st assignment
This is my “black box”
def f( x ):
Global scope
x = x + 1
Some
print('in f(x): x =', x) f code
return x
3
x
x = 3
z = f( x )
VARIABLE SCOPE
after f invoked
def f( x ): Global scope
f scope
x = x + 1 Some
f
print('in f(x): x =', x) code x 3
return x
x 3
x = 3
z = f( x )
7
12/12/2024
VARIABLE SCOPE
after f invoked
Global scope
def f( x ):
Some f scope
x = x + 1 f
code 3
print('in f(x): x =', x) x
return x 3
y
y = 3
z = f( y )
VARIABLE SCOPE
eval body of f in f’s scope
in f(x): x = 4 printed out
Global scope
def f( x ): f scope
x = x + 1 f Some
code x 4
3
print('in f(x): x =', x)
return x
x 3
x = 3
z = f( x )
8
12/12/2024
VARIABLE SCOPE
during return
Global scope
def f( x ): f scope
x = x + 1 f Some
code x
print('in f(x): x =', x) 4
return x 3
x
returns 4
x = 3
z = f( x )
VARIABLE SCOPE
after exec 2nd assignment
def f( x ):
Global scope
x = x + 1
Some
print('in f(x): x =', x) f code
return x
3
x
x = 3
4
z = f( x )
z
9
12/12/2024
BIG IDEA
You need to know what
expression you are executing
to know the scope you are in.
ANOTHER SCOPE EXAMPLE
Inside a function, can access a variable defined outside
Inside a function, cannot modify a variable defined outside
(can by using global variables, but frowned upon)
Use the Python Tutor to step through these!
def f(y): def g(y): def h(y):
x = 1 print(x) x += 1
x += 1 print(x + 1)
print(x) x = 5
x = 5 h(x)
x = 5 g(x) print(x)
f(x) print(x)
print(x)
10
12/12/2024
ANOTHER SCOPE EXAMPLE
Inside a function, can access a variable defined outside
Inside a function, cannot modify a variable defined outside
(can by using global variables, but frowned upon)
Use the Python Tutor to step through these!
def f(y): def g(y): def h(y):
x = 1 print(x) x += 1
x += 1 print(x + 1)
print(x) x = 5
x = 5 h(x)
x = 5 g(x) print(x)
f(x) print(x)
print(x) 5
2 6 Error
5 5
FUNCTIONS as
ARGUMENTS
11
12/12/2024
HIGHER ORDER PROCEDURES
Objects in Python have a type
int, float, str, Boolean, NoneType, function
Objects can appear in RHS of assignment statement
Bind a name to an object
Objects
Can be used as an argument to a procedure
Can be returned as a value from a procedure
Functions are also first class objects!
Treat functions just like the other types
Functions can be arguments to another function
Functions can be returned by another function
OBJECTS IN A PROGRAM
function
object with
my_func
some code
is_even
def is_even(i): r int object 2
return i%2 == 0
float object
pi 3.14285714
r = 2
pi = 22/7 False
a
my_func = is_even
b True
a = is_even(3)
b = my_func(4)
12
12/12/2024
BIG IDEA
Everything in Python is
an object.
FUNCTION AS A PARAMETER
def calc(op, x, y):
return op(x,y)
def add(a,b):
return a+b
def div(a,b): if
b != 0:
return a/b
print("Denominator
was 0.")
print(calc(add, 2, 3))
13
12/12/2024
STEP THROUGH THE CODE
def calc(op, x, y):
return op(x,y)
Program Scope
def add(a,b):
return a+b calc function
Some
object
code
def div(a,b):
Some
function
if b != 0: add
code
object
return a/b
print("Denom was 0.")
function
Some
div
object
code
res = calc(add, 2, 3)
res
CREATE calc SCOPE
def calc(op, x, y):
return op(x,y)
Program Scope calc scope
def add(a,b):
return a+b calc function
Some
object
code
def div(a,b):
Some
function
if b != 0: add
code
object
return a/b
print("Denom was 0.")
function
Some
div
object
code
res = calc(add, 2, 3)
res
14
12/12/2024
MATCH FORMAL PARAMS in calc
def calc(op, x, y):
return op(x,y)
Program Scope calc scope
def add(a,b):
return a+b calc Some
function op add
code
object
def div(a,b):
Some
function 2
if b != 0: add x
code
object
return a/b
print("Denom was 0.")
Some
function 3
div y
code
object
res = calc(add, 2, 3)
res
FIRST (and only) LINE IN calc
def calc(op, x, y):
return op(x,y)
Program Scope
def add(a,b): calc scope
return a+b calc function
Some add
object
code op
def div(a,b):
Some
function 2
if b != 0: add x
code
object
return a/b
print("Denom was 0.")
function
Some 3
div y
object
code
res = calc(add, 2, 3)
res
15
12/12/2024
CREATE SCOPE OF add
def calc(op, x, y):
return op(x,y)
Program Scope add scope
def add(a,b): calc scope
return a+b calc function
Some add
object
code op
def div(a,b):
Some
function 2
if b != 0: add x
code
object
return a/b
print("Denom was 0.")
function
Some 3
div y
object
code
res = calc(add, 2, 3)
res
MATCH FORMAL PARAMS IN add
def calc(op, x, y):
return op(x,y)
Program Scope
def add(a,b): calc scope add scope
return a+b calc function
Some add 2
object
code op a
def div(a,b):
Some
function 2 3
if b != 0: add x
code
object b
return a/b
print("Denom was 0.")
function
Some 3
div y
object
code
res = calc(add, 2, 3)
res
16
12/12/2024
EXECUTE LINE OF add
def calc(op, x, y):
return op(x,y)
Program Scope calc scope add scope
def add(a,b):
return a+b calc function
Some op add a 2
object
code
def div(a,b):
Some
function 2 3
if b != 0: add x b
code
object
return a/b
print("Denom was 0.")
function
Some
div y 3
object
code
res = calc(add, 2, 3)
res
returns 5
REPLACE FUNC CALL WITH RETURN
def calc(op, x, y):
return op(x,y)
Program Scope
def add(a,b): calc scope
return a+b calc function
Some add
object
code op
def div(a,b):
Some
function 2
if b != 0: add x
code
object
return a/b
print("Denom was 0.")
function
Some 3
div y
object
code
res = calc(add, 2, 3)
res
17
12/12/2024
EXECUTE LINE OF calc
def calc(op, x, y):
return op(x,y)
Program Scope calc scope
def add(a,b):
return a+b calc function
Some op add
object
code
def div(a,b):
Some
function 2
if b != 0: add x
code
object
return a/b
print("Denom was 0.")
function
Some 3
div y
object
code
res = calc(add, 2, 3)
res
returns 5
REPLACE FUNC CALL WITH RETURN
def calc(op, x, y):
return op(x,y)
Program Scope
def add(a,b):
return a+b calc function
Some
object
code
def div(a,b):
Some
function
if b != 0: add
code
object
return a/b
print("Denom was 0.")
function
Some
div
object
code
res = calc(add, 2, 3)
5
res
18
12/12/2024
YOU TRY IT!
Do a similar trace with the function call
def calc(op, x, y):
return op(x,y)
def div(a,b):
if b != 0:
return a/b
print("Denom was 0.")
res = calc(div,2,0)
What is the value of res and what gets printed?
ANOTHER EXAMPLE:
FUNCTIONS AS PARAMS
def func_a():
print('inside func_a')
def func_b(y):
print('inside func_b')
return y
def func_c(f, z):
print('inside func_c')
return f(z)
print(func_a())
print(5 + func_b(2))
print(func_c(func_b, 3))
19
12/12/2024
FUNCTIONS AS PARAMETERS
func_a scope
Global scope
def func_a(): Some
print('inside func_a') func_a code
def func_b(y): Some
print('inside func_b') func_b code
return y Some
def func_c(f, z): code
func_c
print('inside func_c')
return f(z)
print(func_a())
print(5 + func_b(2))
print(func_c(func_b, 3))
FUNCTIONS AS PARAMETERS
Global scope func_a scope
def func_a():
func_a Some
print('inside func_a') code
def func_b(y): Some
print('inside func_b') func_b code
return y Some
def func_c(f, z): func_c code
print('inside func_c')
None
return f(z)
print(func_a())
print(5 + func_b(2))
print(func_c(func_b, 3))
20
12/12/2024
FUNCTIONS AS PARAMETERS
Global scope
def func_a():
Some
print('inside func_a') func_a code
def func_b(y): Some
print('inside func_b') func_b code
return y Some
def func_c(f, z): code
func_c
print('inside func_c')
return f(z)
print(func_a())
print(5 + func_b(2))
print(func_c(func_b, 3))
FUNCTIONS AS PARAMETERS
Global scope func_b scope
def func_a(): Some
func_a y 2
print('inside func_a') code
def func_b(y): Some
func_b code
print('inside func_b')
return y Some
def func_c(f, z): func_c code
print('inside func_c') None
return f(z)
print(func_a())
print(5 + func_b(2))
print(func_c(func_b, 3))
21
12/12/2024
FUNCTIONS AS PARAMETERS
Global scope func_b scope
def func_a(): func_a')
Some 2
func_a code y
print('inside
def func_b(y): Some
print('inside func_b') func_b code
def return y func_c') Some
code
func_c(f, z): func_c
None
print('inside
return f(z)
print(func_a())
print(5 + func_b(2))
print(func_c(func_b, 3))
FUNCTIONS AS PARAMETERS
Global scope func_b scope
def func_a():
func_a Some y 2
print('inside func_a') code
def func_b(y): Some
func_b code
print('inside func_b')
return y Some
code
def func_c(f, z): func_c') func_c
None
print('inside
return f(z)
print(func_a()) 7 returns 2
print(5 + func_b(2))
print(func_c(func_b, 3))
22
12/12/2024
FUNCTIONS AS PARAMETERS
Global scope
def func_a():
func_a Some
print('inside func_a') code
def func_b(y): Some
print('inside func_b') func_b code
return y Some
def func_c(f, z): func_c code
print('inside func_c') None
return f(z)
print(func_a()) 7
print(5 + func_b(2))
print(func_c(func_b, 3))
FUNCTIONS AS PARAMETERS
Global scope func_c scope
def func_a(): Some
func_a f func_b
print('inside func_a') code
def func_b(y): Some z
3
func_b code
print('inside func_b')
return y Some
func_c code
def func_c(f, z):
print('inside func_c') None
return f(z)
print(func_a()) 7
print(5 + func_b(2))
print(func_c(func_b, 3))
23
12/12/2024
FUNCTIONS AS PARAMETERS
Global scope func_c scope
def func_a(): func_a') func_b
func_a Some f
print('inside code
def func_b(y): Some z
3
print('inside func_b') func_b code
return y Some 3
def func_c(f, z): func_c') func_c code
print('inside None
returns 3 func_b scope
return f(z)
y 3
print(func_a()) 7
print(5 + func_b(2))
print(func_c(func_b, 3))
FUNCTIONS AS PARAMETERS
Global scope func_c scope
def func_a(): func_b
func_a Some f
print('inside func_a') code
def func_b(y): Some z 3
print('inside func_b') func_b code
return y Some 3
def func_c(f, z): func_c code
print('inside func_c') None
return f(z)
7
print(func_a())
print(5 + func_b(2))
print(func_c(func_b, 3)) 3
48 returns 3
24
12/12/2024
YOU TRY IT!
Write a function that meets these specs.
def apply(criteria,n):
"""
* criteria is a func that takes in a number and returns a bool
* n is an int
Returns how many ints from 0 to n (inclusive) match
the criteria (i.e. return True when run with criteria)
"""
49
SUMMARY
Functions are first class objects
They have a type
They can be assigned as a value bound to a name
They can be used as an argument to another procedure
They can be returned as a value from another procedure
Have to be careful about environments
Main program runs in the global environment
Function calls each get a new temporary environment
This enables the creation of concise, easily read code
25