Reputation: 1
As the title suggests, I am attempting to make a Python 3-powered prime number generator and I can't get it to work.
Here is the code:
import random
def main():
d=1
x=random.randint
while True:
d=d+1
if isinstance(x/d, int)==True:
print (x)
else: main()
main()
and the error:
Traceback (most recent call last):
File "/media/mint/casper-rw/ProjectsOrWork/Python/PrimeIdle.py", line 10, in <module>
main()
File "/media/mint/casper-rw/ProjectsOrWork/Python/PrimeIdle.py", line 7, in main
if isinstance(x/d, int)==True:
TypeError: unsupported operand type(s) for /: 'method' and 'int'
Upvotes: 0
Views: 277
Reputation: 33960
Code is at bottom, but try to code your own based on the following suggestions, that's more educational for you:
x = random.randint
is not actually calling randint()
main()
every single time your candidate tests composite. That would cause unbounded stack growth and eventually overflow. (Never make a recursive call if you know you won't return from it). Also, you can't easily return
from a very deep chain of recursion... you're kludging by using print(x)
to sidestep that.generate_divisor()
and a predicate function is_prime()
(that returns True/False).is_prime()
falls-through and returns True.if (isinstance(x/d, int)==True)
is bad, beware truncation errors on large x/d, use if (x%d == 0)
to test for divisibility instead.d = d+1
(or d += 1
), you're generating lots of composite divisors and diminishing few primes. (Indeed you're generating tons of composite divisors like 27 or 51, then testing divisibility by those, which is a total waste of time, since you already tested divisibility by 3 and 17.).
import random
from math import sqrt, floor
def generate_prime_candidate():
"""Generator to generate random prime candidate"""
yield random.randint() # probably do randint(2, 2**32 -1). You decide.
def find_random_prime():
x = generate_prime_candidate()
while not is_prime(x):
x = generate_prime_candidate()
# Found one!
print(x)
return x
def is_prime(x): # normally we call integers n, floats x, but whatever...
for d in generate_divisors(floor(sqrt(x))): # only search up to sqrt(x)
if x%d == 0:
return False # x is composite - d is a divisor
return True # x is prime
def generate_divisors(dmax):
"""Generate divisors, up to a limit. We exclude numbers easily known to be composite: residue 0,2,4,5,6,8 modulo 10"""
yield 2
yield 3
yield 5 # now for d>5, exclude them by residue
d = 7
while d<dmax:
while (d%10) == 5: # d easily known to be composite
d += 2 # in fact we only need to test [0,2,4,6,8] not 5, since d+=2 is skipping residue 5 anyway
yield d
Upvotes: 2
Reputation: 122086
x=random.randint
doesn't assign a random integer to x
, it assigns the randint
function. You should do:
x = random.randint(min, max)
However, that is the least of your problems - your prime test won't work, that isn't actually a generator function and you pick a new random number on each recursive call.
Upvotes: 1