5b. Prof. Rosenthal’s Review#

A review of Chapter 5: Conditionals and Recursion, 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#

One question draws a picture with jupyturtle, a small turtle-graphics module for Jupyter notebooks. The turtle starts in the middle of the canvas, facing east (to the right). make_turtle() starts a new drawing, forward(d) moves the turtle d units while drawing a line (backward if d is negative), left(a) and right(a) turn it a degrees, and penup() and pendown() stop and restart the drawing.

The setup cell below downloads jupyturtle and imports those functions.

from os.path import basename, exists

def download(url):
    filename = basename(url)
    if not exists(filename):
        from urllib.request import urlretrieve

        local, _ = urlretrieve(url, filename)
        print("Downloaded " + str(local))
    return filename

download('https://github.com/ramalho/jupyturtle/releases/download/2024-03/jupyturtle.py');

from jupyturtle import make_turtle, forward, left, right, penup, pendown

Question 1 (easy): what is displayed?#

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

minutes = 135
print(minutes // 60, minutes % 60)
print(17 % 5, 20 % 5, 3 % 7)
print(7 // 2, -7 // 2)

Question 2 (easy): what is displayed?#

x = 5
y = 7
print(x == y, x != y)
print(x < y and y < 10)
print(x > y or y == 7)
print(not x < y)
print(type(True))

Question 3 (easy): what is displayed?#

def check(n):
    if n % 2 == 0:
        print(n, 'is even')
    else:
        print(n, 'is odd')

check(4)
check(7)
check(0)

Question 4 (easy): write a function#

Write a function called sign that takes a number x and displays positive, negative or zero.

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

def sign(x):
    ...

Examples

sign(12)
sign(-0.5)
positive
negative
sign(0)
zero

Question 5 (medium): what is displayed?#

def grade(score):
    if score >= 60:
        print('pass')
    elif score >= 90:
        print('excellent')
    else:
        print('fail')

grade(95)
grade(70)
grade(30)

Question 6 (medium): what is displayed?#

x = 15
if x > 10:
    print('big')
if x > 5:
    print('medium')
if x > 0:
    print('small')
else:
    print('not positive')

Question 7 (medium): what is displayed?#

def describe(x):
    if 0 < x < 10:
        print(x, 'is a positive single digit')
    else:
        if x <= 0:
            print(x, 'is not positive')
        else:
            print(x, 'is 10 or more')

describe(5)
describe(-3)
describe(10)

Question 8 (medium): find the error#

Each part has one mistake. Predict the error for each, then open the Answer to check.

Part a

x = 5
if x = 5:
    print('five')

Part b

x = 5
if x > 0
    print('positive')

Part c

x = 5
 y = 6

Question 9 (medium): write a function#

Write a function called end_hour that takes start (an hour on a 24-hour clock, from 0 to 23) and duration (a number of hours), and displays the hour when the event ends, also from 0 to 23.

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

def end_hour(start, duration):
    ...

Examples

end_hour(9, 3)
end_hour(22, 5)
12
3
end_hour(20, 28)
0

Question 10 (medium): write a function#

Write a function called fizzbuzz that takes a positive integer n and displays FizzBuzz if n is divisible by both 3 and 5, Fizz if it is divisible by 3 only, Buzz if it is divisible by 5 only, and otherwise n itself.

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

def fizzbuzz(n):
    ...

Examples

fizzbuzz(9)
fizzbuzz(10)
Fizz
Buzz
fizzbuzz(30)
fizzbuzz(7)
FizzBuzz
7

Question 11 (medium): write a function#

Write a function called largest that takes three numbers and displays the largest of them. Use if statements (not the built-in function max).

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

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

Examples

largest(3, 9, 4)
largest(10, 2, 7)
9
10
largest(5, 5, 1)
largest(-1, -8, -0.5)
5
-0.5

Question 12 (hard): what is displayed?#

def mystery(n, s):
    print('n =', n, 's =', s)
    if n == 0:
        print('result:', s)
    else:
        mystery(n - 1, s + n)

mystery(3, 0)

Question 13 (hard): what is displayed?#

def up_down(n):
    if n > 0:
        print('*' * n)
        up_down(n - 1)
        print('*' * n)

up_down(3)

Question 14 (hard): infinite recursion#

Run this cell to define countdown_by_two.

def countdown_by_two(n):
    if n == 0:
        print('Blastoff!')
    else:
        countdown_by_two(n - 2)

Two correct ways to call it:

countdown_by_two(4)
Blastoff!
countdown_by_two(10)
Blastoff!

What happens with this call? How would you fix the function? (Try your fix in a new cell, so that the cell above keeps the original code.)

countdown_by_two(5)

Question 15 (hard): write a recursive function#

Write a recursive function called stairs that takes a positive integer n and displays n lines: n copies of #, then n - 1 copies, and so on, down to one. Do not use a for loop.

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

def stairs(n):
    ...

Examples

stairs(3)
###
##
#
stairs(5)
#####
####
###
##
#

Question 16 (hard): write two recursive functions#

Write two recursive functions that take a non-negative integer n and display its digits, one per line: digits_backward(n) from the last digit to the first, and digits_forward(n) from the first to the last. Use % 10 (the last digit) and // 10 (the number without its last digit), and no loops.

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

def digits_backward(n):
    ...

def digits_forward(n):
    ...

Examples

digits_backward(472)
2
7
4
digits_forward(472)
4
7
2
digits_forward(5)
5

Question 17 (hard): what is drawn?#

This recursive function draws with jupyturtle. Describe what it draws, then open the Answer to check.

def branch(length):
    if length > 10:
        forward(length)
        left(30)
        branch(length * 0.6)
        right(60)
        branch(length * 0.6)
        left(30)
        forward(-length)

make_turtle(delay=0, height=220)
left(90)            # face up
penup()
forward(-100)       # move down without drawing
pendown()
branch(70)

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