Reputation: 11
I understand that maybe with the use of "for" the code could be clear, but I would like to understand why this code isn't working. Also, the code is an adaptation for a 2008 MIT OCW class exercise in which the only functions that are allowed for use are the arithmetic ones, if, elif, else, print and while. Just to point it out, the code was supposed to print out the first 1000 prime numbers.
print '2, ' #Print the prime 2 to set only odd primes.
primesofar=3 #Set 3 as the first prime
primecounter=1 #Mark 3 as the first prime to test until 1000, otherwise the while below should test to 1001
primesupport=1 #Create primesupport with a integer value
while primecounter<1000:
primesupport=primesofar/2 #Create a support counter for test the prime. This counter only had to have the half value of the supposed prime, because we only need to try to divide by the primes that are lower than the half of the suppposed prime. In fact it would be better to test for values that are lower than the square root of the supposed prime, but we can't use square root operation yet.
while primesupport>0:
if primesofar%primesupport == 0:
primesupport=-1 #If the remainer of the division is 0, the number isn't prime because it will have more than two divisors so we set primesupport as -1 to exit the while and increase the current primesofar to the next odd number.
primesofar=primesofar+2
elif primesupport==1: #If primesupport is 1, we tested all the numbers below the half of the supposed prime which means the number is prime. So we print it, set the while exit and increase the number of primes counted and go to the next odd number.
print primesofar+', '
primesofar=primesofar+2
primesupport=-1
primecounter=primecounter+1
else:
primesupport=primesupport-1
I am thankfully for the fast responses and now I think that maybe there was a break in the code that I can't see. Because of this, I will try to write down what I think that the code was supposed to do in order to make it easier for you to point out where I am making a mistake. Let's start: primesofar receives 3; primecounter receives 1 and primesupport receives 1. The first while test primecounter and since primesupport is less than 1000, it enters the loop. Then, primesupport value is changed to 1 because 3/2=1 Since primesupport is greater than 0, it enters in the second while loop. The if condition is true (3%1=0) so the code enter the if, change the primesupport to -1 and increase primesofar by two.(now primesupport=-1 and primesofar=5) Here is has a problem because it leaves without printing 3, but let's continue. When it goes back to the second while it will receive a False, since -1 is not greater than 0. That will make the code test the first while and since primecounter was not changed, it will enter the loop again. Primesupport will now receive 2 (because 5/2=2) It will enter the second loop and pass throught all of it until the else condition. Primesupport will be decreased by one( primesupport now =1) and the while loop will continue entering in the elif now. That will print 5 increase primesofar to 7 decrease primesupport to leave the while loop and increase primecounter, going back to the first loop and start again. I confess that besides the 3 that is not being printed as expected, i can't see where i am making a mistake here. Hope you could point me out.
Thank you all for the help, especially FallenAngel, John Machin , DiamRem and Karl Knechtel for pointing out the error and by showing a debug method.
Upvotes: 1
Views: 1574
Reputation: 612
The problem with your code is that every time primecounter gets to 1, you are checking if primesofar%primesupport == 0, and it'll always do. So your program never enter the elif and the else part. thus prime counter never get increment. So it'll be a infinite loop.
You can check this by putting a print statement after if primesofar%primesupport == 0:
if primesofar%primesupport == 0:
print primesofar
You can correct it by check primesupport==1 before you check primesofar%primesupport == 0 :
print '2, ' #Print the prime 2 to set only odd primes.
primesofar=3 #Set 3 as the first prime
primecounter=1 #Mark 3 as the first prime to test until 1000, otherwise the while below should test to 1001
primesupport=1 #Create primesupport with a integer value
while primecounter<1000:
primesupport=primesofar/2 #Create a support counter for test the prime. This counter only had to have the half value of the supposed prime, because we only need to try to divide by the primes that are lower than the half of the suppposed prime. In fact it would be better to test for values that are lower than the square root of the supposed prime, but we can't use square root operation yet.
while primesupport>0:
if primesupport==1: #If primesupport is 1, we tested all the numbers below the half of the supposed prime which means the number is prime. So we print it, set the while exit and increase the number of primes counted and go to the next odd number.
print primesofar
primesofar=primesofar+2
primesupport=-1
primecounter=primecounter+1
elif primesofar%primesupport == 0:
primesupport=-1 #If the remainer of the division is 0, the number isn't prime because it will have more than two divisors so we set primesupport as -1 to exit the while and increase the current primesofar to the next odd number.
primesofar=primesofar+2
else:
primesupport=primesupport-1
this code will print 1000 primes for you.
And by the way, you can't connect a str and int with a +. you can just print the prime. Print statement will add newline automatically.
Upvotes: 0
Reputation: 82934
You need to test for primesupport == 1
BEFORE you test for primesofar % primesupport == 0
because any_integer % 1
is always 0, and the code that you want to execute when primesupport == 1
just isn't happening.
When you fix that, you will see that print primesofar+',
won't work ... you should be able to fix that yourself.
The most elementary effective debug techniques that you can deploy are (1) use a small set of data so that you can comprehend what is going on, and you can check the results with no more than a pencil and a piece of paper (2) print out what is happening.
(1) while primecounter < 5:
(2) After the 2nd while,
print "sofar, support, count", primesofar, primesupport, primecounter
Upvotes: 1
Reputation: 18727
I place some print
statements and this is the output that your program gives:
primesupport 1
primesofar 5
primesupport 2
primesupport 1
primesofar 7
primesupport 3
primesupport 2
primesupport 1
primesofar 9
primesupport 4
primesupport 3
primesofar 11
primesupport 5
primesupport 4
primesupport 3
primesupport 2
primesupport 1
primesofar 13
primesupport 6
primesupport 5
primesupport 4
primesupport 3
primesupport 2
primesupport 1
primesofar 15
primesupport 7
primesupport 6
primesupport 5
primesofar 17
primesupport 8
primesupport 7
...
Your code never enters elif primesupport==1:
block, so primecounter
never increases...
What is used for testing is :
while primecounter<2:
primesupport=primesofar/2
print 'primesupport %s' % primesupport
while primesupport>0:
if primesofar%primesupport == 0:
primesupport=-1
primesofar=primesofar+2
print 'primesofar %s' % primesofar
elif primesupport==1:
print primesofar+', '
primesofar=primesofar+2
primesupport=-1
primecounter=primecounter+1
print 'primesofar %s' % primesofar
print 'primesupport %s' % primesupport
print 'primecounter %s' % primecounter
else:
primesupport=primesupport-1
print 'primesupport %s' % primesupport
Reason is, final else
block decreases primesupport
up to 1, then in the next loop, if primesofar%primesupport == 0:
returns true and that block is executed, you increase primesofar
by 2 and start a new prime number check...
Upvotes: 1
Reputation: 61527
if primesofar%primesupport == 0:
primesupport=-1
When the code gets to this point, the inner loop will be broken without primecounter
changing. The code will repeat the same steps with the same primecounter
value, and necessarily get to the same point; there is no way to break the outer loop.
(Although the correct way to break out of a loop is to use break
.)
Upvotes: 1
Reputation: 31542
I think this is the issue:
you got stuck because primesofar=3 and in python 3/2 = 1, so in if primesofar%primesupport == 0: this is True because 1%1 = 0 in python and in the code of that if primesofar is 1+2, then primesofar is again 3 and you jump from a while to another in the eternity.
Upvotes: 1