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