Lab 4: Lambdas
Due at 11:59:59 pm on 9/29/2020.
Download lab04.zip. Inside the archive, you will find starter files for the questions in this lab, along with a copy of the OK autograder.
By the end of this lab, you should have submitted the lab with
python3 ok --submit. You may submit more than once before the deadline; only the final submission will be graded. Check that you have successfully submitted your code on okpy.org. See this article for more instructions on okpy and submitting assignments.
- To receive full credit for this lab, all questions must be attempted.
When you are ready to submit, run
ok with the
python3 ok --submit
ok will display a submission URL, with which you can view your submission on okpy.org.
Lambda expressions are one-line functions that specify two things:
the parameters and the return value.
lambda <parameters>: <return value>
def statements are related to functions, there are some differences.
lambda expression by itself is not very interesting. As with any objects such as numbers, booleans, strings, we usually:
- assign lambda to variables (
foo = lambda x: x)
- pass them in to other functions (
bar(lambda x: x))
- return them as the results of other functions (
return lambda x: x)
- return them as the results of other lambdas (
lambda x: lambda y: x + y)
In the final example above, the outer lambda (
lambda x) takes in a value
x, and it
returns another lambda (
lambda y) that takes an argument
y and returns
Environment diagrams are one of the best learning tools for understanding
lambda expressions because you're able to keep
track of all the different names, function objects, and arguments to functions.
We highly recommend drawing environment diagrams or using Python
tutor if you get stuck doing the WWPD problems below.
For examples of what environment diagrams should look like, try running some
code in Python tutor. Here are the rules:
Note: As we saw in the
lambdaexpression section above,
lambdafunctions have no intrinsic name. When drawing
lambdafunctions in environment diagrams, they are labeled with the name
lambdaor with the lowercase Greek letter λ. This can get confusing when there are multiple lambda functions in an environment diagram, so you can distinguish them by numbering them or by writing the line number on which they were defined.
- Draw the lambda function object and label it with λ, its formal parameters, and its parent frame. A function's parent frame is the frame in which the function was defined.
This is the only step. We are including this section to emphasize the fact that
the difference between
lambda expressions and
def statements is that
lambda expressions do not create any new bindings in the environment.
Question 1: WWPD: Lambda the Free
Use Ok to test your knowledge with the following "What Would Python Display?" questions:
python3 ok -q lambda -u
For all WWPD questions, type
Functionif you believe the answer is
Errorif it errors, and
Nothingif nothing is displayed. As a reminder, the following two lines of code will not display anything in the Python interpreter when executed:
>>> x = None >>> x
>>> lambda x: x # A lambda expression with one parameter x______<function <lambda> at ...>>>> a = lambda x: x # Assigning the lambda function to the name a >>> a(5)______5>>> (lambda: 3)() # Using a lambda expression as an operator in a call exp.______3>>> b = lambda x: lambda: x # Lambdas can return other lambdas! >>> c = b(88) >>> c______<function <lambda> at ...>>> c()______88>>> d = lambda f: f(4) # They can have functions as arguments as well. >>> def square(x): ... return x * x >>> d(square)______16
>>> z = 3 >>> e = lambda x: lambda y: lambda: x + y + z >>> e(0)(1)()______4>>> f = lambda z: x + z >>> f(3)______NameError: name 'x' is not defined
>>> higher_order_lambda = lambda f: lambda x: f(x) >>> g = lambda x: x * x >>> higher_order_lambda(2)(g) # Which argument belongs to which function call?______Error>>> higher_order_lambda(g)(2)______4>>> call_thrice = lambda f: lambda x: f(f(f(x))) >>> call_thrice(lambda y: y + 1)(0)______3>>> print_lambda = lambda z: print(z) # When is the return expression of a lambda expression executed? >>> print_lambda______Function>>> one_thousand = print_lambda(1000)______1000>>> one_thousand______# print_lambda returned None, so nothing gets displayed
Environment Diagram Practice
There is no submission for this component. However, we still encourage you to do these problems on paper to develop familiarity with Environment Diagrams, which will appear on the exam.
Question 2: Make Adder
Draw the environment diagram for the following code:
n = 9 def make_adder(n): return lambda k: k + n add_ten = make_adder(n+1) result = add_ten(n)
There are 3 frames total (including the Global frame). In addition, consider the following questions:
- In the Global frame, the name
add_tenpoints to a function object. What is the intrinsic name of that function object, and what frame is its parent?
- In frame
f2, what name is the frame labeled with (
add_tenor λ)? Which frame is the parent of
- What value is the variable
resultbound to in the Global frame?
- The intrinsic name of the function object that
add_tenpoints to is λ (specifically, the lambda whose parameter is
k). The parent frame of this lambda is
f2is labeled with the name λ the parent frame of
f1, since that is where λ is defined.
- The variable
resultis bound to 19.
Question 3: Lambda the Environment Diagram
Try drawing an environment diagram for the following code and predict what Python will output.
You do not need to submit or unlock this question through Ok. Instead, you can check your work with the Online Python Tutor, but try drawing it yourself first!
>>> a = lambda x: x * 2 + 1 >>> def b(b, x): ... return b(x + a(x)) >>> x = 3 >>> b(a, x)______21 # Interactive solution: https://goo.gl/Lu99QR
Question 4: Compose
Write a function that takes in 2 single-argument functions, f and g, and returns another lambda function that takes in a single argument x. The returned function should return the output of applying f(g(x)).
Hint: The staff solution is only 1 line!
def compose(f, g): """Write a function that takes in 2 single-argument functions, f and g, and returns another lambda function that takes in a single argument x. The returned function should return the output of applying f(g(x)). Hint: The staff solution is only 1 line! Return the composition function which given x, computes f(g(x)). >>> add_two = lambda x: x + 2 # adds 2 to x >>> square = lambda x: x ** 2 # squares x >>> a = compose(square, add_two) # (x + 2 ) ^ 2 >>> a(5) 49 >>> mul_ten = lambda x: x * 10 # multiplies 10 with x >>> b = compose(mul_ten, a) # ((x + 2 ) ^ 2) * 10 >>> b(5) 490 >>> b(2) 160 """"*** YOUR CODE HERE ***"return lambda x: f(g(x))
Use OK to test your code:
python3 ok -q compose
Question 5: Mul_by_num
lambda expression, complete the
mul_by_num function. This
function should take an argument and return a one argument function
that multiplies any value passed to it by the original number. Its
body must be one line long:
def mul_by_num(num): """ Returns a function that takes one argument and returns num times that argument. >>> x = mul_by_num(5) >>> y = mul_by_num(2) >>> x(3) 15 >>> y(-4) -8 """"*** YOUR CODE HERE ***"return lambda num2: num * num2
Use OK to test your code:
python3 ok -q mul_by_num
Required Practice ProblemsOpen in a new window
These questions are a mix of Parsons Problems, Code Tracing questions, and Code Writing questions.
Confused about how to use the tool? Check out https://codestyle.herokuapp.com/cs88-lab01 for some problems designed to demonstrate how to solve these types of problems.
These cover some similar material to lab, so can be helpful to further review or try to learn the material. Unlike lab and homework, after you've worked for long enough and tested your code enough times on any of these questions, you'll have the option to view an instructor solution. You'll unlock each question one at a time, either by correctly answering the previous question or by viewing an instructor solution.
Use OK to test your code:
python3 ok -q practice_problems
Make sure to submit this assignment by running:
python3 ok --submit