Primes - Why do the test cases involve 0 and negative numbers


#1

Why do the test cases involve 0 and negative numbers when these values are not traditionally even considered in regards to whether a number is prime or not and when the question gives no indications of how these cases should be handled?


Is_prime problem: Isn't 7 a prime number ?! It gives me this message "Your function fails on is_prime(-7). It returns True when it should return False." Help
#2

We can often times get away with a brute force method that assumes only valid inputs will be given, especially if we are the only user. The minute our code gets out into the ether, we can no longer be sure that the program will always be given valid inputs.

It is up to the programmer to build in safeguards against invalid inputs. Now assuming the inputs will always be numbers, one safeguard would be to refuse any value less than 2. There are no primes smaller than 2. Another would be to truncate floats by converting any input that fails the first test to a natural number. All primes are counting numbers.

That would be enough to guarantee than any number you input will have a result, or be rejected. I’m not even certain that the test cases include a float because it has never been necessary in order to pass. It bears noting, though.

x < 2 ? return false

x = int(x)

Should any non-numeric inputs occur, both of the above lines will choke, but it will be on the first that an exception is raised.

>>> 'a' < 2
Traceback (most recent call last):
  File "<pyshell#215>", line 1, in <module>
    'a' < 2
TypeError: unorderable types: str() < int()
>>> 

We can busy ourselves with creating all kinds of type detection, or we can turn to Python’s exception handling tools that are at our disposal. The following kicks butt and takes a number…

def is_prime(x):
  try:
    if x < 2: return False
    return True
  except TypeError:
    return "Invalid input."

For a test run,

 > is_prime('a')
=> 'Invalid input.'
 > is_prime(-1)
=> False
 > is_prime(2)
=> True  

Of course any number that fails the less than 2 test will be True at this point, but it bears noting, 2 returns True out of the gate.

We have a short and effective way to deal with values that cannot be used in comparison with a number. This brings up another special type of input, which our exception handling does not need to confront, booleans.

 > is_prime(False)
=> False
 > is_prime(True)
=> False   

These two values cast to 0 and 1 respectively, but both pass the less than 2 test so return False.

At this point we are free to cast x as an integer and proceed with the trial division as prescribed in the lesson. Of course we are well beyond the lesson parameters, but the rest falls back in line with the instructions.

Bottom line is you will have a tougher function that gives predictible results and does not raise any exceptions on bad inputs. Don’t let this segue you from your studies, but keep it in your kit going forward.


def is_prime(x):
  try:
    if x < 2: return False
    u = int(x ** 0.5) + 1
    x = int(x)
    for n in range(2, u):
      if x % n: continue
      else: return False
    return True
  except TypeError:
    return "Invalid input."

#3

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.