2

I wrote the code for a Python prime number generator, to generate the first 100 primes. But, somehow, I get non-primes like 22, 25, etc. in my output. I've rechecked it over and over again for hours now and still can't figure out where I went wrong... Please help!

Here's my code:

from math import sqrt

y=[2]
x=3

while len(y)!=100:
   for i in range (2,int(round(sqrt(x)+1))):
     if x%i==0:
        x=x+1

     else:
        y.append(x)
        x=x+1
        break

print(y)
Will
  • 21,498
  • 11
  • 84
  • 98
stephen
  • 45
  • 4
  • Checkout this stackoverflow page, might be useful: [Simple prime number generator python](http://stackoverflow.com/questions/567222/simple-prime-generator-in-python) – Just Ice Jul 25 '16 at 12:26

6 Answers6

7

I would have done it this way; a bit more Pythonic:

y = [2]
x = 3
while len(y) < 100:
    if all(x % i != 0 for i in range(2, int(round(sqrt(x) + 1)))):
        y.append(x)
    x = x + 1

print(y)

The all() function is very useful.

This is more similar to what you did; please note the break statement and what it does:

from math import sqrt

y=[2]
x=3

while len(y) != 100:
    is_prime = True
    for i in range (2, int(round(sqrt(x) + 1))):
        if x % i == 0:
            x += 1
            is_prime = False
            break # this means that x is not prime and we can move on, note that break breaks only the for loop
    if is_prime:
        y.append(x)
        x += 1

print(y)
Graham
  • 6,577
  • 17
  • 55
  • 76
Mr. Nun.
  • 707
  • 10
  • 26
  • 1
    +1 because this is the most pythonic way, but note that in the second case an `else` clause can be used on the `for` loop as I show in my answer – Chris_Rands Jul 25 '16 at 13:28
4

The other answers are correct, but none of them show that you can actually use an else clause on the for loop. Read more about this here. So you don't need the if is_prime: statement. The resulting code could look something like this.

 from math import sqrt

 y = [2]
 x = 3

 while len(y) != 100:
    for i in range (2, int(round(sqrt(x) + 1))):
        if x % i == 0:
            x = x + 1
            break

    else:
        y.append(x)
        x = x + 1
print(y)

Tip: x+=1 could replace x=x+1

Furthermore, as @user2346536, you can actually use a much more efficient algorithm for calculating the prime numbers, which will be important if you are looping over large numbers.

Mr. Nun.
  • 707
  • 10
  • 26
Chris_Rands
  • 30,797
  • 12
  • 66
  • 100
2

the content of your else should be outside the for loop. Here you are appending x to your array as soon as it failed to be divided by "at least one of the i" instead of "failing to be divided by each of the i"

Also this algorithms is very inefficient. For a fast one try: https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes

from math import sqrt

y=[2]
x=3

while len(y)!=100:
    prime = True
    for i in [ i for i in y if i < sqrt(x) + 1 ]:
        if x%i==0:
            prime = False
            break

    if prime:
        y.append(x)

    x=x+1


print(y)

Note that I already optimized your algorithm by dividing only by previously found primes.

user2346536
  • 1,316
  • 2
  • 16
  • 40
0

Your test for a number being prime is wrong. You check whether a number is divisible by i going from 2 to sqrt(x) which is correct, but as soon as you hit a number which isn't a factor you assume that the number is prime, which is not correct. You have to check all numbers and if none is factor, then you can conclude that your number is prime:

from math import sqrt

y=[2]
x=3

while len(y)!=100:
    isPrime=True
    for i in range (2,int(round(sqrt(x)+1))):
        if x%i==0:
            x=x+1
            isPrime=False
            break             # See Mr Nun's answer
    if(isPrime):
        y.append(x)
        x=x+1

print(y)

As it was pointed out, this is not a very efficient solution. Check out the link in @user2346536's answer.

jotasi
  • 4,477
  • 2
  • 22
  • 45
0

As user2346536 said, your else should not be inside the loop. You will only ever look at the element for i = 2

How to do it :

from math import sqrt, ceil
prime_list = [2]
x = 2
while prime_list != 100:
    x += 1
    is_prime = True
    for element in range(2,int(ceil(sqrt(x)))):
        # if x is divided, then we go to next iteration
        if x%element == 0:
            is_prime = False
            break
    if is_prime:
        y.append(x)
HolyDanna
  • 584
  • 3
  • 11
0

Find Prime Numbers using Sieve of Eratosthenes rule

# Find Prime Numbers using Sieve of Eratosthenes rule
listPrime = []  #create a list and add 1 to 100 nunbers
for i in range (1, 101):
    listPrime.append (i)
print("The Numbers are: " + str(listPrime))

for i in range (2, 101):
    for j in range (i, 101): 
        z = i * j
        if (z > 100):
            break
        else:
            if z in listPrime:
                listPrime.remove(z)

print ("The Prime Numbers are: " + str(listPrime))