You can solve this either with a single
while loop, or a single
for loop. You certainly don’t need both.
Having read several of your threads, I think a common source of confusion for you with these exercises is that you’re diving in and attempting to write code to solve the problem without fully understanding what the problem is or what the process you need to follow to get the result should be.
Perhaps it would help you to take a step back from the code, and consider how you would solve the problem if you had to do the math by hand with a pencil and paper. If you can’t write out a step-by-step of how you’d do this manually, with every decision you’d make to determine if a given number is prime, then you’re going to struggle to create a program that does the job.
Yes, your code in this instance is definitely not great. I’m not sure if you’re just racing through the content, but I don’t think you’re taking the time to make sure you understand the topics of each lesson before progressing along to the next. By your own admission, you’re not 100% on using the
while loop here so I have to wonder whether there’s other things in your code that you’re not completely sure of but are simply rolling with because you’ve managed to get it to work.
What @ionatan means (I presume) is that you ought to add
print statements inside your function, which will allow you to follow in the console how Python is stepping through your program and see exactly what it’s doing.
I’ve taken the liberty of modifying your code as ionatan suggested, and included some
print statements so we can follow the process Python takes when running it. Here’s my amended code:
def is_prime(x, z):
print "Entering the while loop"
while x > 0 and x < z:
print "Inside the while loop"
print "Entering the for loop"
for n in range(2,x - 1):
print "Inside the for loop"
if x % n == 0:
print "%d divided by %d returns %d. Not prime." % (x, n, (x%n))
print "%d divided by %d returns %d. Possibly prime?" % (x, n, (x%n))
print "Inside the for ELSE block!"
If we run your code, by calling
print is_prime(1, 92348238) we get the following back from Python:
Entering the while loop
Inside the while loop
Entering the for loop
Inside the for ELSE block!
Now we know the route that Python is taking through your program, we can look at why it doesn’t work as intended.
We can see that Python gets to the point of beginning the
for loop without a problem, so programmatically there’s nothing wrong with your code up to the line
for n in range(2,x - 1):
Notice that Python never enters your
for loop as we don’t see the output
Inside the for loop in the console; instead, we see that Python has progressed into the
else clause that trails your
for loop. Once it’s here, it carries out your
break statement which terminates the
while loop, and that’s the final line of your function.
You might be asking why we see
None as the final output to the console.
We’ve told Python to print the output of your
is_prime function by using
print is_prime(1, 92348238). We’re expecting some output from your function, since we’re trying to print it, but the way you tell the function what the output should be is with the
return statement. None of the
return statements in your code ever get executed, so instead Python gives you a default output in the form of
None. This is not your program telling you there were no prime numbers between 1 and 92348238.
So, finally, why does Python never enter your
for statement iterates over the elements of a sequence, such as a tuple or a list. When Python reaches your
for statement, it evaluates the iterable object to create the sequence it must loop through. In your code, you’re telling Python to iterate through
range(2, x - 1). Python needs to evaluate that and create an iterable sequence before it can carry on.
Your problem is that, if we call your function by using
is_prime(1, 92348238) then
x = 1. In turn, this means our
range(2, 0). This is invalid, and we can see why if we just print that
range to the console:
>>> print range(2,0)
The reason this doesn’t work is because in the
range function, we can provide three parameters: start, stop, and step like so:
If you don’t specify the value for step, it defaults to
1. We can’t start at
2 and add any amount of
1s to reach 0, so the output is an empty list.
The default behaviour for
for when presented with an empty list is to proceed to the
else statement, if there is one. This is the behaviour we see in your program.
(Your code also won’t work even if we provided a larger value for
x, say 7. I won’t go into the why of that in this post… it’s long enough already!)
Sorry for the epic long post, but hopefully this’ll help you see where you’ve gone wrong. I would again strongly encourage you to think about the manual process you’d follow to check whether a number is prime, and then once you’re sure that’s right try and implement it in Python.