Homework 10 Solutions
Solution Files
You can find the solutions in hw10.py.
Required Questions
Iterators and Generators
Q1: Scale
Implement an iterator class called ScaleIterator that scales(multiplies) elements in an
iterable s by a number k.
Be careful! If your
__next__method never raisesStopIteration, you might loop forever.
class ScaleIterator:
"""An iterator the scales elements of the iterable s by a number k.
>>> s = ScaleIterator([1, 5, 2], 5)
>>> for elem in s:
... print(elem)
5
25
10
>>> m = ScaleIterator([1, 2, 3, 4, 5, 6], 2)
>>> [next(m) for _ in range(5)]
[2, 4, 6, 8, 10]
"""
def __init__(self, s, k):
self.s = iter(s)
self.k = k
def __iter__(self):
return self
def __next__(self):
return next(self.s) * self.k
Use Ok to test your code:
python3 ok -q ScaleIterator
Q2: Amplify
Implement amplify, a generator function that takes a one-argument function f and a starting value x. The element at index k that it yields (starting at 0) is the result of applying f k times to x. It terminates whenever the next value it would yield is a falsy value, such as 0, "", [], False, etc.
def amplify(f, x):
"""Yield the values x, f(x), f(f(x)), ... that are all truthy values
and stop yielding once the sequence reaches the first falsy value.
>>> gen1 = amplify(lambda s: s[1:], 'boxes')
>>> [next(gen1) for _ in range(5)]
['boxes', 'oxes', 'xes', 'es', 's']
>>> try:
... next(gen1)
... except StopIteration:
... print('Correctly raised StopIteration')
... else:
... print('Expected StopIteration error but was not raised')
Correctly raised StopIteration
>>> gen2 = amplify(lambda x: x // 2 - 1, 14)
>>> [next(gen2) for _ in range(3)]
[14, 6, 2]
>>> try:
... next(gen2)
... except StopIteration:
... print('Correctly raised StopIteration')
... else:
... print('Expected StopIteration error but was not raised')
Correctly raised StopIteration
"""
while x:
yield x
x = f(x)
Use Ok to test your code:
python3 ok -q amplify
Q3: Countdown
Write both a generator function and an iterator (that is not a generator) that count down to 0.
def countdown(n):
"""
A generator that counts down from N to 0.
>>> for number in countdown(5):
... print(number)
...
5
4
3
2
1
0
>>> for number in countdown(2):
... print(number)
...
2
1
0
"""
while n >= 0:
yield n
n = n - 1
class Countdown:
"""
An iterator that counts down from N to 0.
>>> for number in Countdown(5):
... print(number)
...
5
4
3
2
1
0
>>> for number in Countdown(2):
... print(number)
...
2
1
0
"""
def __init__(self, cur):
self.cur = cur
def __next__(self):
if self.cur < 0:
raise StopIteration
self.cur -= 1
return self.cur + 1
def __iter__(self):
"""So that we can use this iterator as an iterable."""
return self
Use Ok to test your code:
python3 ok -q countdown
python3 ok -q Countdown
Submit Assignment
Submit this assignment by uploading any files you've edited to the appropriate Gradescope assignment. Lab 00 has detailed instructions.