bdhar
bdhar

Reputation: 22983

Prime numbers iterator

I wrote a piece of code to print n prime numbers:

class PrimeGen:
    def __init__(self):
        self.current = 2
    def genPrime(self, num):
        for i in range(num):
            while 1:
                for j in range(2, self.current/2 + 1):
                    if self.current % j == 0:
                        self.current = self.current + 1
                        break
                else:
                    break
            print self.current,
            self.current = self.current + 1

if __name__ == '__main__':
    p = PrimeGen()
    p.genPrime(5)

The code works fine. I get 2 3 5 7 11 as output. I tried to make the class iterable. Code below. But the output is 0 1 2 3 4. I could not quite figure out where I am going wrong. Any help is appreciated. Thanks

class PrimeIter:
    def __init__(self):
        self.current = 1

    def next(self):
        self.current = self.current + 1
        while 1:
            for i in range(2, self.current/2 + 1):
                if self.current % i == 0:
                    self.current = self.current + 1
                    break # Break current for loop
            else:
                break # Break the while loop and return
        return self.current

    def __iter__(self):
        return self

if __name__ == '__main__':
    p = PrimeIter()
    for p in range (5):
        print p,

Upvotes: 1

Views: 8737

Answers (3)

user12489525
user12489525

Reputation: 11

Iterator for generating prime numbers upto some maximum m:

class PrimeIter: 
    def ___init__(self, m): 
       self.max = m

    def __iter__(self):
       self.n = 1
       return self

    def __next__(self):
        if self.n < self.max:
           self.n += 1
           i = 2
           while i < (self.n//2+1):
                if self.n % i == 0:
                   self.n = self.n+1
                   if self.n > self.max:
                       raise StopIteration
                   i = 1
                i += 1
           else:
                return self.n
       else:
            raise StopIteration

 p = PrimeIter (100)        
 for i in p:
     print(i, end=' ')

Upvotes: 1

icktoofay
icktoofay

Reputation: 129059

You're using this code to print out the values:

for p in range (5):
    print p,

If you look at that, it's printing the values of the range. You probably want to print things from the prime iterator. itertools has some functions that may help:

for prime in itertools.islice(p, 5):
    print prime,

Additionally, you may want to consider using a generator:

def primes():
    current = 1
    while True:
        current += 1
        while True:
            for i in xrange(2, current // 2 + 1):
                if current % i == 0:
                    current += 1
                    break
            else:
                break
        yield current

Upvotes: 4

Gabe
Gabe

Reputation: 86768

Your problem is that you are reusing the variable p in your test code:

if __name__ == '__main__':
    p = PrimeIter() # first declaration of p
    for p in range (5): # second declaration of p
        print p,   # uses second declaration of p

I'd recommend using itertools.islice to get the first 5 elements of an iterator:

if __name__ == '__main__':
    p = PrimeIter()
    for x in itertools.islice(p, 5):
        print x,

Upvotes: 1

Related Questions