**Note the special due date and time:** *Due by 7pm on Tuesday, 2/12*

**Submission.** See the online submission instructions.
We have provided a starter file for the questions below.

**Readings.** Section 1.6
and 1.7
of the online lecture notes.

**Q1.** The idea of smoothing a function is an important concept in signal
processing. If `f` is a one-argument function and `dx` is some small number,
then the smoothed version of `f` is the function whose value at a point `x`
is the average of `f(x - dx)`, `f(x)`, and `f(x + dx)`. Write a function
`smooth` that takes as input a function `f` and a value to use for `dx`
and returns a function that computes the smoothed version of `f`. Do not use
any `def` statements inside of `smooth`; use `lambda` expressions instead.

def smooth(f, dx): """Returns the smoothed version of f, g where g(x) = (f(x - dx) + f(x) + f(x + dx)) / 3 >>> square = lambda x: x ** 2 >>> round(smooth(square, 1)(0), 3) 0.667 """ "*** YOUR CODE HERE ***"

It is sometimes valuable to repeatedly smooth a function (that is, smooth the
smoothed function, and so on) to obtain the `n`-fold smoothed function. Show
how to generate the `n`-fold smoothed function, `n_fold_smooth`, of any
given function using your `smooth` function and `repeated` from homework 2.
As with `smooth`, use `lambda` expressions rather than `def` statements in
the body of `n_fold_smooth`.

def n_fold_smooth(f, dx, n): """Returns the n-fold smoothed version of f >>> square = lambda x: x ** 2 >>> round(n_fold_smooth(square, 1, 3)(0), 3) 2.0 """ "*** YOUR CODE HERE ***"

**Q2.** An infinite continued fraction is an expression of the form:

As an example, one can show that the inverse of the golden ratio can be computed
by setting all of the terms to 1. A way to approximate the value of an infinite
continued fraction is to compute the value of truncating after a given number of
terms. This truncation, called the `k`-term finite continued fraction, has the
form:

Write a function `iterative_continued_frac`, which takes two functions
`n_term` and `d_term`, which each produce the `ith` `N` and `D` term
respectively, and a number `k` and returns the `k`-term finite continued
fraction. Use iteration to perform the computation.

def iterative_continued_frac(n_term, d_term, k): """Returns the k-term continued fraction with numerators defined by n_term and denominators defined by d_term. >>> # golden ratio ... round(iterative_continued_frac(lambda x: 1, lambda x: 1, 8), 3) 0.618 >>> # 1 / (1 + (2 / (2 + (3 / (3 + (4 / 4)))))) ... round(iterative_continued_frac(lambda x: x, lambda x: x, 4), 6) 0.578947 """ "*** YOUR CODE HERE ***"

Now write a function `recursive_continued_frac` that uses recursion to compute
the `k`-term finite continued fraction. *Hint:* try writing a recursive helper
function to do most of the work, rather than trying to do the recursion with
`recursive_continued_frac` directly.

def recursive_continued_frac(n_term, d_term, k): """Returns the k-term continued fraction with numerators defined by n_term and denominators defined by d_term. >>> # golden ratio ... round(recursive_continued_frac(lambda x: 1, lambda x: 1, 8), 3) 0.618 >>> # 1 / (1 + (2 / (2 + (3 / (3 + (4 / 4)))))) ... round(recursive_continued_frac(lambda x: x, lambda x: x, 4), 6) 0.578947 """ "*** YOUR CODE HERE ***"

**Q3.** A mathematical function `G` on positive integers is defined by two
cases:

`G(n) = n, if n <= 3`

`G(n) = G(n - 1) + 2 * G(n - 2) + 3 * G(n - 3), if n > 3`

Write a recursive function `g` that computes `G(n)`. Then, write an
iterative function `g_iter` that computes `G(n)`:

def g(n): """Return the value of G(n), computed recursively. >>> g(1) 1 >>> g(2) 2 >>> g(3) 3 >>> g(4) 10 >>> g(5) 22 """ "*** YOUR CODE HERE ***" def g_iter(n): """Return the value of G(n), computed iteratively. >>> g_iter(1) 1 >>> g_iter(2) 2 >>> g_iter(3) 3 >>> g_iter(4) 10 >>> g_iter(5) 22 """ "*** YOUR CODE HERE ***"

**Q4.** (Extra for experts) The recursive factorial function can be written as
a single expression by using a conditional expression.

>>> fact = lambda n: 1 if n == 1 else mul(n, fact(sub(n, 1))) >>> fact(5) 120

However, this implementation relies on the fact (no pun intended) that `fact`
has a name, to which we refer in the body of `fact`. To write a recursive
function, we have always given it a name using a `def` or assignment
statement so that we can refer to the function within its own body. In this
question, your job is to define fact without giving it a name!

Write an expression that computes `n` factorial using only call expressions,
conditional expressions, and lambda expressions (no assignment or def
statements). The `sub` and `mul` functons from the operator module are the
only built-in function required to solve this problem. Return the expression
from the function below:

from operator import sub, mul def make_anonymous_factorial(): """Return the value of an expression that computes factorial. >>> make_anonymous_factorial()(5) 120 """ return YOUR_EXPRESSION_HERE