Iterator/Generator Questions

Question 1: Scale

Implement an iterator class called ScaleIterator that scales elements in an iterable iterable by a number scale.

class ScaleIterator:
    """An iterator the scales elements of the iterable by a number scale.

    >>> s = ScaleIterator([1, 5, 2], 5)
    >>> list(s)
    [5, 25, 10]
    >>> m = ScaleIterator(naturals(), 2)
    >>> [next(m) for _ in range(5)]
    [2, 4, 6, 8, 10]
    """
    def __init__(self, iterable, scale):
        "*** YOUR CODE HERE ***"

    def __iter__(self):
        return self

    def __next__(self):
        "*** YOUR CODE HERE ***"

Use OK to test your code:

python3 ok -q ScaleIterator

Question 2: Restart

Implement an iterator class called IteratorRestart that will reset to the beginning when __iter__ is called again.

class IteratorRestart:
    """
    >>> iterator = IteratorRestart(2, 7)
    >>> for num in iterator:
    ...     print(num)
    2
    3
    4
    5
    6
    7
    >>> for num in iterator:
    ...     print(num)
    2
    3
    4
    5
    6
    7
    """
    def __init__(self, start, end):
        "*** YOUR CODE HERE ***"

    def __next__(self):
        "*** YOUR CODE HERE ***"

    def __iter__(self):
        "*** YOUR CODE HERE ***"

Use OK to test your code:

python3 ok -q IteratorRestart

Question 3: Hailstone

Write a generator that outputs the hailstone sequence from Lab 01.

Here's a quick refresher on how the hailstone sequence is defined:

  1. Pick a positive integer n as the start.
  2. If n is even, divide it by 2.
  3. If n is odd, multiply it by 3 and add 1.
  4. Continue this process until n is 1.
def hailstone(n):
    """
    >>> for num in hailstone(10):
    ...     print(num)
    ...
    10
    5
    16
    8
    4
    2
    1
    """
    "*** YOUR CODE HERE ***"

Use OK to test your code:

python3 ok -q hailstone

Question 4: Merge

Implement merge(r0, r1), which takes two iterables r0 and r1 whose elements are ordered. merge yields elements from r0 and r1 in sorted order, eliminating repetition. You may also assume r0 and r1 represent infinite sequences; that is, their iterators never raise StopIteration.

See the doctests for example behavior.

def merge(r0, r1):
    """Yield the elements of strictly increasing iterables r0 and r1 and
    make sure to remove the repeated values in both.
    You can also assume that r0 and r1 represent infinite sequences.

    >>> twos = naturals(initial = 2, step = 2)
    >>> threes = naturals(initial = 3, step = 3)
    >>> m = merge(twos, threes)
    >>> type(m)
    <class 'generator'>
    >>> [next(m) for _ in range(10)]
    [2, 3, 4, 6, 8, 9, 10, 12, 14, 15]
    """
    i0, i1 = iter(r0), iter(r1)
    e0, e1 = next(i0), next(i1)
    "*** YOUR CODE HERE ***"

Use OK to test your code:

python3 ok -q merge

Submit

Make sure to submit this assignment by running:

python3 ok --submit