views:

186

answers:

4

I'm following the python tutorial at their site and I'm currently at the break continue section. I just tried this sample code.

>>> for n in range(2, 10):
...     for x in range(2, n):
...         if n % x == 0:
...             print n, 'equals', x, '*', n/x
...             break
...     else:
...         # loop fell through without finding a factor
...         print n, 'is a prime number'
... 
2 is a prime number
3 is a prime number
4 equals 2 * 2
5 is a prime number
6 equals 2 * 3
7 is a prime number
8 equals 2 * 4
9 equals 3 * 3

And instead of spitting out what it says above I get

3 is a prime number
4 equals 2 * 2
5 is a prime number
5 is a prime number
5 is a prime number
6 equals 2 * 3
7 is a prime number
7 is a prime number
7 is a prime number
7 is a prime number
7 is a prime number
8 equals 2 * 4
9 is a prime number
9 equals 3 * 3

It seems to me that it continues to run the inside for loop, but why would the tutorial not take this into account? Is it outdated for the latest interpreter build (I'm running xubuntu jaunty)?

I was able to fix it by adding the line

     else:
...                     if n != y:
...                             print n, 'is a prime number'
...                             y = n

but I am concerned this may be bad coding practice. Thank you for your help.

A: 

You may need to update your Python interpreter.

This code runs correctly for me (notice Python version number):

Python 2.6.1 (r261:67515, Dec  6 2008, 16:42:21) 
[GCC 4.0.1 (Apple Computer, Inc. build 5370)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> for n in range(2, 10):
...      for x in range(2, n):
...          if n % x == 0:
...              print n, 'equals', x, '*', n/x
...              break
...      else:
...          # loop fell through without finding a factor
...          print n, 'is a prime number'
... 
2 is a prime number
3 is a prime number
4 equals 2 * 2
5 is a prime number
6 equals 2 * 3
7 is a prime number
8 equals 2 * 4
9 equals 3 * 3
Chris Redford
+4  A: 

The output which you show contains ten times the string "x is a prime number". However, this string is printed in the else clause of the inner loop, and is as such executed at most once for each execution of the inner loop.

Since the outer loop performs eight iterations, "x is a prime number" cannot be printed more than eight times. Thus the output which you display cannot be brought about by the code shown.

Conclusion: something is fishy. Can you show the code as you executed it?


Edit: solved!

You incorrectly indented the else clause, such that Python interpreted it as belonging to the if statement. Python treats a tab as 8 spaces. Perhaps your editor displays tabs as 4 spaces. That way you may have missed this bug. As per PEP 8, please don't mix tabs and spaces, and preferably use four spaces to indent your code.

>>> for n in range(2, 10):
...     for x in range(2, n):
...         if n % x == 0:
...             print n, 'equals', x, '*', n/x 
...             break
...         else:
...             # loop fell through without finding a factor
...             print n, 'is a prime number'
... 
3 is a prime number
4 equals 2 * 2
5 is a prime number
5 is a prime number
5 is a prime number
6 equals 2 * 3
7 is a prime number
7 is a prime number
7 is a prime number
7 is a prime number
7 is a prime number
8 equals 2 * 4
9 is a prime number
9 equals 3 * 3
Stephan202
I see! Thank you for your help! I am just using the tty interactive interpreter but the bad indentation was entirely my fault. Silly user error. Thank you again.
Clordio
+1  A: 

My best guess is that your 'else:' statement isn't properly indented, and then your result is logical, check that you else's indentation is on level with 'for x'.

I.e. you use:

for n in range(2,10):
    for x in range(2,n):
     if n%x == 0:
         print(n, '=', x, '*', n/x)
         break
        else:
         print(n, 'is a prime')

instead of:

for n in range(2,10):
    for x in range(2,n):
     if n%x == 0:
      print(n, '=', x, '*', n/x)
      break
    else:
     print(n, 'is a prime')
SurDin
A: 

I think you have got indents wrong. If I take your code, and indent the else so that it is under the if statement, I get exactly the output that you are getting.

The code below reproduces your output,

for n in range(2, 10):
    for x in range(2, n):
        if n % x == 0:
            print n, 'equals', x, '*', n/x
            break
        else:
            # loop fell through without finding a factor
            print n, 'is a prime number'

while

for n in range(2, 10):
    for x in range(2, n):
        if n % x == 0:
            print n, 'equals', x, '*', n/x
            break
    else:
        # loop fell through without finding a factor
        print n, 'is a prime number'

Does what you want it to do.

Note the different in the indenting of the else.

Simon Callan
code that OP *uses* is indeed badly indented but there's no problem with the code he *posted*.
SilentGhost
Ah ha! Thank you all for your help!
Clordio