Functions
Experessions
Types of expressions
An expression describes a computation and evaluates to a value.
Call Expressions in Python
All expressions can use function call notation.
Anatomy of a Call Expression
add(2,3)
add => Operator
2,3 => Operands
Operators and operands are also expressions. So they evaluate to values.
Evalutaion procedure for call expressions
- Evaluate the operator and then the operands subexpressions
- Apply the function that is the value of the operator subexpression to the arguments that are the values of the operand subexpressions
Evaluating Nested Expressions
mul(add(2,mul(4,6)), add(3,5))
Names, Assignment, and User-Defined Functions
Primitive expressions:
- 2 : Number or Numeral
- add : Name
- 'hello': String
Call expressions:
max(2,3)
- max : Operator
- 2,3 : Operands
An operand can also be a call expression
Question 1
What is the value of the final expression in the following sequence of expressions?
f = min
f = max
g, h = min, max
max = g
max(f(2, g(h(1, 5), 3)), 4)
Answer: 3
Environment Diagrams
Environment diagrams visualize the interpreter's process
Assignment Statements
Execution rule for assignment statements:
- Evaluate all expressions to the right of = form left to right
- Bind all names to the left of = to the resulting values in the current frame
Defining Functions
Assignment is a simple means of abstraction: binds names to values
Function definition is a more powerful means of abstraction: binds names to expressions
def <name>(<formal parameters>):
return <return expression>
Execution procedure for def statements:
- Create a function with signature
( ) - Set the body of that function to be everything indented after the first line
- Bind
to that function in the current frame
Calling User-Defined Functions
Procedure for calling a user-defined function:
- Add a local frame, forming a new environment
- Bind the formal parameters to the arguments
- Execute the body of the function in the new environment
Looking Up Names In Environments
Every expression is evaluated in the context of an environment
So far, the current environment is either:
- The global frame alone, or
- A local frame, followed by the global frame
Most important
An environment is a sequence of frames.
A name evaluates to the value bound to that name in the first frame in the sequence where that name is found.
E.g., to look up some name in the body of the square function:
- Look for that name in the local frame.
- If not found, look for it in the global frame.(Built-in names like "max" are in the global frame too, but we don't draw them in environment diagrams.)
Homework
from operator import add, sub
def a_plus_abs_b(a, b):
"""Return a+abs(b), but without calling abs.
>>> a_plus_abs_b(2, 3)
5
>>> a_plus_abs_b(2, -3)
5
>>> a_plus_abs_b(-1, 4)
3
>>> a_plus_abs_b(-1, -4)
3
"""
if b < 0:
f = sub
else:
f = add
return f(a, b)
def a_plus_abs_b_syntax_check():
"""Check that you didn't change the return statement of a_plus_abs_b.
>>> # You aren't expected to understand the code of this test.
>>> import inspect, re
>>> re.findall(r'^\s*(return .*)', inspect.getsource(a_plus_abs_b), re.M)
['return f(a, b)']
"""
# You don't need to edit this function. It's just here to check your work.
def two_of_three(i, j, k):
"""Return m*m + n*n, where m and n are the two smallest members of the
positive numbers i, j, and k.
>>> two_of_three(1, 2, 3)
5
>>> two_of_three(5, 3, 1)
10
>>> two_of_three(10, 2, 8)
68
>>> two_of_three(5, 5, 5)
50
"""
return min(i, j, k)**2 + max(min(j, k), min(i,k), min(i,j))**2
def two_of_three_syntax_check():
"""Check that your two_of_three code consists of nothing but a return statement.
>>> # You aren't expected to understand the code of this test.
>>> import inspect, ast
>>> [type(x).__name__ for x in ast.parse(inspect.getsource(two_of_three)).body[0].body]
['Expr', 'Return']
"""
# You don't need to edit this function. It's just here to check your work.
def largest_factor(n):
"""Return the largest factor of n that is smaller than n.
>>> largest_factor(15) # factors are 1, 3, 5
5
>>> largest_factor(80) # factors are 1, 2, 4, 5, 8, 10, 16, 20, 40
40
>>> largest_factor(13) # factor is 1 since 13 is prime
1
"""
"*** YOUR CODE HERE ***"
num = 1
for i in range(n):
if not(i == 0):
if n % i == 0:
num = max(num, i)
return num
def hailstone(n):
"""Print the hailstone sequence starting at n and return its
length.
>>> a = hailstone(10)
10
5
16
8
4
2
1
>>> a
7
>>> b = hailstone(1)
1
>>> b
1
"""
"*** YOUR CODE HERE ***"
t = 1
while (n != 1):
if n % 2 == 0:
t+=1
print(n)
n=int(n/2)
else:
t+=1
print(n)
n = n*3+1
print(1)
return t
Comments NOTHING