6b. Prof. Rosenthal’s Review#

A review of Chapter 6: Return Values, for students who have already studied the chapter. Use the two lists under Concepts covered as a checklist (click a list’s title to hide it), then work through the Questions, which go from easy to hard. Each question has a suggested answer under Answer. Try the question first, then open the Answer.

Run this page on Colab

Concepts covered#

Questions#

The questions use functions that return values, if statements, recursion and the math module. The setup cell below imports math.

import math

Question 1 (easy): what is displayed?#

Predict what this code displays, then open the Answer to check.

def double(x):
    return x * 2

y = double(5)
print(y, double(y))
print(double('ab'))

Question 2 (easy): what is displayed?#

def shout(word):
    print(word + '!')

result = shout('hi')
print(result)

Question 3 (easy): what is displayed?#

def add_one(x):
    print('start')
    return x + 1
    print('never')

print(add_one(1))

Question 4 (easy): write a function#

Write a function called average that takes two numbers and returns (not displays) their average.

Start from this header (replace ... with the body):

def average(a, b):
    ...

Examples

print(average(3, 5))
4.0
result = average(1, 2)
print(result * 2)
3.0

Question 5 (medium): what is displayed?#

def absolute_value_wrong(x):
    if x < 0:
        return -x
    if x > 0:
        return x

print(absolute_value_wrong(-3), absolute_value_wrong(4), absolute_value_wrong(0))

Question 6 (medium): what is displayed?#

def is_even(n):
    return n % 2 == 0

print(is_even(4), is_even(7))
if is_even(10):
    print('10 is even')
if not is_even(3):
    print('3 is odd')
x = is_even(5) or is_even(6)
print(x)

Question 7 (medium): what is displayed?#

def square(x):
    return x * x

def sum_of_squares(a, b):
    return square(a) + square(b)

print(sum_of_squares(3, 4))
print(square(square(2)))
print(square(sum_of_squares(1, 1)))

Question 8 (medium): find the bug#

This code should display 60 (a bill of 50 plus a 20% tip). What does it display instead, and how do you fix it?

def add_tip(bill):
    return bill + bill // 5

bill = 50
add_tip(bill)
print(bill)

Question 9 (medium): what is displayed?#

def half(n):
    if not isinstance(n, int):
        print('half needs an integer')
        return None
    return n // 2

print(half(9))
print(half(9.0))

Question 10 (medium): write two functions#

Write a function larger(a, b) that returns the larger of two numbers, and a function largest(a, b, c) that returns the largest of three numbers by calling larger. Do not use the built-in function max.

Start from this header (replace ... with the body):

def larger(a, b):
    ...

def largest(a, b, c):
    ...

Examples

print(larger(3, 7), larger(7, 3))
7 7
print(largest(4, 9, 2), largest(-1, -5, -3))
9 -1

Question 11 (medium): write a boolean function#

A year is a leap year if it is divisible by 4, except that years divisible by 100 are not leap years, unless they are also divisible by 400. Write a function is_leap that takes a year and returns True if it is a leap year and False otherwise.

Start from this header (replace ... with the body):

def is_leap(year):
    ...

Examples

print(is_leap(2024), is_leap(2023))
True False
print(is_leap(1900), is_leap(2000))
False True

Question 12 (medium): simplify a boolean function#

This function works, but it is longer than it needs to be.

def is_teen(age):
    if age >= 13 and age <= 19:
        return True
    else:
        return False

Rewrite it with a single return statement and no if statement.

Start from this header (replace ... with the body):

def is_teen(age):
    ...

Examples

print(is_teen(15), is_teen(12))
True False
print(is_teen(19), is_teen(20))
True False

Question 13 (hard): what is displayed?#

def power(b, e):
    print('power', b, e)
    if e == 0:
        return 1
    result = b * power(b, e - 1)
    print('returning', result)
    return result

print(power(2, 3))

Question 14 (hard): what is displayed?#

Predict what this code displays. What does mystery compute, in general?

def mystery(n):
    if n < 10:
        return n
    return n % 10 + mystery(n // 10)

print(mystery(7), mystery(123), mystery(9999))

Question 15 (hard): missing the base case#

Run this cell to define factorial.

def factorial(n):
    if n == 0:
        return 1
    return n * factorial(n - 1)

Two correct ways to call it:

print(factorial(3))
6
print(factorial(0))
1

What happens with this call? Change factorial so that it displays a message and returns None when its argument is not a non-negative integer.

factorial(1.5)

Question 16 (hard): write a recursive function#

Write a recursive function multiply that takes two integers a and b, where b is not negative, and returns a times b, using only + and - (no * and no loops). Hint: a times b is a plus a times b - 1.

Start from this header (replace ... with the body):

def multiply(a, b):
    ...

Examples

print(multiply(6, 7))
42
print(multiply(-3, 4), multiply(5, 0))
-12 0

Question 17 (hard): incremental development#

The area of a triangle with sides a, b and c can be computed in two steps (Heron’s formula):

  1. s is half the perimeter: (a + b + c) / 2.

  2. The area is the square root of s * (s - a) * (s - b) * (s - c).

Write a function triangle_area that returns the area. Use incremental development: start with a version that returns 0, then add one step at a time, displaying the intermediate values, and remove those print calls at the end.

Start from this header (replace ... with the body):

def triangle_area(a, b, c):
    ...

Examples

print(triangle_area(3, 4, 5))
6.0
print(triangle_area(5, 5, 6), round(triangle_area(2, 2, 2), 3))
12.0 1.732

Summary and questions by Prof. Y. Rosenthal, based on Think Python: 3rd Edition by Allen B. Downey. Text license: Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International