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
Related
I have the below script that returns each number stating whether it is prime or not and asking the user if they wish to see the next number in sequence. I wish to make a change so that the script does not produce a print statement for the non-prime numbers and instead skips them and only returns the next prime number, after which asks if the user wished to see the next prime.
Here is my code:
def prime_number():
game_on = True
count = 3
while True:
for num in range(2, count):
if (count % num) == 0:
print(count,"is not a prime number")
break
else:
print(count,"is a prime number")
question = input("Would you like to see another prime number?? Please enter Yes or No: ")
if question[0].lower() == "y":
count = count + 1
continue
return
When I run this and select Yes a few times I get the below. I want to skip the non-prime numbers altogether and get rid of the non-prime print statements below. I have tried a few ways of ignoring the non-primes in the above while loop but non have worked so far.
3 is a prime number
Would you like to see another prime number?? Please enter Yes or No: Yes
4 is not a prime number
Would you like to see another prime number?? Please enter Yes or No: Yes
5 is a prime number
Would you like to see another prime number?? Please enter Yes or No: Yes
6 is not a prime number
Would you like to see another prime number?? Please enter Yes or No:
Another proposal close to yours:
def prime_number():
number = 3
while True:
if all(number % num != 0 for num in range(2, number)):
print(f"{number} is a prime number")
response = input("Would you like to see another prime number?? Please enter Yes or No: ")
if response[0].lower() == "n":
return
number += 1
Remarks:
Why starting with 3? 2 is the first prime.
There are way more efficient ways to compute primes (e.g., you could check only up to sqrt(number)), but I didn't want to change your algo. I doubt it really matters for this use case.
Have you tried creating a list then looping through your for in range loop adding each prime to the list then loop through your list printing all primes to a Given Number.
Oh, I get it. You can just do this:
def next_prime(n):
while True:
for denom in range(2, n//2):
if n % denom == 0:
n += 1
break
else:
return n
def prime_number():
game_on = True
p = 2
while True:
p = next_prime(p + 1)
print(p)
question = input("Would you like to see another prime number?? Please enter Yes or No: ")
if question[0].lower() == "y":
continue
return
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
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
I'm beginning to learn python and I've just finished my first project, which was the collatz sequence, which is "If n is even, divide it by 2 to get n / 2. If n is odd, multiply it by 3 and add 1 to obtain 3n + 1. Repeat the process until you reach 1."
Here is my code, it's not very long:
import sys
def integer(): #Asks for input and checks whether positive integer
while True:
number = input("Enter a positive, whole number:")
try:
number = int(number)
if number > 0:
break
else:
raise ValueError
except ValueError:
print("That's not right! \n Please enter a positive, whole number")
return number
number = None
def collatz():
global number
print(number)
while number > 1:
if number % 2 ==0:
number = number // 2
else:
number = number * 3 + 1
print(number)
while True: #loop so that you can try again
number = integer()
collatz()
repeat = input("Try again? Y/N").upper()
while repeat != "Y" and repeat != "N": #Only Y/N are valid
repeat = input("Try again? Y/N")
if repeat == "N":
sys.exit() #end program if N selected
else:
pass #Reloops to try again
I ran this code on an app called "QPython3" on my Google Pixel XL (Up to 2.4 GHz), running Android 7.1.1 and also my base model MacBook Pro (Retina, 13-inch, Early 2015)(2.7GHz).
The MacBook took multiple minutes to reach 1 when I used an absurdly large number such as 10^100, but my phone did it almost instantaneously.
I don't understand why this would be the case. Shouldn't the proper computer be better in every way?
(If you want to give feedback on the overall effectiveness of my code, that is appreciated, but probably not worth your time as I'm very new and would likely not understand things too well. I'm just trying to make code that works at this stage)
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()