# Homework 3 Solutions

**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 *n*th
element is defined as *F _{n} = F_{n-1} +
F_{n-2}*.

Implement the `fib`

function, which takes an integer `n`

and returns
the `n`

th 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`