Stuck in an infinite loop with my prime number finder program - python

I've been working on a program for my class for a bit. It is supposed to be a prime number finder, where the def is_prime (num) function loops and continually asks the user to input more numbers, checks whether they are prime, and prints whether they are or not. If a negative number is entered, it is supposed to then quit.
def is_prime (num):
while num >= 0:
if num % 1 == num or num % num == 0:
print(num, "is a prime")
elif num % 2 == 0:
print(num, "is not a prime")
continue
elif num < 0:
print("Done. Thanks for using the program!")
break
return 0
if __name__ == "__main__":
print("This program checks if a given number is a prime number\n")
num1 = int(input("Please enter a positive number (or a negative number to exit):\n"))
is_prime(num1)
However, it only has part of that right. It reads and determines prime numbers...but instead of looping back to the function beginning it just endlessly prints the statement of whether or not it is a prime. I'm pretty sure it's a problem of where I've put my while loops, but I'm not entirely sure how to fix that.
Any help would be appreciated.

You haven't described your intended algorithm; it's not at all clear from your code. YOur first if checks whether the input number is divisible by 1 or divisible by itself ... both of which are algebraic tautologies.
Then you repeat this as long as the input remains positive. Since you never change the value of num, this is a pretty direct infinite loop.

You can't test for divisibility for each candidate factor with a different if in an if ladder.
You'll need to stash each prime you find in a list.
EG:
def sieve_primes(stop=100000):
"""Yield primes below stop."""
primes = [2]
for candidate in range(3, stop + 1, 2):
if not any(candidate % prime == 0 for prime in primes):
primes.append(candidate)
yield candidate
for prime in sieve_primes():
print(prime)
Raid it for ideas, but don't copy it verbatim. You could speed it up a lot with math.sqrt(), BTW.
HTH

Related

Inputting large numbers and check if it is prime (Python)

I am making a program using python wherein it checks large numbers if it is a prime number or not. (this is for RSA Encryption)
Here is my code:
p = int(input("Enter first prime number: "))
while(1):
if isPrime(p) is False:
print("%d is not a prime number!" % p)
p = int(input("Please enter first prime number again: "))
else:
print("%d is a prime number." % p)
break
q = int(input("Enter second prime number: "))
while(1):
if isPrime(q) is False:
print("%d is not a prime number!" % q)
q = int(input("Please enter second prime number again: "))
else:
print("%d is a prime number." % q)
break
p is the first large number and q is the second large number.
here is the function that checks if it is a prime number:
def isPrime(num):
if num > 1:
for i in range(2, num):
if(num % i) == 0:
return False
else:
return True
else:
return False
I tried running it using small numbers like 17 and 11 and it works but when I tried to input a 16-digit number, it doesn't work anymore.
Here is the sample run:
On the second image, when I entered a large number, it does not continue. I tried waiting for half an hour and see if it works but it still, it's just like that. Why is it so?
It's taking so long because you're looping over A LOT of numbers, every one up until your 16 digit one, which is a lot of loop iterations. Even if you're only doing constant work per iteration, getting through that many numbers will still take awhile. Loops in python are notoriously slow. Luckily, you can use sympy like so:
from sympy.ntheory import factorint
def isPrime(n):
return len(factorint(n)) == 1
and then things should be going much faster. For reference:
factorint(133453565475464563453)
took about half a second

Python - prime number algorithm doesn't work with higher numbers

I´m new at python and I have problem with my simple program.
I have found some simple algorithm that can tell if input number is prime number or not. Evrything works fine with input numbers like 2 or 13. The problem happens when I use higher number (and I need to use higher numbers only).
num = 3231817448941
if num > 1:
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")
else:
print(num,"is not a prime number")
My number input is 3231817448941. Because this number is prime number it should print:
Output should be:
3231817448941 is a prime number
But after runing this program my concole is empty and nothing is printed.
Also when I use similar number with same length that is not prime number then it works.
As I said I'm new at python and I would appreciate any advice.
One change to speed up the process A LOT
num = 3231817448941
if num > 1:
for i in range(2,int(num**0.5)+1): # Dont have to check to n, just sqrt(n)
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")
else:
print(num,"is not a prime number")
You can find more optimizations here

Why is my prime number checking code not displaying the correct output?

I have a code that checks whether a number is prime or not, and outputs "Yes" or "No" accordingly. But when I input 1763, it outputs "Yes" even though it isn't a prime. The code checks whether a number is prime or not by checking if it can be divisible by any number between 2 and n-1. So when I input 1763, it should output "No" because 1763 can be divisible by 41. What went wrong in my code?
def getNumber():
n=int(input())
return n
def isPrime(n):
if n==2:
print("Yes")
else:
for i in range (2,n):
if n%i==0:
print("No")
break
else:
print("Yes")
break
def main():
n = getNumber()
isPrime(n)
main()
The problem is that you are not accounting for all the divisors. As soon as your first condition (if n%i==0:) is false, you execute the second elif condition and print "Yes".
Solution: You can use a flag which will be turned 1 only when a divisor will be found, which means the number is not prime. Below is slightly modified code of yours (showing only partial code, rest remains the same as yours). As pointed out by #bereal in the comments, you don't need to iterate up to n but only up to the square root sqrt(n). math.ceil returns the closest rounded off integer.
import math
def isPrime(n):
flag = 0
if n==2:
print("Yes")
return
else:
# for i in range (2, n):
for i in range (2, math.ceil(np.sqrt(n)) + 1):
if n%i==0:
print("No")
flag = 1
break
if not flag:
print ("Yes")
1763
No
In your loop you break on the first iteration, even if you haven't been able to prove that it isn't a prime yet.
You need to print yes only after you've checked all possible divisors up to n (it's actually enough to only check all numbers upp to the square of n).
for i in range (2,n):
if n%i==0:
print("No")
return
print("Yes")
You should declare a number to be a prime only after you iterate through all the possible divisors without finding one. For that you can use the for-else construct instead, where the else block is only executed if the for loop isn't aborted with a break statement:
def isPrime(n):
if n==2:
print("Yes")
else:
for i in range (2,n):
if n%i==0:
print("No")
break
else:
print("Yes")

A prime number checker that fails

It seems like a normal code and works well, but for whatever reasons when I try entering this number = 18765411123451, computer seems to freeze, any clue?
num = 18765411123451
if num > 1:
for i in range(2,num):
if num % i == 0:
print(num,"is not a prime number")
print("Because", i,"x",num//i, "=" ,num)
break
else:
print(num,"is a prime number")
else:
print(num,"is not a prime number")
I've tried many other numbers and the code works as it should except that number. What happened here?
it freezes because your number just too high.
The reason is for i in range(2,num): with num = 18765411123451 with is 100 trillion...
Plus the fact that python 2 will try to allocate that memory just to create the list to iterate on it (in that case use xrange)
Good news: you don't have to check until the number itself, just check until square root (included):
for i in range(2,int(num**0.5)+1):
that's more reasonable (less that 5 million iterations) and will provide the same result.
Past the square root of a number, if you haven't found divisors, you won't find any afterwards (if q is a divisor of num, then p*q == num so either p or q has to be lower or equal than square root of num

Python prime checker

I recently started learning python (by which I mean, 35 minutes ago at the time of posting...) and I've wrote a few things e.g. square root generator, factorial generator, Fibonacci number generator, prime checker etc. After I wrote the prime checker, I thought I'd try modifying it so that instead of checking every number in the specified range, it would accept an input and check that one specifically.
DISCLAIMER: If I were better at Python then I would only check numbers up to sqrt(p) and I would add an option to check if it is even and not 2 then it automatically returns that it's not prime but let me walk before I run! :)
CODE:
p = input("Enter a potential prime.")
for n in range (2,p):
if p % n == 0:
print(p, "equals", n, "x", p//n, "so it isn't a prime number")
break
else:
print(p, "is a prime number.")
It works for p = 2 but that's it...
NB - Obviously the code is indented accordingly, it's just not formatted properly here.
I see some errors: You need to convert your user input to an int, plus you need to move the else: clause to beneath your for-loop instead of beneath your if-statement. The following code works for what you want:
p = int(input("Enter a potential prime."))
for n in range (2,p):
if p % n == 0:
print(p, "equals", n, "x", p//n, "so it isn't a prime number")
break
else:
print(p, "is a prime number.")
Yes, this is correct - the else: is NOT part of the if-statement, it is part of your for-loop. This syntax means that if your for-loop runs to a break, then it'll break as normally. If there is no break, then the else: clause will be executed. Thus, it'll do the basic trial division, and if the number passes the test, it'll print "is a prime number" only once. The code you posted will print "is a prime number" for every iteration of your loop.
Edit: Try the following code for your followup question.
def primeChecker():
# Function that keeps prompting for input, and checks if it's prime. Enter "quit"
# to exit:
user_input = input("Enter a potential prime (or type 'quit' to exit): ")
if user_input == 'quit':
return
else:
p = int(user_input)
# Trial division algorithm:
for n in range (2,p):
if p % n == 0:
print(p, "equals", n, "x", p//n, "so it isn't a prime number")
break
else:
print(p, "is a prime number.")
# Recursive function call:
primeChecker()
# Start by calling the main function:
primeChecker()

Categories