Solution 1

class RmotrRange(object):
    def __init__(self, start, end, step=1):
        self.start = start
        self.end = end
        self.step = step
        self.current = start

    def __iter__(self):
        return self

    def __next__(self):
        if self.current >= self.end:
            raise StopIteration()

        num = self.current
        self.current += self.step
        return num

    next = __next__

rmotr_range = RmotrRange

Solution 2

def rmotr_range(start, end, step=1):
    current = start
    while current < end:
        num = current
        current += step
        yield num

Range Generator

In this assignment we're going to build a generator (as a function) that mimics the well known range function from Python. As you know, in Python 3, range returns an iterator (in Python 2 we have xrange).

The general usage of our range generator is going to be quite similar to the Python's one:

for num in rmotr_range(start=0, end=3):
    print(num)

>>> 0
>>> 1
>>> 2

for num in rmotr_range(start=1, end=5):
    print(num)

>>> 1
>>> 2
>>> 3
>>> 4

for num in rmotr_range(start=0, end=6, step=2):
    print(num)

>>> 0
>>> 2
>>> 4

Extra: Try to solve this assignment also with an Iterator (a class with __next__ and __iter__ method). Check the solutions for both Iterator and generator based solutions.

Test Cases

test with step - Run Test

import pytest

def test_with_step():
    gen1 = iter(rmotr_range(2, 10, 2))
    assert next(gen1) == 2
    assert next(gen1) == 4
    assert next(gen1) == 6
    assert next(gen1) == 8
    with pytest.raises(StopIteration):
        next(gen1)

test starting from zero - Run Test

import pytest

def test_starting_from_zero():
    gen1 = iter(rmotr_range(0, 3))
    assert next(gen1) == 0
    assert next(gen1) == 1
    assert next(gen1) == 2
    with pytest.raises(StopIteration):
        next(gen1)

test starting over zero - Run Test

import pytest

def test_starting_over_zero():
    gen1 = iter(rmotr_range(3, 6))
    assert next(gen1) == 3
    assert next(gen1) == 4
    assert next(gen1) == 5
    with pytest.raises(StopIteration):
        next(gen1)
def rmotr_range(start, end, step=0): pass