#
Homework 4

*Due at 11:59:59 pm on Friday, October 1.*

## Instructions

Download hw04.zip. Inside the archive, you will find starter files for the questions in this homework, along with a copy of the OK autograder.

**Submission:** When you are done, submit with `python3 ok --submit`

. You may submit more than once before the deadline; only the final submission will be scored. Check that you have successfully submitted your code on okpy.org. See this article for more instructions on okpy and submitting assignments.

**Readings:** This homework relies on following references:

## Lists

### Question 1: Decode

Implement a function `decode`

, which takes in a list of pairs of numbers and returns a list of lists of decoded values.

- The list contains pairs of the form
`[sex, age]`

- Sex is an int that is either 0 or 1 and age is an int between 0 and 10
- Return a list of strings where the Sex gets replaced by "Male" for 0 and "Female" for 1, and age gets replaced by "0-9", "10-19", ..., "90-99", "100+"

See the doctests for examples.

One other thing: your answer to the `decode`

function can only be *one line long*. You should make use of list comprehensions and use the helper function!

```
def decode_helper(pair):
"""
Optional helper function! Could be useful to turn something like [0, 0] to 'Male 0-9'
"""
"*** YOUR CODE HERE ***"
return ''
def decode(list_of_sex_age_pairs):
"""
>>> decode([[0, 0], [1, 1], [1, 10]])
['Male 0-9', 'Female 10-19', 'Female 100+']
>>> decode([[0, 0], [0, 1], [0, 2], [0, 3], [0, 4], [1, 5], [1, 6], [1, 7], [1, 8], [1, 9], [1, 10]])
['Male 0-9', 'Male 10-19', 'Male 20-29', 'Male 30-39', 'Male 40-49', 'Female 50-59', 'Female 60-69', 'Female 70-79', 'Female 80-89', 'Female 90-99', 'Female 100+']
"""
"*** YOUR CODE HERE ***"
```

Use OK to test your code:

`python3 ok -q decode`

## Higher Order Functions

### Question 2: Match and Apply

Sometimes when we are given a dataset, we need to alter it for specific values. For example, say we have a table with one column being people's names and the other being the price they have to pay.

We can use a list of pairs for this:

`[["Jessica", 5], ["Andrew", 9], ["Alex", 2], ["Amir", 11], ["John", 3], ["Lyric", 2]]`

The first value in each pair is the name, the second is the price.

Now, let's say we want to give a discount to specific people. We have a discount function that we want to apply to the person's price. Now, we need a function that will only apply the discount function to specific people.

Implement `match_and_apply(pairs, function)`

:

`pairs`

is a list of pairs.`function`

is some function

`match_and_apply`

returns a function such that when the function is given an input that
matches the first of a pair, returns the result of applying `function`

to the second value in the pair.

```
def match_and_apply(pairs, function):
"""
>>> pairs = [[1, 2], [3, 4], [5, 6], [7, 8], [9, 0]]
>>> def square(num):
... return num**2
>>> func = match_and_apply(pairs, square)
>>> result = func(3)
>>> result
16
>>> result = func(1)
>>> result
4
>>> result = func(7)
>>> result
64
>>> result = func(15)
>>> print(result)
None
"""
"*** YOUR CODE HERE ***"
```

Use OK to test your code:

`python3 ok -q match_and_apply`

## Lambdas

### Question 3: Make your own lambdas

For each of the following expressions, write functions `f1`

, `f2`

,
`f3`

, and `f4`

such that the evaluation of each expression
succeeds, without causing an error. Be sure to use lambdas in your
function definition instead of nested `def`

statements. Each function
should have a one line solution.

```
def f1():
"""
>>> f1()
3
"""
"*** YOUR CODE HERE ***"
def f2():
"""
>>> f2()()
3
"""
"*** YOUR CODE HERE ***"
def f3():
"""
>>> f3()(3)
3
"""
"*** YOUR CODE HERE ***"
def f4():
"""
>>> f4()()(3)()
3
"""
"*** YOUR CODE HERE ***"
```

Use OK to test your code:

```
python3 ok -q f1
python3 ok -q f2
python3 ok -q f3
python3 ok -q f4
```

### Question 4: Higher Order Lambdas

Return a lambda function that takes in a multiplier and returns a lambda function that given an input will return the input multiplied by the multiplier.

```
def higher_order_lambdas():
"""
Return a lambda function that takes in a multiplier and returns a lambda function that given an input will
return the input multiplied by the multiplier
>>> hol = higher_order_lambdas()
>>> doubles = hol(2)
>>> doubles(3)
6
>>> hol = higher_order_lambdas()
>>> triples = hol(3)
>>> triples(4)
12
"""
"*** YOUR CODE HERE ***"
```

Use OK to test your code:

`python3 ok -q higher_order_lambdas`

### Question 5: Lambdas and Currying

We can transform multiple-argument functions into a chain of single-argument, higher order functions by taking advantage of lambda expressions. This is useful when dealing with functions that take only single-argument functions. We will see some examples of these later on.

Write a function `lambda_curry2`

that will curry any two argument
function using lambdas. See the doctest if you're not sure what this
means.

```
def lambda_curry2(fn):
"""
Returns a Curried version of a two argument function func.
>>> from operator import add
>>> x = lambda_curry2(add)
>>> y = x(3)
>>> y(5)
8
"""
"*** YOUR CODE HERE ***"
```

Use OK to test your code:

`python3 ok -q lambda_curry2`