Prime number check acts strange [duplicate] - python

This question already has answers here:
How to create the most compact mapping n → isprime(n) up to a limit N?
(29 answers)
Closed 7 years ago.
I have been trying to write a program that will take an imputed 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 imputed 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?

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))

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

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

The two main problems with your code are:
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.
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:
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.
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.

This example is use reduce(), but slow it:
def makepnl(pnl, n):
for p in pnl:
if n % p == 0:
return pnl
pnl.append(n)
return pnl
def isprime(n):
return True if n == reduce(makepnl, range(3, n + 1, 2), [2])[-1] else False
for i in range(20):
print i, isprime(i)
It use Sieve Of Atkin, faster than above:
def atkin(limit):
if limit > 2:
yield 2
if limit > 3:
yield 3
import math
is_prime = [False] * (limit + 1)
for x in range(1,int(math.sqrt(limit))+1):
for y in range(1,int(math.sqrt(limit))+1):
n = 4*x**2 + y**2
if n<=limit and (n%12==1 or n%12==5):
# print "1st if"
is_prime[n] = not is_prime[n]
n = 3*x**2+y**2
if n<= limit and n%12==7:
# print "Second if"
is_prime[n] = not is_prime[n]
n = 3*x**2 - y**2
if x>y and n<=limit and n%12==11:
# print "third if"
is_prime[n] = not is_prime[n]
for n in range(5,int(math.sqrt(limit))):
if is_prime[n]:
for k in range(n**2,limit+1,n**2):
is_prime[k] = False
for n in range(5,limit):
if is_prime[n]: yield n
def isprime(n):
r = list(atkin(n+1))
if not r: return False
return True if n == r[-1] else False
for i in range(20):
print i, isprime(i)

Your problem is that the loop continues to run even thought you've "made up your mind" already. You should add the line break after a=a+1

After you determine that a number is composite (not prime), your work is done. You can exit the loop with break.
while num > a :
if num%a==0 & a!=num:
print('not prime')
break # not going to update a, going to quit instead
else:
print('prime')
a=(num)+1
Also, you might try and become more familiar with some constructs in Python. Your loop can be shortened to a one-liner that still reads well in my opinion.
any(num % a == 0 for a in range(2, num))

Begginer here, so please let me know if I am way of, but I'd do it like this:
def prime(n):
count = 0
for i in range(1, (n+1)):
if n % i == 0:
count += 1
if count > 2:
print "Not a prime"
else:
print "A prime"

This would do the job:
number=int(raw_input("Enter a number to see if its prime:"))
if number <= 1:
print "number is not prime"
else:
a=2
check = True
while a != number:
if number%a == 0:
print "Number is not prime"
check = False
break
a+=1
if check == True:
print "Number is prime"

a=input("Enter number:")
def isprime():
total=0
factors=(1,a)# The only factors of a number
pfactors=range(1,a+1) #considering all possible factors
if a==1 or a==0:# One and Zero are not prime numbers
print "%d is NOT prime"%a
elif a==2: # Two is the only even prime number
print "%d is prime"%a
elif a%2==0:#Any even number is not prime except two
print "%d is NOT prime"%a
else:#a number is prime if its multiples are 1 and itself
#The sum of the number that return zero moduli should be equal to the "only" factors
for number in pfactors:
if (a%number)==0:
total+=number
if total!=sum(factors):
print "%d is NOT prime"%a
else:
print "%d is prime"%a
isprime()

This is a slight variation in that it keeps track of the factors.
def prime(a):
list=[]
x=2
b=True
while x<a:
if a%x==0:
b=False
list.append(x)
x+=1
if b==False:
print "Not Prime"
print list
else:
print "Prime"

max=int(input("Find primes upto what numbers?"))
primeList=[]
for x in range(2,max+1):
isPrime=True
for y in range(2,int(x**0.5)+1) :
if x%y==0:
isPrime=False
break
if isPrime:
primeList.append(x)
print(primeList)

Prime number check.
def is_prime(x):
if x < 2:
return False
else:
if x == 2:
return True
else:
for i in range(2, x):
if x % i == 0:
return False
return True
x = int(raw_input("enter a prime number"))
print is_prime(x)

# is digit prime? we will see (Coder: Chikak)
def is_prime(x):
flag = False
if x < 2:
return False
else:
for count in range(2, x):
if x % count == 0:
flag = True
break
if flag == True:
return False
return True

Related

List previous prime numbers of n

I am trying to create a program in python that takes a number and determines whether or not that number is prime, and if it is prime I need it to list all of the prime numbers before it. What is wrong with my code?
import math
def factor(n):
num=[]
for x in range(2,(n+1)):
i=2
while i<=n-1:
if n % i == 0:
break
i = i + 1
if i > abs(n-1):
num.append(n)
print(n,"is prime",num)
else:
print(i,"times",n//i,"equals",n)
return
Your method only returns whether the 'n' is prime or not.
For this purpose, you don't need a nested loop. Just like this
def factor(n):
num=[]
for x in range(2,(n+1)):
if n % x == 0:
break
if x > abs(n-1):
num.append(n)
print(n,"is prime",num)
else:
print(x,"times",n//x,"equals",n)
return
And then, if you want all the other primes less than n, you can use prime number sieve algorithm.
--------- Update --------------
A modification of your code which can find the other primes (but prime sieve algorithm still has better performance than this)
def factor(n):
num=[]
for x in range(2,(n+1)):
i=2
while i<=x-1:
if x % i == 0:
break
i = i + 1
if i > abs(x-1):
num.append(x)
if n in num:
print num
else:
print str(n) + ' is not num'
return

I am getting incorrect output from prime number script

Getting wrong output from this script.
#!/usr/bin/python
numbers = [1,3,5,7,8,25]
def primes():
for i in numbers:
if i > 1:
if (i % 2) == 0:
print "not prime"
else :
print "prime"
print primes()
its saying 25 is prime, any idea why ?
Your program is checking if numbers are odd, not if they're prime.
This is the validation you want (from this page)
# prime numbers are greater than 1
if num > 1:
# check for factors
for i in range(2,num):
if (num % i) == 0:
print(num,"is not a prime number")
print(i,"times",num//i,"is",num)
break
else:
print(num,"is a prime number")
import math
numbers = [1,3,5,7,8,25]
def primes(n):
if n == 2:
return True
if n%2 == 0 or n <= 1:
return False
sqr = int(math.sqrt(n)) + 1
for divisor in range(3, sqr, 2):
if n%divisor == 0:
return False
return True
for i in numbers:
print i, '\t', primes(i)
Your code will just check for odd or even number. Not for prime number.

prime number python for loops

Question:
A program that take a positive integer n as input and returns True if n is a prime number, otherwise returns False.
My Answer:
n = int(input("Enter a number: "))
for i in range(2,n):
if n%i == 0:
print(False)
print(True)
when I enter a prime number it works but when I enter a non prime number it doesn't work.
Example:
>>>
Enter a number: 12
False
False
False
False
True
>>>
please help!
You can break and use else:
n = int(input("Enter a number: "))
for i in range(2, n):
if n % i == 0:
print(False)
break
else:
print(True)
True will only be printed if the loop completes fully i.e no n % i was equal to 0.
Your code always prints True at the end, and prints a number of Falses before that. Instead, you should have a variable (isPrime?) that gets initialized to True and gets set to False when you find it is divisible by something. Then print that variable at the end.
You're just printing each intermediate value, if you use return in a function it works fine
def prime(n):
for i in range(2, n):
if n%i == 0:
return False
return True
>>> prime(5)
True
>>> prime(12)
False
You could use the for-else clause here. Also, you don't need to go beyond the square root of n:
import math
for i in range(2, int(math.sqrt(n))):
if n % i == 0:
print "False"
break
else:
print "True"
There's a lot of different ways to fix your code, but all of them hinge on the fact that you should be breaking out of that loop if you find a divisor (ie if n%i == 0)
Usually, you'd have a boolean value storing whether or not you've found a divisor, but python lets you do the following
n = int(input("Enter a number: "))
for i in range(2,n):
if n%i == 0:
print(False)
break
else:
#else statement only happens if you don't break out of the loop
print(True)
Check out the algorithm here:
http://www.programiz.com/python-programming/examples/prime-number
# Python program to check if the input number is prime or not
# take input from the user
num = int(input("Enter a number: "))
# prime numbers are greater than 1
if num > 1:
# check for factors
for i in range(2,num):
if (num % i) == 0:
print(num,"is not a prime number")
print(i,"times",num//i,"is",num)
break
else:
print(num,"is a prime number")
# if input number is less than
# or equal to 1, it is not prime
else:
print(num,"is not a prime number")
If you encounter an i which gives modulo zero with n, then you have to print False and then do nothing. For this you can use a flag variable which takes care of this condition. If no such i is encountered, flag remains 1 and True is printed.
n = int(input("Enter a number: "))
flag = 1
for i in range(2,n):
if n%i == 0:
print(False)
flag = 0
break
if flag:
print(True)
check this one, it should make clear why the else statement is indented 'non conventionally':
num = int(input('Enter the maximum value: '))
for number in range(3, num+1):
#not_prime = False
for factor in range(2, number):
if number%factor == 0:
#not_prime = True
break
#if not_prime:
#continue
else:
print(number)
All of the above things are correct but I want to add thing that you should check for the condition of 1. if someone puts 1 as an integer you will have to return False. 1 is not prime
def prime_num(num):
if num <= 0:
return "the number is not primary"
for i in range(2, num - 1):
if num % i == 0:
return "The number is not primary, it can be divided: " + str(i)
return "The number: " + str(num) + " is primary"
This is one of the many ways to solve it:
def is_prime(num):
if (num == 2):
return True
elif any(x for x in range(2, num - 1) if (num % x == 0)):
return False
else:
return True

Trying to find the prime numbers using Python

Below is my code to find the prime number using Python which is not working. Here the function prime will take an integer as input and return whether its a prime number or not. Could you please sort out the problem and explain it.
def prime(x):
if x == 0 or 1:
return False
elif x == 2:
return True
else:
for n in range(2, x):
if x % n == 0:
return False
else:
return True
I think i have sorted out the first issue, the first "if" statement should be if x == 0 or x == 1. Now what about the rest.
What does your for loop?
if x % n == 0:
return False
else:
return True
which by the way eqals return bool(x % n)
So, you return in first iteration, when n == 2.
The whole for loop equals return bool(x % 2), which simply checks if x is diviseable by 2.
That's not what you want.
So, what do you want?
You want to check if x is not diviseable by any numer from range(2, x).
You know that x is not prime, if you find one n from range(2, x), for which x % n == 0 is True.
You know that x is prime, when there is no n in range(2, x), for which x % n == 0 is True.
When can you say that none of n from range is a divisor of x?
After checking all ns from range!
After is the key here.
After the loop, in which you try to find divisor, you can only tell that x is prime.
I hope you now understand the code others posted without explanation.
Note: alternative syntax
Code others posted is correct. However, in Python there is second way writing the for, using for .. else:
for x in range(2, x):
if x % n == 0:
return False
else:
return True
The problem is that the return true should not happen until the for loop has completed.
what we have in the original code is a cuple of tests for trivial cases (x less than 3)
and then a loop for testing all the larger numbers.
In the loop an attempt is made to divide x by a smaller number (starting with 2) and then if it divides evenly False is returned, if it does not True is returned, that is the mistake, instead of returning true, the loop should be allowed to repeat, and division should be tried again with the next number, and only after the supply of divisors (from the for loop) has been exhausted should true be returned.
here's a fixed version:
def prime(x):
if x <= 1:
return False
elif x == 2:
return True
else:
for n in range(2, x):
if x % n == 0:
return False
return True
Others have commented that the loop need not continue all the way up to x and that stopping at sqrt(x) is sufficient, they are correct. doing that will make it faster in almost all cases.
Another speed up can be had if you have a list of small primes (upto sqrt(x)) - you need only test divisibility by the primes below sqrt(x),and not every integer in that range.
The below code is for finding the prime number from 2 to nth number.
For an example, the below code will print the prime number from 2 to 50 and also it will print the number in between 2 to 5o which is not prime.
import time
i=2
j=2
count=0
while(i<50):
while (i>j):
if (i%j)==0:
count=count+1
j=j+1
else:
j=j+1
if count==0:
print i," is a prime"
else:
print i," is not a prime"
i=i+1
j=2
count=0
time.sleep(2)

Why is my modulo condition in my prime number tester not working?

I'm trying (and failing) to write a simple function that checks whether a number is prime. The problem I'm having is that when I get to an if statement, it seems to be doing the same thing regardless of the input. This is the code I have:
def is_prime(x):
if x >= 2:
for i in range(2,x):
if x % i != 0: #if x / i remainder is anything other than 0
print "1"
break
else:
print "ok"
else:
print "2"
else: print "3"
is_prime(13)
The line with the comment is where I'm sure the problem is. It prints "1" regardless of what integer I use as a parameter. I'm sorry for what is probably a stupid question, I'm not an experienced programmer at all.
Your code is actually really close to being functional. You just have a logical error in your conditional.
There are some optimizations you can make for a primality test like only checking up until the square root of the given number.
def is_prime(x):
if x >= 2:
for i in range(2,x):
if x % i == 0: # <----- You need to be checking if it IS evenly
print "not prime" # divisible and break if so since it means
break # the number cannot be prime
else:
print "ok"
else:
print "prime"
else:
print "not prime"
The problem is this line:
if x % i != 0:
You are testing if x % i is not 0, which is true for any pair of integers that are relatively prime (hence, you always get it printed out)
It should be:
if x % i == 0:
This kind of checks can be single expression:
def is_prime(n):
return n>1 and all(n%k for k in range(2,n//2))
Try using return statements instead of (or in addition to) print statements, eg:
from math import sqrt # for a smaller range
def is_prime(x):
if x <= 2:
return True
for i in range(2, int(sqrt(x)) + 1):
if x % i == 0:
print "%d is divisible by %d" % (x,i)
return False
return True
is_prime(13)
True
is_prime(14)
14 is divisible by 2
False

Categories