Skip to content
10 changes: 9 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,9 @@
# PythonHW_Iterator_Generator
### PythonHW_Iterator_Generator

Contains Python 3 code for classes IteratorEnhancedRange and GeneratorEnhancedRange.

Both work similar to standard Python range(int) function, except they are able work with float arguments.
Both classes require at least one argument. All arguments are positional:
start (default = 0), end (no default, required argument), step (default = 1).
One specified argument (x) is interpreted as (0, x, 1).
Two arguments are interpreted as start and end, respectively.
84 changes: 84 additions & 0 deletions RangeEnhancedIterator_Generator.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
class IteratorEnhancedRange:

def __init__(self, *args):
#Arguments are: start (default = 0), end (no default, required argument), step (default = 1)
self.args = args
Comment thread
agbragin marked this conversation as resolved.
for arg in args:
if not (type(arg) == int or type(arg) == float):
raise Exception("Arguments must be numeric")
if len(args) == 1:
self.start = 0
self.end = self.args[0]
self.step = 1
elif len(args) == 2:
self.start = self.args[0]
self.end = self.args[1]
self.step = 1
elif len(args) == 3:
if self.args[2] == 0:
raise Exception("Unable to range with step = 0")
self.start = self.args[0]
self.end = self.args[1]
self.step = self.args[2]
else:
raise Exception("IteratorEnhancedRange requires at least one, but no more than three arguments")
self.startediter = False
Comment thread
agbragin marked this conversation as resolved.

def __iter__(self):
return self

def __next__(self):
if (self.step / abs(self.step)) * self.start >= (self.step / abs(self.step)) * self.end:
raise StopIteration
else:
if self.startediter is False:
self.startediter = True
return self.start
else:
if (self.step / abs(self.step)) * (self.start + self.step) >= (self.step / abs(self.step)) * self.end:
raise StopIteration
else:
self.start += self.step
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

self.start change during the iteration seems to be not obvious, isn't it?

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I don't understand this one. += self.step seems very obvious to me

return self.start

def __call__(self):
return self


class GeneratorEnhancedRange:

def __init__(self, *args):
#Arguments are: start (default = 0), end (no default, required argument), step (default = 1)
self.args = args
Comment thread
agbragin marked this conversation as resolved.
for arg in args:
if not (type(arg) == int or type(arg) == float):
raise Exception("Arguments must be numeric")
if len(args) == 1:
self.start = - 1
self.end = self.args[0]
self.step = 1
elif len(args) == 2:
self.start = self.args[0] - 1
self.end = self.args[1]
self.step = 1
elif len(args) == 3:
if self.args[2] == 0:
raise Exception("Unable to range with step = 0")
self.start = self.args[0] - self.args[2]
self.end = self.args[1]
self.step = self.args[2]
else:
raise Exception("GeneratorEnhancedRange requires at least one, but no more than three arguments")
self.startediter = False

def __iter__(self):
return GeneratorEnhancedRange.gener(self)

def gener(self):
while (self.step / abs(self.step)) * (self.start + self.step) < (self.step / abs(self.step)) * self.end:
self.start += self.step
yield self.start

def __call__(self):
return self

1 change: 1 addition & 0 deletions __init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

36 changes: 36 additions & 0 deletions tests/Tests_RangeEnhancedGenerator.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import unittest
from RangeEnhancedIterator_Generator import GeneratorEnhancedRange


class GeneratorTests(unittest.TestCase):

def test_on_range_w_one_arg(self):
self.assertEqual([n for n in GeneratorEnhancedRange(2)], [0, 1])

def test_on_range_w_two_args(self):
self.assertEqual([n for n in GeneratorEnhancedRange(2, 5)], [2, 3, 4])

def test_on_range_w_three_args(self):
self.assertEqual([n for n in GeneratorEnhancedRange(2, 7, 2)], [2, 4, 6])

def test_on_nonnumeric_args(self):
with self.assertRaises(Exception, msg = "Arguments must be numeric"):
example = GeneratorEnhancedRange(5, "o", -1)

def test_on_zero_step(self):
with self.assertRaises(Exception, msg = "Unable to range with step = 0"):
example = GeneratorEnhancedRange(5, 6, 0)

def test_on_wrong_number_of_args(self):
with self.assertRaises(Exception,
msg = "GeneratorEnhancedRange requires at least one, but no more than three arguments"):
example = GeneratorEnhancedRange()
with self.assertRaises(Exception,
msg = "GeneratorEnhancedRange requires at least one, but no more than three arguments"):
example = GeneratorEnhancedRange(2, 7, 2, 0)


if __name__ == '__main__':
unittest.main()


49 changes: 49 additions & 0 deletions tests/Tests_RangeEnhancedIterator.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import unittest
from RangeEnhancedIterator_Generator import IteratorEnhancedRange


class IteratorTests(unittest.TestCase):

def test_on_range_w_one_arg(self):
Comment thread
agbragin marked this conversation as resolved.
example = IteratorEnhancedRange(2)
self.assertEqual(next(example), 0)
self.assertEqual(next(example), 1)
self.assertRaises(StopIteration, next, example)

def test_on_range_w_two_args(self):
example = IteratorEnhancedRange(2,5)
self.assertEqual(next(example), 2)
self.assertEqual(next(example), 3)
self.assertEqual(next(example), 4)
self.assertRaises(StopIteration, next, example)

def test_on_range_w_three_args(self):
example = IteratorEnhancedRange(2, 7, 2)
self.assertEqual(next(example), 2)
self.assertEqual(next(example), 4)
self.assertEqual(next(example), 6)
self.assertRaises(StopIteration, next, example)

def test_on_nonnumeric_args(self):
with self.assertRaises(Exception, msg = "Arguments must be numeric"):
example = IteratorEnhancedRange(5, "o", -1)

def test_on_zero_step(self):
with self.assertRaises(Exception, msg = "Unable to range with step = 0"):
example = IteratorEnhancedRange(5, 6, 0)

def test_on_wrong_number_of_args(self):
with self.assertRaises(Exception,
msg = "IteratorEnhancedRange requires at least one, but no more than three arguments"):
example = IteratorEnhancedRange()
with self.assertRaises(Exception,
msg = "IteratorEnhancedRange requires at least one, but no more than three arguments"):
example = IteratorEnhancedRange(2, 7, 2, 0)

def tearDown(self):
print ('Tear down called')


if __name__ == '__main__':
unittest.main()

1 change: 1 addition & 0 deletions tests/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@