# Extra Questions # Q6 def scale(s, k): """Yield elements of the iterable s scaled by a number k. >>> s = scale([1, 5, 2], 5) >>> type(s) >>> list(s) [5, 25, 10] >>> m = scale(naturals(), 2) >>> [next(m) for _ in range(5)] [2, 4, 6, 8, 10] """ "*** YOUR CODE HERE ***" # Q7 def merge(s0, s1): """Yield the elements of strictly increasing iterables s0 and s1, removing repeats. Assume that s0 and s1 have no repeats. You can also assume that s0 and s1 represent infinite sequences. >>> twos = scale(naturals(), 2) >>> threes = scale(naturals(), 3) >>> m = merge(twos, threes) >>> type(m) >>> [next(m) for _ in range(10)] [2, 3, 4, 6, 8, 9, 10, 12, 14, 15] """ i0, i1 = iter(s0), iter(s1) e0, e1 = next(i0), next(i1) "*** YOUR CODE HERE ***" # Q8 def remainders_generator(m): """ Takes in an integer m, and yields m different remainder groups of m. >>> remainders_mod_four = remainders_generator(4) >>> for rem_group in remainders_mod_four: ... for _ in range(3): ... print(next(rem_group)) 0 4 8 1 5 9 2 6 10 3 7 11 """ "*** YOUR CODE HERE ***" # the naturals generator is used for testing scale and merge functions def naturals(): """A generator function that yields the infinite sequence of natural numbers, starting at 1. >>> m = naturals() >>> type(m) >>> [next(m) for _ in range(10)] [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] """ i = 1 while True: yield i i += 1