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 -

``````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 -

``````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 -

``````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