6/15 - is_prime: Issue with non-primes being returned as 'True'


#1

Hello,

I haven't been able to find anything similar to the issue I am having and was hoping for some insight. I am able to return prime numbers as 'True' fine, however a handful of non-prime numbers return as prime. See bellow:

def is_prime(x) :
if x < 2 :
    return False
elif x == 3 or x == 2:
    return True
else:
    for i in range(2, x-1) :
        if x % i == 0 :
            return False
        else :
            return True

When the code tries to run 9 or 15 in the function it returns as true, however I am not quite sure why... They are both multiples of 3, is my elif statement interfering with the else statement somehow?

Thank you for your help,

Sean


#2

Hi @seanph16,

What helps to troubleshoot most problems is to use debug print statements throughout your code. For example, to see if 9 is being affected by your elif, just change its return value like so:

def is_prime(x) :
    if x < 2 :
        return False
    elif x == 3 or x == 2:
        return "Should catch only 2 and 3"
    else:
        for i in range(2, x-1):
            if x % i == 0 :
                return False
            else :
                return True

for i in range(10):
    print "%s is prime? %s" % (i, is_prime(i))

and will yield:

0 is prime? False
1 is prime? False
2 is prime? Should catch only 2 and 3
3 is prime? Should catch only 2 and 3
4 is prime? False
5 is prime? True
6 is prime? False
7 is prime? True
8 is prime? False
9 is prime? True

So there goes the answer to that... :smile:


#3

Now as to why 9 is being evaluated as prime, peppering your code with debug statements like so:

def is_prime(x) :
    if x < 2 :
        return False
    elif x == 3 or x == 2:
        return "Should catch only 2 and 3"
    else:
        for i in range(2, x):
            print "  %s %% %s = %s" % (x, i, x % i)
            if x % i == 0 :
                
                return False
            else:
                return True

for i in range(10):
    print "%s is prime? %s" % (i, is_prime(i))

will yield:

0 is prime? False
1 is prime? False
2 is prime? Should catch only 2 and 3
3 is prime? Should catch only 2 and 3
  4 % 2 = 0
4 is prime? False
  5 % 2 = 1
5 is prime? True
  6 % 2 = 0
6 is prime? False
  7 % 2 = 1
7 is prime? True
  8 % 2 = 0
8 is prime? False
  9 % 2 = 1
9 is prime? True

Can you spot the problem now? :smile:

You are exiting your for loop and returning True after evaluating only one value. You need to indent your else back one level like so:

def is_prime(x) :
    if x < 2 :
        return False
    elif x == 3 or x == 2:
        return "Should catch only 2 and 3"
    else:
        for i in range(2, x):
            print "  %s %% %s = %s" % (x, i, x % i)
            if x % i == 0 :
                
                return False
          
            # now, if your condition is not met, it will continue to loop!

        # and at this point, when the for loop is over, if it has not returned
        # anything as False, it will then resort to this else which will return True
        else:
            return True

for i in range(10):
    print "%s is prime? %s" % (i, is_prime(i))

and now it will yield the expected result:

0 is prime? False
1 is prime? False
2 is prime? Should catch only 2 and 3
3 is prime? Should catch only 2 and 3
  4 % 2 = 0
4 is prime? False
  5 % 2 = 1
  5 % 3 = 2
  5 % 4 = 1
5 is prime? True
  6 % 2 = 0
6 is prime? False
  7 % 2 = 1
  7 % 3 = 1
  7 % 4 = 3
  7 % 5 = 2
  7 % 6 = 1
7 is prime? True
  8 % 2 = 0
8 is prime? False
  9 % 2 = 1
  9 % 3 = 0
9 is prime? False

Hope this helped! :smile:


Is_prime
#4

Wow, great answer and great debugging tips denisaltroy! Thank you for taking the time for writing out your responses, crystal clear.

Cheers,

Sean


#5

My pleasure!

Also one little thing I forgot to write is regarding your for condition:

for i in range(2, x-1) :

I understand why you typed x-1 but you need not the -1 as, although the first parameter of range() is inclusive, the second parameter is exclusive, meaning that using range(2,7), it will evaluate 2 but not evaluate 7:

for i in range(2, 7):
    print "  7 %% %s = %s" % (i, 7 % i)
    if 7 % i == 0 :
                
        print "False"
else:
    print "True"

will yield:

  7 % 2 = 1    # starts with 2!
  7 % 3 = 1
  7 % 4 = 3
  7 % 5 = 2
  7 % 6 = 1    # but stops at 6!
True

Cheers! :smile:


#6

hey man! loved the debugging technique..thanks a ton. :smile:


#7

Such a simple thing to move that 'else' statement back a few spaces, never would have figured that out :frowning:


#8

Hi @hackerrankwes,

One trick I like to use sometimes is to try and read the code outloud to myself or write every step beside in plain english. I added the print statements afterward to help me demonstrate but this is actually how I figured this one out:

for i in range(2, x):  # take one number from 2 to 9
    if x % i == 0 :    # if 9 is divisible by this number
        return False   # it is not prime
    else:              # otherwise if 9 is not divisible by this number
        return True    # it is prime

While it should read:

for i in range(2, x):  # take one number from 2 to 9
    if x % i == 0 :    # if 9 is divisible by this number
        return False   # it is not prime
else:                  # otherwise if 9 is not divisible by any number from 2 to 9
    return True        # it is prime

This way it's easy to spot the logic problem and to see that we mean for... else rather than if... else


#9

I did it the long way heh

def is_prime(x):
    if x == 0 or x == 1 or x == 4:
        return False
    elif x < 0:
        return False
    else:
        if x == 2 or x==3 or x == 5 or x == 7:
            return True
    if x > 5:
        if x%2 == 0:
            print "not prime"
            return False
        elif x%3 == 0:
             print "not prime"
             return False
        elif x%4 == 0:
             print "not prime"
             return False
        elif x%5 == 0:
             print "not prime"
             return False         
        elif x%6 == 0:
            print "not prime"
            return False
        elif x%7 == 0:
             print "not prime"
             return False
        elif x%8 == 0:
             print "not prime"
             return False
        elif x%9 == 0:
             print "not prime"
             return False 
        else:
            return True


#10

My code fails on the number 9, any help?

def is_prime(x):
if x < 2:
return False
elif x==2 or x==3:
return True
else:
for n in range(2,x):
if x % n == 0:
return False
else:
return True


#11

Hi @maameli, his is exactly what this thread is about, I'm sure if you read it from the beginning you will find the answer to your question :smile:


#12

@mesolen, sorry for the late answer I had not noticed it before today!

Not only you did it the long way but doing so, your function will break if we ask it to evaluate a number bigger than 9... :confused:

Anytime you find yourself repeating or copy pasting a chunk of code, ask yourself if you wouldn't be better served by a loop! That's what they are for :smile:


#13

don't understand why this code won't work. Can someone help me please.

' def is_prime (x):
    n = range (2, x-1)
    if x % n 0:
        return False
    else:
        return True 
'

#14

def is_prime(x):
if x < 2:
return False
else:
for n in range(2, x):
if x % n == 0:
return False
break
else:
return True

I didn't test 2, 3 by "elif" and set the range to "range(2,x)", it seems worked. When x is 2 (the range is range(2, 2)), you can test "print 2 in range(2,2)", which results False. Then code logical goes to the second "else" instead of going into the "for". For 3 , it is just a normal case like 4, 5,6.....

If any wrong, pls tell me. Thanks a lot


#16

The Best Answer ...Thanks !


#17
def is_prime(x):
    p = True
    if x < 2:
        p = False
    elif x >= 2:
        for n in range(2,x-1):
            if x%n == 0:
                p = False
                break
    return p

#18

my code:

def is_prime(x):
score = 0
if x < 2:
return False
elif x == 2 or x == 3:
return True
else:
for n in range(2,x-1):
if x % n == 0:
score +=1
if score > 0:
return False
else:
return True


#19

Awesome mate! Great advice, thanks!


#20

OMG, I've been trying to figure this out a half an hour!
THANK YOU for explaining this in plain English!
:heart:


#21

Hi guys,
Here’s how I passed the exercise:


def is_prime(x):
  if x == 0 or x == 1 or x < 0:
    return False
  else:
    for n in range(2, x):
    	if x % n == 0:
    		return False
    else:
      return True

I, of course, used ideas from this thread.

Cheers!