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

Questions

Question 1: Harmonic Mean

Implement harmonic_mean, which returns the harmonic mean of two positive numbers x and y. The harmonic mean of 2 numbers is 2 divided by the sum of the reciprocals of the numbers. (The reciprocal of x is 1/x.)

def harmonic_mean(x, y):
    """Return the harmonic mean of x and y.

    >>> harmonic_mean(2, 6)
    3.0
    >>> harmonic_mean(1, 1)
    1.0
    >>> harmonic_mean(2.5, 7.5)
    3.75
    >>> harmonic_mean(4, 12)
    6.0
    """
    return 2/(1/x+1/y)

Use OK to test your code:

python3 ok -q harmonic_mean

Question 2: Two of three

Write a function that takes three positive numbers and returns the sum of the squares of the two largest numbers. Use only a single expression for the body of the function.

def two_of_three(a, b, c):
    """Return x*x + y*y, where x and y are the two largest members of the
    positive numbers a, b, and c.

    >>> two_of_three(1, 2, 3)
    13
    >>> two_of_three(5, 3, 1)
    34
    >>> two_of_three(10, 2, 8)
    164
    >>> two_of_three(5, 5, 5)
    50
    """
    return (a*a + b*b + c*c) - min(a*a, b*b, c*c)

Use OK to test your code:

python3 ok -q two_of_three

We use the fact that if a>b and b>0, then square(a)>square(b). So, we can take the max of the sum of squares of all pairs. The max function can take an arbitrary number of arguments.

Question 3: Nonzero

Write a function that takes in a list and returns the first nonzero entry.

def nonzero(lst):
    """ Returns the first nonzero element of a list

    >>> nonzero([1, 2, 3])
    1
    >>> nonzero([0, 1, 2])
    1
    >>> nonzero([0, 0, 0, 0, 0, 0, 5, 0, 6])
    5
    """
    for i in lst:
        if i != 0:
            return i

Use OK to test your code:

python3 ok -q nonzero

Question 4: Contains N

Write a function that takes in a list and a number, and returns whether or not the list contains the value n.

def has_n(lst, n):
    """ Returns whether or not a list contains the value n.

    >>> has_n([1, 2, 2], 2)
    True
    >>> has_n([0, 1, 2], 3)
    False
    >>> has_n([], 5)
    False
    """
    for elem in lst:
        if elem == n:
            return True
    return False

Use OK to test your code:

python3 ok -q has_n

Question 5: Fibonacci

The Fibonacci sequence is a famous sequence in mathematics. The first element in the sequence is 0 and the second element is 1. The nth element is defined as Fn = Fn-1 + Fn-2.

Implement the fib function, which takes an integer n and returns the nth Fibonacci number. Use a while loop in your solution.

def fib(n):
    """Returns the nth Fibonacci number.

    >>> fib(0)
    0
    >>> fib(1)
    1
    >>> fib(2)
    1
    >>> fib(3)
    2
    >>> fib(4)
    3
    >>> fib(5)
    5
    >>> fib(6)
    8
    >>> fib(100)
    354224848179261915075
    """
    curr, next = 0, 1
    while n > 0:
        curr, next = next, curr + next
        n -= 1
    return curr

Use OK to test your code:

python3 ok -q fib

Question 6: Adding matrices

To practice, write a function that adds two matrices together using list comprehensions. The function should take in two 2D lists of the same dimensions. Try to implement this in one line!

def add_matrices(x, y):
    """
    >>> matrix1 = [[1, 3],
    ...            [2, 0]]
    >>> matrix2 = [[-3, 0],
    ...            [1, 2]]
    >>> add_matrices(matrix1, matrix2)
    [[-2, 3], [3, 2]]
    """
    return [[x[i][j] + y[i][j] for j in range(len(x[0]))]
                               for i in range(len(x))]

Use OK to test your code:

python3 ok -q add_matrices

Question 7: Coordinates

Implement a function coords, which takes a function, a sequence, and an upper and lower bound on output of the function. coords then returns a list of x, y coordinate pairs (lists) such that:

  • Each pair contains [x, fn(x)]
  • The x coordinates are the elements in the sequence
  • Only pairs whose y coordinate is within the upper and lower bounds (inclusive)

See the doctests for examples.

One other thing: your answer can only be one line long. You should make use of list comprehensions!

def coords(fn, seq, lower, upper):
    """
    >>> seq = [-4, -2, 0, 1, 3]
    >>> def fn(x):
    ...     return x**2
    >>> coords(fn, seq, 1, 9)
    [[-2, 4], [1, 1], [3, 9]]
    """
    return [[x, fn(x)] for x in seq if lower <= fn(x) and f(x) <= upper]

Use OK to test your code:

python3 ok -q coords