7c. Prof. Rosenthal’s Review#

A review of Chapter 7: Iteration and Search, 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 for loops over strings, counters, the in operator, string methods and doctests. One question reads words.txt, a list of about 114,000 English words, one per line, in alphabetical order (the first two are aa and aah).

The setup cell below downloads words.txt.

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://raw.githubusercontent.com/AllenDowney/ThinkPython/v3/words.txt');

Question 1 (easy): what is displayed?#

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

for letter in 'hi':
    print(letter * 2)
for letter in 'code':
    print(letter, end=' ')

Question 2 (easy): what is displayed?#

x = 5
x = x + 1
x += 2
x *= 3
x -= 4
print(x)

Question 3 (easy): what is displayed?#

word = 'Gadsby'
print('e' in word, 'G' in word, 'g' in word)
print('ads' in word)
print(word.lower(), word)

Question 4 (easy): write a function#

Write a function called exclaim_letters that takes a string word and displays each of its letters followed by !, one per line.

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

def exclaim_letters(word):
    ...

Examples

exclaim_letters('hi')
h!
i!
exclaim_letters('yes')
y!
e!
s!

Question 5 (medium): what is displayed?#

count = 0
total = 0
for letter in 'Mississippi':
    total += 1
    if letter == 's':
        count += 1
print(count, total)

Question 6 (medium): what is displayed?#

word = 'Hello'
word.lower()
print(word)
word = word.lower()
print(word)

Question 7 (medium): what is displayed?#

line = '  hello world \n'
print(len(line), len(line.strip()))
print(line.strip() + '!')

Question 8 (medium): what happens?#

for letter in 'abc':
    num_letters = num_letters + 1
print(num_letters)

Question 9 (medium): reading a file#

words.txt has one word per line; its first two lines are aa and aah. Predict what this code displays.

file_object = open('words.txt')
first = file_object.readline()
second = file_object.readline()
print(len(first), len(second.strip()))
print(second.strip())

Question 10 (medium): write a function#

Write a function called count_vowels that takes a string and returns the number of vowels (a, e, i, o, u, uppercase or lowercase) in it.

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

def count_vowels(word):
    ...

Examples

print(count_vowels('banana'))
3
print(count_vowels('Python'), count_vowels('AEIOU'), count_vowels('rhythm'))
1 5 0

Question 11 (medium): write a function#

Write a function called first_vowel that takes a string and returns its first vowel (a, e, i, o or u, lowercase), or None if it has none.

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

def first_vowel(word):
    ...

Examples

print(first_vowel('python'), first_vowel('strength'))
o e
print(first_vowel('rhythm'))
None

Question 12 (hard): what is displayed?#

def uses_any_wrong(word, letters):
    for letter in word:
        if letter in letters:
            return True
        else:
            return False

print(uses_any_wrong('nab', 'n'), uses_any_wrong('banana', 'n'))

Question 13 (hard): what is displayed?#

count = 0
for a in 'ab':
    line = ''
    for b in 'xyz':
        line += a + b
        count += 1
    print(line)
print(count)

Question 14 (hard): doctests#

run_doctests runs the tests in a function’s docstring (you can ignore how it works: globals() and __name__ are explained later). Predict what the last line displays. What is wrong with count_e, and how do you fix it?

Run this cell to define run_doctests.

from doctest import run_docstring_examples

def run_doctests(func):
    run_docstring_examples(func, globals(), name=func.__name__)
def count_e(word):
    """Count the letter e (or E) in word.

    >>> count_e('Eerie')
    3
    >>> count_e('sky')
    0
    """
    count = 0
    for letter in word:
        if letter == 'e':
            count += 1
    return count

run_doctests(count_e)

Question 15 (hard): searching a file#

What does this code display? Explain what it counts. (You cannot know the number without running it; predict what it means, then open the Answer to see the number.)

count = 0
for line in open('words.txt'):
    word = line.strip()
    if 'q' in word and 'u' not in word:
        count += 1
print(count)

Question 16 (hard): write a function#

A word is abecedarian if its letters are in alphabetical order (repeated letters are allowed), like almost or abbey. Write a function is_abecedarian that takes a lowercase word and returns True if it is abecedarian and False otherwise. Strings can be compared with <: 'a' < 'b' is True, and 'h' < 'e' is False.

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

def is_abecedarian(word):
    ...

Examples

print(is_abecedarian('almost'), is_abecedarian('abbey'))
True True
print(is_abecedarian('hello'), is_abecedarian('a'))
False True

Question 17 (hard): write a function with doctests#

Write a function count_doubles that takes a word and returns the number of times a letter is immediately followed by the same letter. Give it a docstring with at least three doctests, and check that running them displays nothing.

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

def count_doubles(word):
    ...

Examples

print(count_doubles('bookkeeper'))
3
print(count_doubles('Mississippi'), count_doubles('cat'), count_doubles('aaa'))
3 0 2

This question uses run_doctests from Question 14.

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