Search code examples
pythonbooleanor-operator

Ordering of evaluation using boolean or


So I've got this snippet of code. And it works (It says 1 is non-prime).:

n = 1
s = 'prime'
for i in range(2, n / 2 + 1):
    if n == 1 or n % i == 0:
        s= 'non-' +s
        break

print s

My problem is that if I change the fourth line to: if n % i == 0 or n == 1:, it doesn't work (it says 1 is prime.)

Why is that? Since I'm using or should it be that either one of them is True so the order doesn't count?

(I'm still learning about boolean so I may be making some basic mistake.)

Thanks in advance!

EDIT: Thanks for the answers; I never realized my issue with the range() function. And about the code working and not working: I have no idea what happened. I may have made some mistake somewhere along the way (maybe forgot to save before running the script. Although I could've sworn that it worked differently :P ). Maybe I'm just getting tired...

Thanks for the answers anyways!


Solution

  • The precedence is fine. % is evaluated first, then ==, then or, so it breaks down into:

         ___or___
        /        \
      ==          ==
     /  \        /  \
    n    1      %    0
               / \
              n   i
    

    Your problem is that your for loop is not being executed at all, so that s is still set to "prime".

    The range 2,n/2+1 when n is 1 equates to 2,1 which will result in the body not being executed.

    In fact it won't be executed where n is 2 either since 2/2+1 is 2 and the range 2,2 doesn't execute. The values are the start and terminating value, not start and end (last) value - it's just fortuitous there that 2 is considered a prime by virtue of the initialisation of s :-)

    Try this instead:

    #!usr/bin/python
    
    n = 9
    s = 'prime'
    if n == 1:
        s = 'non-prime'
    else:
        i = 2
        while i * i <= n:
            if n % i == 0:
                s= 'non-prime'
                break
            i = i + 1
    print s
    

    It's wasteful going all the way up to n/2, the square root of n is all that's needed.