Python Prime number checker [duplicate]

I have been trying to write a program that will take an inputed number, and check and see if it is a prime number. The code that I have made so far works perfectly if the number is in fact a prime number. If the number is not a prime number it acts strange. I was wondering if anyone could tell me what the issue is with the code.

a=2
num=13
while num > a :
  if num%a==0 & a!=num:
    print('not prime')
    a=a+1
  else:
    print('prime')
    a=(num)+1

the result given when 24 is inputed is: not prime not prime not prime prime

How would i fix the error with the reporting prime on every odd and not prime for every even


Solution 1:

You need to stop iterating once you know a number isn't prime. Add a break once you find prime to exit the while loop.

Making only minimal changes to your code to make it work:

a=2
num=13
while num > a :
  if num%a==0 & a!=num:
    print('not prime')
    break
  i += 1
else: # loop not exited via break
  print('prime')

Your algorithm is equivalent to:

for a in range(a, num):
    if a % num == 0:
        print('not prime')
        break
else: # loop not exited via break
    print('prime')

If you throw it into a function you can dispense with break and for-else:

def is_prime(n):
    for i in range(3, n):
        if n % i == 0:
            return False
    return True

Even if you are going to brute-force for prime like this you only need to iterate up to the square root of n. Also, you can skip testing the even numbers after two.

With these suggestions:

import math
def is_prime(n):
    if n % 2 == 0 and n > 2: 
        return False
    for i in range(3, int(math.sqrt(n)) + 1, 2):
        if n % i == 0:
            return False
    return True

Note that this code does not properly handle 0, 1, and negative numbers.

We make this simpler by using all with a generator expression to replace the for-loop.

import math
def is_prime(n):
    if n % 2 == 0 and n > 2: 
        return False
    return all(n % i for i in range(3, int(math.sqrt(n)) + 1, 2))

Solution 2:

def isprime(n):
    '''check if integer n is a prime'''

    # make sure n is a positive integer
    n = abs(int(n))

    # 0 and 1 are not primes
    if n < 2:
        return False

    # 2 is the only even prime number
    if n == 2: 
        return True    

    # all other even numbers are not primes
    if not n & 1: 
        return False

    # range starts with 3 and only needs to go up 
    # the square root of n for all odd numbers
    for x in range(3, int(n**0.5) + 1, 2):
        if n % x == 0:
            return False

    return True

Taken from:

http://www.daniweb.com/software-development/python/code/216880/check-if-a-number-is-a-prime-number-python

Solution 3:

def is_prime(n):
    return all(n%j for j in xrange(2, int(n**0.5)+1)) and n>1

Solution 4:

The two main problems with your code are:

  1. After designating a number not prime, you continue to check the rest of the divisors even though you already know it is not prime, which can lead to it printing "prime" after printing "not prime". Hint: use the `break' statement.
  2. You designate a number prime before you have checked all the divisors you need to check, because you are printing "prime" inside the loop. So you get "prime" multiple times, once for each divisor that doesn't go evenly into the number being tested. Hint: use an else clause with the loop to print "prime" only if the loop exits without breaking.

A couple pretty significant inefficiencies:

  1. You should keep track of the numbers you have already found that are prime and only divide by those. Why divide by 4 when you have already divided by 2? If a number is divisible by 4 it is also divisible by 2, so you would have already caught it and there is no need to divide by 4.
  2. You need only to test up to the square root of the number being tested because any factor larger than that would need to be multiplied with a number smaller than that, and that would already have been tested by the time you get to the larger one.