def number_sequence_generator():
a = 0
while True:
yield a
a += 1
Generators are a simple tool for creating iterators
They are just functions with yield instead of return statement whenever they want to return data
if __name__ == '__main__':
generator = number_sequence_generator()
next(generator) # 0
next(generator) # 1
next(generator) # 2
Each time next() is called on it, the generator resumes where it left off. It remembers all the data values and which statement was last executed
def finite_generator():
for i in range(4):
yield i ** 2
if __name__ == '__main__':
generator = finite_generator()
next(generator) # 0
next(generator) # 1
next(generator) # 4
next(generator) # 9
next(generator) # StopIteration error
def finite_generator():
a = 0
while True:
yield a ** 2
a += 1
if __name__ == '__main__':
generator = finite_generator()
next(generator) # 0
next(generator) # 1
next(generator) # 4
next(generator) # 9
next(generator) # 16
next(generator) # 25
# ...
They should be lazy whenever it's possible
for i in range(100000000000):
print(i)
e.g. this will not cause your computer to die in python 3.x. Cause all numbers are generated one after another, not all at once
though it will in python 2.x, therefore xrange should be used in python 2.x
for i_square in (i ** 2 for i in range(100000000000)):
print(i_square)
Yet more concise way to write iterators
Unit testing
Integration testing
System testing
Sanity testing
Smoke testing
Regression testing
from unittest import TestCase
class SimpleTests(TestCase):
@classmethod
def setUpClass(cls):
print("I'm executed once before all tests in class")
def setUp(self):
print("I'm executed before each test in class")
def test_something(self):
self.assertEqual(1, 2, "Some test comment")
@classmethod
def tearDownClass(cls):
print("I'm executed once after all tests in class")
def setUp(self):
print("I'm executed after each test in class")