Due by 9:00pm on Wednesday, 2/13/2019


Download hw02.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:

Review from lab

Call Expressions

A call expression applies a function, which may or may not accept arguments. The call expression evaluates to the function's return value. It has a familiar notation borrowed from Math.

The syntax of a function call:

  add   (    2   ,    3   )
   |         |        |
operator  operand  operand

Every call expression requires a set of parentheses delimiting its comma-separated operands.

To evaluate a function call:

  1. Evaluate the operator
  2. Evaluate the operands (from left to right).
  3. Apply the operator to the operands (the values of the operands).

If an operand is a nested call expression, then these two steps are applied to that operand in order to evaluate it.

Introduction to Functions

So what is a function anyway?

In math we see functions all the time. Mathematical functions map inputs to transformed outputs. A less obvious role functions serve is to abbreviate. Instead of writing out some complicated polynomial like x^9 + 3x^8 + 4x^4 - 7x^4 + x - 23 every time we'd like to use it, we define f(x) as x^9 + 3x^8 + 4x^4 - 7x^4 + x - 23 once then use it by plugging in numbers (ie. f(5)).

Functions in computer science "function" in a very similar way. When you find yourself about to copy paste code, you should probably be defining a function. Remember converting Fahrenheit to Celsius! We coded that in the first lab.

It would be exhausting to have to write ((fahrenheit - 32)*5)/9 Every time we want to convert fahrenheit to celsius. So, we bundle it up into a function:

# the below line is what we call the “function definition”
# it states the name of the function and its parameters/arguments, which is
# “fahrenheit” # in this case.
# a parameter is something that a function takes in and uses in some way.
def converter(fahrenheit):
    return ((fahrenheit - 32)*5)/9

Now every time we want to do a conversion, we can call just the converter function:


This is abstraction. We abstract the expression into a convenient function that can be used for any input values.

Return Statement

Most functions that you define will contain a return statement. The return statement will give the result of some computation back to the caller of the function and exit the function. For example, the function square below takes in a number x and returns its square.

def square(x):
    >>> square(4)
    return x * x


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)
    >>> harmonic_mean(1, 1)
    >>> harmonic_mean(2.5, 7.5)
    >>> harmonic_mean(4, 12)
    "*** YOUR CODE HERE ***"

Use OK to test your code:

python3 ok -q harmonic_mean

Question 2: Speed Converter

Define speed_converter, which takes a value "miles per minute" with units miles per minute and returns the same value converted to kilometers per day.

The approach for converting from miles per minute to kilometers per day is twofold:

  1. Convert Minutes to Days (Hint: Multiply by Minutes / Hour, Hours / Day)
  2. Convert Miles to Kilometers (Hint: Assume 1 Mile = 1.609 Kilometers)

Try to use only a single expression for the body of the function.

def speed_converter(miles_per_min):
    >>> speed_converter(0)
    >>> speed_converter(0.5)
    >>> speed_converter(0.75)
    >>> speed_converter(2)
    "*** YOUR CODE HERE ***"
    return kilos_per_day

Use OK to test your code:

python3 ok -q speed_converter

Question 3: 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)
    >>> two_of_three(5, 3, 1)
    >>> two_of_three(10, 2, 8)
    >>> two_of_three(5, 5, 5)
    "*** YOUR CODE HERE ***"

Use OK to test your code:

python3 ok -q two_of_three

Question 4: Largest factor

Write a function that takes an integer n greater than 1 and returns the largest integer smaller than n that evenly divides n*n-1.

Hint: To check if b evenly divides a, you can use the expression a % b == 0, which can be read as, "the remainder of dividing a by b is 0." However, it is possible to solve this problem without any if or while statements.

def largest_factor(n):
    """Return the largest factor of n*n-1 that is smaller than n.

    >>> largest_factor(4) # n*n-1 is 15; factors are 1, 3, 5, 15
    >>> largest_factor(9) # n*n-1 is 80; factors are 1, 2, 4, 5, 8, 10, ...
    "*** YOUR CODE HERE ***"

Use OK to test your code:

python3 ok -q largest_factor

Question 5: Law of Sines

Write a function that determines whether the Law of Sines is upheld.

In trigonometry, the Law of Sines relates the length of the sides of a triangle with the sines of its angles. In other words, assuming a triangle has three sides of length 'a', 'b', and 'c' in addition to three angles denoted as 'A', 'B', and 'C', the Law of Sines is expressed as follows:

sin(A) / a = sin(B) / b = sin(C) / c

from math import sin

def law_of_sines(a, b, c, A, B, C):
    >>> law_of_sines(1, 1, 1, 1.0472, 1.0472, 1.0472)
    >>> law_of_sines(1, 2, 3, 1, 2, 3)
    "*** YOUR CODE HERE ***"
    return is_triangle

Use OK to test your code:

python3 ok -q law_of_sines