**Solutions:** You can find the file with solutions for all
questions here.

## 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'
"""
result = ""
if pair[0] == 0:
result += "Male "
else:
result += "Female "
if pair[1] == 0:
result += '0-9'
elif pair[1] == 10:
result += '100+'
else:
result += str(pair[1]) + '0-' + str(pair[1]) + '9'
return result
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+']
"""
return [decode_helper(pair) for pair in list_of_sex_age_pairs]
```

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
"""
def foo(num):
for pair in pairs:
if pair[0] == num:
return function(pair[1])
return None
return foo
```

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
"""
return 3
def f2():
"""
>>> f2()()
3
"""
return lambda: 3
def f3():
"""
>>> f3()(3)
3
"""
return lambda x: x
def f4():
"""
>>> f4()()(3)()
3
"""
return lambda: lambda x: lambda: x
```

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
"""
return lambda m : lambda n : m * n
```

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
"""
return lambda arg1: lambda arg2: fn(arg1, arg2)
```

Use OK to test your code:

`python3 ok -q lambda_curry2`