Reputation: 204
I am a beginner at Python, and I need help fixing this piece of code i have created. Bassicaly, I have my code here below.
import math
def generate_p(p, Count, X, List):
while Count <= X:
isprime = True
for x in range(2, int(math.sqrt(p)) + 1):
if p % x == 0:
isprime = False
if isprime:
Count += 1
print p
P.append(p)
p += 1
if __name__ == "__main__":
p = 2
count = 1
X = int(raw_input('number: '))
List = []
generate_p(p, count, X, List)
Basically, The function does work, however, it does not function how i want it to function. First, i will say how the function's logic work, since the second part of the code is just variables and declaring the function.
while the variable count is less or equal to X, is prime is true, as long as p (the number being tested) can go into every x without a remainder (x is in a range of 2 through the square root of p). If it is prime, add 1 to the count, print the prime, add it too the list, and then and 1 to p, the number being tested. If it is not prime, then just add 1 to p. This keeps going until Count is greater than X, then the code stops.
As you have probably noticed by now, there is a list collecting prime numbers, however, this is mostly being unused. What i want to do, but I don't know how to do, is fix this part of the code,
for x in range(2, int(math.sqrt(p)) + 1):
if p % x == 0:
isprime = False
so that x is in the range of 2 and the square root of p+1, however, i only want x to be numbers in that range that are in the list of P. Can anyone help me do this, and maybe point out any other things in this code?
Upvotes: 0
Views: 1571
Reputation: 755
If you want to optimize the function with regards to time complexity when p is large, I would recommend looking into Fermats primality test, or the Soloway strausse test for primality. Additionally a list of common divisors might come in handy!
Upvotes: 0
Reputation: 445
See if you can wrap your noodle around this generator... The fastest one yet.
def isprime(value):
stack = [0 for i in xrange(value*2)]
for jump in xrange(2,value,1):
for i in xrange(jump,value*2,jump):
stack[i] += 1
if stack[value] > 1:
return False
else:
return True
At least my fastest method. Much faster than checking each number
Upvotes: 0
Reputation: 148910
I think that your are looking for the sieve of Eratosthenes algorythm. A python implementation could look like :
def erato(n):
"Compute all prime numbers less than or equal to n"
# utility functions in order to work only with numbers starting at 2
def prime(i):
return isprime[i - 2]
def setprime(i, val):
isprime[i - 2] = val
# suppose all numbers may be primes until we find divisors
isprime = [ True for i in range(2, n+1) ]
for i in range(2, int(math.sqrt(n)) + 1):
# do not process non prime numbers
if prime(i):
# if i is prime, all its multiples are not
j = 2 * i
while j <= n :
setprime(j, False)
j += i
# return the list of prime numbers
return [ i for i in range(2, n + 1) if prime(i) ]
Upvotes: 0
Reputation: 6223
While the other answers are correct in terms of logic, they will evaluate every item in P for its size. If P is sorted in ascending order of size, and P is sufficiently large, then it might be more efficient to just loop through P and include a break clause at the top of the loop.
Edit Actually to do this, you would need to split this section off into its own function so that you don't terminate the top-level while
loop. Then you just return True/False at each point
def is_prime(x, P):
sqrt_p = int(math.sqrt(p)) + 1
for x in P:
if x > sqrt_p:
return True
if p % x == 0:
return False
return True
In terms of other observations:
upper_bound
, prime_list
, prime
. Also check PEP8 for general naming conventions in Python that will make your code more readable and consistent for other Python programmers.Upvotes: 0
Reputation: 303087
If you want to just iterate over the numbers in P
that are less than or equal to the square root of p
:
for x in (i for i in P if i <= math.sqrt(p)):
if p % x == 0:
isprime = False
break # can stop here
Note that having p
and P
as variables is very confusing.
Upvotes: 2
Reputation: 39013
You can use List Comprehension, like so:
for x in [prime in P if prime<=math.sqrt(p)]:
...
Upvotes: 2