"""
Created on Mon Mar 14 14:40:53 2016
@author: Kirby Urner
Create an iterable that gives back successive prime numbers in
two different ways: as a class and as a generator function.
Trial by division involves accumulating all primes so far and
admitting new candidates to the club only if no prime up to
the sqrt of same, divides with no remainder.
"""
class Primes:
def __init__(self):
self.candidate = 1
self._primes_so_far = [2] # first prime, only even prime
def __iter__(self):
"""I'm already an iterator so just return me as is"""
return self
def __next__(self):
"""proof I'm an iterator"""
while True:
self.candidate += 2 # check odds only from now on
for prev in self._primes_so_far:
if prev**2 > self.candidate:
self._primes_so_far.append(self.candidate)
return self._primes_so_far[-2]
if not divmod(self.candidate, prev)[1]: # no remainder!
break
def primes():
"""generate successive prime numbers (trial by division)"""
candidate = 1
_primes_so_far = [2] # first prime, only even prime
yield _primes_so_far[-1]
while True:
candidate += 2 # check odds only from now on
for prev in _primes_so_far:
if prev**2 > candidate:
yield candidate # surrender control at this point!
_primes_so_far.append(candidate)
break
if not divmod(candidate, prev)[1]: # no remainder!
break # done looping
#p = Primes() # class based iterator
#print([next(p) for _ in range(30)]) # next 30 primes please!
p = primes() # generator function based iterator
print([next(p) for _ in range(3000)]) # next 30 primes please!