Need help understanding why this won't work


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

It returns True for 4 when it shouldn’t and I honestly can’t figure out why this code isn’t working :confused:


#2

Are we checking x minus 1 or x for divisibility?


#3

Hello mtf,
Checking if that value of x - 1 (x being 4 so -1 would be 3) 3 % n == 0.
My code is a little confusing at the moment I’ve been updating it as I’m testing things that I think should work but aren’t returning the correct answer.


#4

Here is the original code I had written for the problem.

def is_prime(x):
  if x < 2:
    return False
  else:
    for n in str(x):
      if (int(x) - 1) % (int(n) + 2) == 0:
        return False
      elif (int(x) - 1) % (int(n) + 2) != 0:
        return True

#5

But isn’t x the number we are checking? Where does x - 1 come into it?


#6

it’s checking for prime numbers so a number divisible by itself we know is prime (4 % 4 == 0) so I subtract 1 from x.


#7

Here were the instructions to the problem that also ask to subtract 1 from x.

Define a function called is_prime that takes a number x as input.

For each number n from 2 to x - 1, test if x is evenly divisible by n.

If it is, return False.

If none of them are, then return True.


#8

That describes the range, not the input that we are checking.

The intention of this exercise was not to discuss range, as much as core concept, Prime numbers and how we can find them.

If the author had felt there was enough time and space, and that learners had the energy to sit through and absorb some of the finer details, they might have included them in the lesson. But, space is limited and one suspects they believed the learner’s attention span is, too, at least in this instance.

That said,

c = a * b

which means,

b = c / a

and

a = c / b

This means that as a gets bigger, b gets smaller, and vice-versa, which also explains why times tables always mirror one half against the other.

The two equations have opposite slopes, in that one is positive, the other negative, and their graphs intersect. The solution for that intersection is the square root of c.

a == b so a ** 2 == c AND b ** 2 == c

#9

I tried this out on PyCharm with different integers for the variable a and it seems to be working fine but when I submit the function on the site it returns “None”.

a = 5


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


print is_prime(a)

#10

The console echoes the final outcome of the function, which is None since the program ended when the function was done.

Consider the range…

2, x

what if x is 2? The loop won’t run since the upper bound is 1. We need a return value for this special case at the very end of the function.


#11

Here I added the elif to include if x == to 2 but I still get None

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

#12

Given all the false positives and returns on every branch I fail to see how, unless x == 3 is slipping through the cracks. The false positives are the result of imposing an either or conditional on divisibility. In this case we can only make a decision one way… It’s divisible. There is no else clause in this conditional. We only want to act when a number proves divisible. That’s what makes it not Prime. The fall through from this loop will be a Prime.


>>> for i in range(2, 3):
	print (i)
	
2
>>> 

Nope, 3 is not slipping through the cracks. My own myopic blindness is keeping me from seeing where a None could be returned from your (most recent) code. Let’s keep looking.


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

>>> is_prime(3)  # not divisible by 2 and the range ends. Prime.
True
>>> is_prime(2)
True
>>> is_prime(1)
False
>>> is_prime(4)  # divisible by 2. Not Prime.
False
>>> is_prime(5)  # not divisible by 2, 3, or 4 so range ends. Prime.
True
>>> is_prime(9)  # not divisible by 2 but returns True, anyway. False positive.
True
>>> 

#13

Hey mtf,
so I got some help from a friend and explained my error I have in the code.

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

The last else statement ends the loop before it checks all the other numbers, so the last else statement needed to be moved outside of the loop but still inside the function.


#14

You should be getting a linter warning that there is no break in the loop. for..else has conditions of its own to comply with. As stated earlier, no else is needed. Just let the loop play out and return True as the final resolve of the function.


#15

I didn’t get any warning but I see what you’re saying and edited my code to fix that. Thank you for the explanation! :slight_smile:


#16

How are you with understanding the whole range question?


#17

I understood the range part I think I just confused myself with x - 1 forgetting it stops before the value of x


#18

… and does not include it.

Above we got a little deeper into this. As you progress through the course and come back around for review, delve into that. Don’t forget, now. But now is not really the time. Keep forging ahead.


#19

Yeah some bad wording I used there I edited it to correct it :stuck_out_tongue:
ex…
for i in range 10 would = to 1 2 3…7 8 (and stop at -->) 9


#20

I’m less concerned about your wording than you getting this course under your belt and coming back to this conversation. What a difference it will be when you have some more tools. Spend some time on each step and lesson, enough to review the docs on any new keywords, but otherwise, keep moving forward. The questions you have now will come up in review unless you’ve already solved them.