Random Number Range in Python, ValueError: empty for Range () - python

This python code is returning a ValueError in the random number generator section of the code. I ran it with hardcoded values in the function: def fermat_test(n): at line
a = random.randit(2,n-1), and it seemed to run otherwise. I can't figure out why the range is out of bounds?
import random
def remainder(i,j):
rem = i%j
return rem
def is_even(n): return n % 2 == 0
def square(n): return n**2
def expmod(b, e, m):
if e==0:
return 1
elif is_even(e):
expm = expmod(b, e/2,m)
return remainder(expm*expm,m)
else:
return remainder(b*expmod(b,e-1,m),m)
def fermat_test(n):
a = random.randint(2,n-1)
return expmod(a,n,n)==a
def is_fermat_prime(n, ntimes):
if ntimes == 0:
return True
elif fermat_test(n):
return is_fermat_prime(n,ntimes-1)
else:
return False
## this is the test you can use to test your code
def sum_of_fermat_primes(n):
sum = 0
for i in xrange(n+1):
if is_fermat_prime(i, 70):
sum += i
return sum
print sum_of_fermat_primes(10)
print sum_of_fermat_primes(20)
print sum_of_fermat_primes(560)
print sum_of_fermat_primes(570)
Traceback (most recent call last):
File "C:\Users\Terik\.atom\code.py", line 33, in <module>
print sum_of_fermat_primes(10)
File "C:\Users\Terik\.atom\code.py", line 30, in sum_of_fermat_primes
if is_fermat_prime(i, 70):
File "C:\Users\Terik\.atom\code.py", line 22, in is_fermat_prime
elif fermat_test(n):
File "C:\Users\Terik\.atom\code.py", line 17, in fermat_test
a = random.randint(2,n-1)
File "C:\Python27\lib\random.py", line 242, in randint
return self.randrange(a, b+1)
File "C:\Python27\lib\random.py", line 218, in randrange
raise ValueError, "empty range for randrange() (%d,%d, %d)" % (istart, istop, width)
ValueError: empty range for randrange() (2,0, -2)

The error is because in
a = random.randint(2,n-1)
n - 1 is less than 2. In fact, the value of n comes from i in for i in xrange(n+1), so it starts from 0, 1, 2, etc. These smallest values make the random.randint(2,n-1) invalid.

Your i in xrange starts at 0 it should start at 1 instead.
for i in xrange(1, n+1):

Related

Error in finding if an imei number in valid in python (TypeError: not all arguments converted during string formatting)

I am making a python script that lets you entire an imei number then checks if it is valid, I keep getting an error
Traceback (most recent call last):
File "program.py", line 28, in
if isValidEMEI(n):
File "program.py", line 19, in isValidEMEI
d = (int)(n % 10)
TypeError: not all arguments converted during string formatting
the code is
def sumDig( n ):
a = 0
while n > 0:
a = a + n % 10
n = int(n / 10)
return a
def isValidEMEI(n):
s = str(n)
l = len(s)
if l != 15:
return False
d = 0
sum = 0
for i in range(15, 0, -1):
d = (int)(n % 10)
if i % 2 == 0:
d = 2 * d
sum = sum + sumDig(d)
n = n / 10
return (sum % 10 == 0)
n = input("Enter number")
if isValidEMEI(n):
print("Valid IMEI Code")
else:
print("Invalid IMEI Code")
I have not really being sure what to try and do but I have looked up the error and nothing helpful/stuff I know to to interpret is showing up.
I am new to learning python so this will probalbly have a very simple sulution
I will update this with a "shortest replication of this error"
Thank you so much all help is welcome, this is for a challange I set myself so I am very determind to finish it
I have fixed it, replace n = input("enter number") with n = int(input("Enter number"))

ValueError with random class in python not working

Here is the code:
import random
import numpy as np
class Room:
def __init__(self, name, contents):
self.name = name
self.contents = contents
rooms = np.zeros((11, 11))
maxRooms = 7
possibleNextRoom = []
def resetLevel():
global rooms
for r in range(len(rooms[0])):
for c in range(len(rooms[1])):
rooms[r][c] = 0
possibleNextRoom = []
halfHeight = int(len(rooms[1]) / 2)
halfWidth = int(len(rooms[0]) / 2)
rooms[halfWidth][halfHeight] = 1
def countRooms():
global rooms
roomCount = 0
for r in range(len(rooms)):
for c in range(len(rooms)):
if rooms[r][c] == 1:
roomCount += 1
return roomCount
def findPossibleRooms():
for r in range(len(rooms) - 1):
for c in range(len(rooms) - 1):
if rooms[r][c] == 1:
if rooms[r][c+1] != 1:
possibleNextRoom.append((r, c+1))
if rooms[r][c-1] != 1:
possibleNextRoom.append((r, c-1))
if rooms[r-1][c] != 1:
possibleNextRoom.append((r-1, c))
if rooms[r+1][c] != 1:
possibleNextRoom.append((r+1, c))
def addRoom():
nextRoom = random.randrange(0, len(possibleNextRoom))
rooms[possibleNextRoom[nextRoom][0]][possibleNextRoom[nextRoom][1]] = 1
possibleNextRoom.pop(nextRoom)
def generateLevel():
resetLevel()
while countRooms() < maxRooms:
countRooms()
findPossibleRooms()
addRoom()
def displayLevel():
print(rooms)
generateLevel()
displayLevel()
Here is the Error:
ValueError: empty range for randrange() (0, 0, 0)
I thought I was using random correctly, but appearantly not. I tried making the array start with something in it, but it still gave me the same error. I have been working on this for a long time and its giving me a headache. Any help with this is greatly appreciated. The error is on line 54.
In [90]: import random
In [91]: random.randrange?
Signature: random.randrange(start, stop=None, step=1, _int=<class 'int'>)
Docstring:
Choose a random item from range(start, stop[, step]).
...
This produces your error:
In [92]: random.randrange(0,0)
Traceback (most recent call last):
File "<ipython-input-92-566d68980a89>", line 1, in <module>
random.randrange(0,0)
File "/usr/lib/python3.8/random.py", line 226, in randrange
raise ValueError("empty range for randrange() (%d, %d, %d)" % (istart, istop, width))
ValueError: empty range for randrange() (0, 0, 0)
So if the error occurs in (telling us the line number if 52 is nearly useless)
nextRoom = random.randrange(0, len(possibleNextRoom))
it means possibleNextRoom is an empty list, [] (or possibly something else with a 0 len).
I see a
possibleNextRoom = []
The append in findPossibleRooms operate in-place, so can modify this global list. But they are wrapped in for and if, so I can't say whether they run at all.
In any case, the error tells that nothing has been appended, for one reason or other.

Input validation and input processing

I'm having quite a hard time creating this program.
Basically the goal is to request user input 7 times, validate the user input based on the criteria of being >= 0 and a valid real number, create a list of that input, then process the input to output Total, max, min, and average.
MAX_HOURS=7
def get_string(prompt):
value=""
value=input(prompt)
return int(value)
def get_pints(pints):
counter = 0
while counter < MAX_HOURS:
pints[counter] = get_real("How many pints were donated? ")
counter = counter + 1
return counter
def valid_real(value):
while True:
try:
value=float(value)
if value >= 0:
return True
else:
print("Please enter a valid number greater than 0! ")
return False
except ValueError:
print("Please enter a valid number greater than 0! ")
return False, int(value)
def get_real(prompt)
value=""
value=input(prompt)
while not valid_real(value):
print(value, "is not a valid entry. Please enter a number greater than 0")
value=input(prompt)
return value
def get_total_pints(pints):
counter = 0
total_pints = 0.0
while counter < 7:
total_pints = total_pints + pints[MAX_HOURS]
counter = counter + 1
return total_pints
def get_min_pints(pints):
min_pints = pints[MAX_HOURS]
min_pints = 0
for i in range(7):
if i < min_pints:
min_pints = i
return min_pints
def get_max_pints(pints):
max_pints = pints
max_pints = 0
for i in range (MAX_HOURS):
if i > max_pints:
max_pints = i
return max_pints
def get_average_pints(total_pints):
average_pints = 0
average_pints=total_pints / MAX_HOURS
return average_pints
def full_program():
pints=[0 for i in range(MAX_HOURS)]
max_pints=[0 for i in range(MAX_HOURS)]
total_pints=[0 for i in range(MAX_HOURS)]
counter=0
pints=get_pints(pints)
total_pints = get_total_pints(pints)
print([pints])
print(int(total_pints))
full_program()
While I'm pretty sure my input validation loop is correct, it seems like the main issue is that I have a an int object that can't be subscripted. I've read other posts and tried some of the code that worked in those scenarios, but I can't get my program to run correctly.
I'm really struggling and at this point, any guidance in the right direction is appreciated.
EDIT: I sent some of the wrong code, I've been revising this code so much I got mixed up on what I meant to send.
Also:
Traceback (most recent call last):
File "C:/Users/User/Desktop/classwork 1125/lab5original.py", line 193, in <module>
full_program()
File "C:/Users/User/Desktop/classwork 1125/lab5original.py", line 182, in full_program
total_pints = get_total_pints(pints)
File "C:/Users/User/Desktop/classwork 1125/lab5original.py", line 97, in get_total_pints
total_pints = total_pints + pints[MAX_HOURS]
TypeError: 'int' object is not subscriptable

python script for Mastermind solving stops unexpectedly (also gives error after increasing range)

I've tried to adapt one of the given scripts here:
How to solve the "Mastermind" guessing game?
When i'm trying to get results for:
digits = 4
variables = 10
times_until = 100
...I'm not having any problem. But when i try to increase 'variables' to 12 program stops after progressing a little.
Also i have another issue that if i change 'times_until' to 500 program gives me error like below:
Traceback (most recent call last):
File "/Users/ivalaostiapytriel/Dropbox/MastermindSolver.py", line 72, in <module>
rungame(hidden_code, strategy_allrand)
File "/Users/ivalaostiapytriel/Dropbox/MastermindSolver.py", line 58, in rungame
restart_game()
File "/Users/ivalaostiapytriel/Dropbox/MastermindSolver.py", line 37, in restart_game
rungame(hidden_code, strategy_allrand)
File "/Users/ivalaostiapytriel/Dropbox/MastermindSolver.py", line 58, in rungame
restart_game()
...
...
restart_game()
File "/Users/ivalaostiapytriel/Dropbox/MastermindSolver.py", line 37, in restart_game
rungame(hidden_code, strategy_allrand)
File "/Users/ivalaostiapytriel/Dropbox/MastermindSolver.py", line 50, in rungame
print ("That's it. After %d tries, I won." % (i+1,))
File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/idlelib/PyShell.py", line 1347, in write
return self.shell.write(s, self.tags)
RuntimeError: maximum recursion depth exceeded while calling a Python object
>>>
Note that I'm NOT knowledgeable -even slightly- about python. Just had a lecture at back university about it, but not any other experience. Just need to adapt it for a project and retrieve some results from this.
Here is the code I've adapted down below. I would be glad if anyone mention where I am doing wrong to cause these errors.
import random
#from itertools import izip, imap
try:
# Python 2
from itertools import izip
from itertools import imap
except ImportError:
# Python 3
izip = zip
imap = map
digits = 4
variables = 10
times_until = 500
maxtries = 25
times_done = 0
average_cal = 0
fmt = '%0' + str(digits) + 'd'
searchspace = tuple([tuple(map(int,fmt % i)) for i in range(0,variables**digits)])
def compare(a, b, imap=imap, sum=sum, izip=izip, min=min):
count1 = [0] * variables
count2 = [0] * variables
strikes = 0
for dig1, dig2 in izip(a,b):
if dig1 == dig2:
strikes += 1
count1[dig1] += 1
count2[dig2] += 1
balls = sum(imap(min, count1, count2)) - strikes
return (strikes, balls)
def restart_game():
hidden_code = random.choice(searchspace)
rungame(hidden_code, strategy_allrand)
def rungame(target, strategy, verbose=True):#, maxtries=):
possibles = list(searchspace)
for i in range(maxtries):
g = strategy(i, possibles)
#if verbose:
#print ("Out of %7d possibilities. I'll guess %r" % (len(possibles), g),)
score = compare(g, target)
#if verbose:
#print (' ---> ', score)
if score[0] == digits:
if verbose:
print ("That's it. After %d tries, I won." % (i+1,))
global times_done
times_done += 1
global average_cal
average_cal += (i+1)
if times_done <= times_until:
restart_game()
else:
print ("That's it. Average %f " % (average_cal/times_until,))
break
possibles = [n for n in possibles if compare(g, n) == score]
return i+1
def strategy_allrand(i, possibles):
return random.choice(possibles)
if __name__ == '__main__':
hidden_code = random.choice(searchspace)
rungame(hidden_code, strategy_allrand)
As I understand it from your code, you call function rungame from function restart_game, and if
if times_done <= times_until:
you call restart_game from rungame. Therefore, if times_until variable exceed certain value you get maximum recursion depth exceeded error.
You get a sequence of nested calls of the form
rungame(...)
restart_game(...)
rungame(...)
restart_game(...)
...
To increase the maximum recursion depth you could use sys.setrecursionlimit function. But a far better solution would be to rewrite your code in such a way
to get rid of recursion.

Simple prime number generator in Python

Could someone please tell me what I'm doing wrong with this code? It is just printing 'count' anyway. I just want a very simple prime generator (nothing fancy).
import math
def main():
count = 3
one = 1
while one == 1:
for x in range(2, int(math.sqrt(count) + 1)):
if count % x == 0:
continue
if count % x != 0:
print count
count += 1
There are some problems:
Why do you print out count when it didn't divide by x? It doesn't mean it's prime, it means only that this particular x doesn't divide it
continue moves to the next loop iteration - but you really want to stop it using break
Here's your code with a few fixes, it prints out only primes:
import math
def main():
count = 3
 
while True:
isprime = True
 
for x in range(2, int(math.sqrt(count) + 1)):
if count % x == 0:
isprime = False
break
 
if isprime:
print count
 
count += 1
For much more efficient prime generation, see the Sieve of Eratosthenes, as others have suggested. Here's a nice, optimized implementation with many comments:
# Sieve of Eratosthenes
# Code by David Eppstein, UC Irvine, 28 Feb 2002
# http://code.activestate.com/recipes/117119/
def gen_primes():
""" Generate an infinite sequence of prime numbers.
"""
# Maps composites to primes witnessing their compositeness.
# This is memory efficient, as the sieve is not "run forward"
# indefinitely, but only as long as required by the current
# number being tested.
#
D = {}
 
# The running integer that's checked for primeness
q = 2
 
while True:
if q not in D:
# q is a new prime.
# Yield it and mark its first multiple that isn't
# already marked in previous iterations
#
yield q
D[q * q] = [q]
else:
# q is composite. D[q] is the list of primes that
# divide it. Since we've reached q, we no longer
# need it in the map, but we'll mark the next
# multiples of its witnesses to prepare for larger
# numbers
#
for p in D[q]:
D.setdefault(p + q, []).append(p)
del D[q]
 
q += 1
Note that it returns a generator.
re is powerful:
import re
def isprime(n):
return re.compile(r'^1?$|^(11+)\1+$').match('1' * n) is None
print [x for x in range(100) if isprime(x)]
###########Output#############
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]
def is_prime(num):
"""Returns True if the number is prime
else False."""
if num == 0 or num == 1:
return False
for x in range(2, num):
if num % x == 0:
return False
else:
return True
>> filter(is_prime, range(1, 20))
[2, 3, 5, 7, 11, 13, 17, 19]
We will get all the prime numbers upto 20 in a list.
I could have used Sieve of Eratosthenes but you said
you want something very simple. ;)
print [x for x in range(2,100) if not [t for t in range(2,x) if not x%t]]
def primes(n): # simple sieve of multiples
odds = range(3, n+1, 2)
sieve = set(sum([list(range(q*q, n+1, q+q)) for q in odds], []))
return [2] + [p for p in odds if p not in sieve]
>>> primes(50)
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47]
To test if a number is prime:
>>> 541 in primes(541)
True
>>> 543 in primes(543)
False
SymPy is a Python library for symbolic mathematics. It provides several functions to generate prime numbers.
isprime(n) # Test if n is a prime number (True) or not (False).
primerange(a, b) # Generate a list of all prime numbers in the range [a, b).
randprime(a, b) # Return a random prime number in the range [a, b).
primepi(n) # Return the number of prime numbers less than or equal to n.
prime(nth) # Return the nth prime, with the primes indexed as prime(1) = 2. The nth prime is approximately n*log(n) and can never be larger than 2**n.
prevprime(n, ith=1) # Return the largest prime smaller than n
nextprime(n) # Return the ith prime greater than n
sieve.primerange(a, b) # Generate all prime numbers in the range [a, b), implemented as a dynamically growing sieve of Eratosthenes.
Here are some examples.
>>> import sympy
>>>
>>> sympy.isprime(5)
True
>>> list(sympy.primerange(0, 100))
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]
>>> sympy.randprime(0, 100)
83
>>> sympy.randprime(0, 100)
41
>>> sympy.prime(3)
5
>>> sympy.prevprime(50)
47
>>> sympy.nextprime(50)
53
>>> list(sympy.sieve.primerange(0, 100))
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]
Here's a simple (Python 2.6.2) solution... which is in-line with the OP's original request (now six-months old); and should be a perfectly acceptable solution in any "programming 101" course... Hence this post.
import math
def isPrime(n):
for i in range(2, int(math.sqrt(n)+1)):
if n % i == 0:
return False;
return n>1;
print 2
for n in range(3, 50):
if isPrime(n):
print n
This simple "brute force" method is "fast enough" for numbers upto about about 16,000 on modern PC's (took about 8 seconds on my 2GHz box).
Obviously, this could be done much more efficiently, by not recalculating the primeness of every even number, or every multiple of 3, 5, 7, etc for every single number... See the Sieve of Eratosthenes (see eliben's implementation above), or even the Sieve of Atkin if you're feeling particularly brave and/or crazy.
Caveat Emptor: I'm a python noob. Please don't take anything I say as gospel.
Here is a numpy version of Sieve of Eratosthenes having both okay complexity (lower than sorting an array of length n) and vectorization.
import numpy as np
def generate_primes(n):
is_prime = np.ones(n+1,dtype=bool)
is_prime[0:2] = False
for i in range(int(n**0.5)+1):
if is_prime[i]:
is_prime[i*2::i]=False
return np.where(is_prime)[0]
Timings:
import time
for i in range(2,10):
timer =time.time()
generate_primes(10**i)
print('n = 10^',i,' time =', round(time.time()-timer,6))
>> n = 10^ 2 time = 5.6e-05
>> n = 10^ 3 time = 6.4e-05
>> n = 10^ 4 time = 0.000114
>> n = 10^ 5 time = 0.000593
>> n = 10^ 6 time = 0.00467
>> n = 10^ 7 time = 0.177758
>> n = 10^ 8 time = 1.701312
>> n = 10^ 9 time = 19.322478
python 3 (generate prime number)
from math import sqrt
i = 2
while True:
for x in range(2, int(sqrt(i) + 1)):
if i%x==0:
break
else:
print(i)
i += 1
Here is what I have:
def is_prime(num):
if num < 2: return False
elif num < 4: return True
elif not num % 2: return False
elif num < 9: return True
elif not num % 3: return False
else:
for n in range(5, int(math.sqrt(num) + 1), 6):
if not num % n:
return False
elif not num % (n + 2):
return False
return True
It's pretty fast for large numbers, as it only checks against already prime numbers for divisors of a number.
Now if you want to generate a list of primes, you can do:
# primes up to 'max'
def primes_max(max):
yield 2
for n in range(3, max, 2):
if is_prime(n):
yield n
# the first 'count' primes
def primes_count(count):
counter = 0
num = 3
yield 2
while counter < count:
if is_prime(num):
yield num
counter += 1
num += 2
using generators here might be desired for efficiency.
And just for reference, instead of saying:
one = 1
while one == 1:
# do stuff
you can simply say:
while 1:
#do stuff
To my opinion it is always best to take the functional approach,
So I create a function first to find out if the number is prime or not then use it in loop or other place as necessary.
def isprime(n):
for x in range(2,n):
if n%x == 0:
return False
return True
Then run a simple list comprehension or generator expression to get your list of prime,
[x for x in range(1,100) if isprime(x)]
Another simple example, with a simple optimization of only considering odd numbers. Everything done with lazy streams (python generators).
Usage: primes = list(create_prime_iterator(1, 30))
import math
import itertools
def create_prime_iterator(rfrom, rto):
"""Create iterator of prime numbers in range [rfrom, rto]"""
prefix = [2] if rfrom < 3 and rto > 1 else [] # include 2 if it is in range separately as it is a "weird" case of even prime
odd_rfrom = 3 if rfrom < 3 else make_odd(rfrom) # make rfrom an odd number so that we can skip all even nubers when searching for primes, also skip 1 as a non prime odd number.
odd_numbers = (num for num in xrange(odd_rfrom, rto + 1, 2))
prime_generator = (num for num in odd_numbers if not has_odd_divisor(num))
return itertools.chain(prefix, prime_generator)
def has_odd_divisor(num):
"""Test whether number is evenly divisable by odd divisor."""
maxDivisor = int(math.sqrt(num))
for divisor in xrange(3, maxDivisor + 1, 2):
if num % divisor == 0:
return True
return False
def make_odd(number):
"""Make number odd by adding one to it if it was even, otherwise return it unchanged"""
return number | 1
This is my implementation. Im sure there is a more efficient way, but seems to work. Basic flag use.
def genPrime():
num = 1
prime = False
while True:
# Loop through all numbers up to num
for i in range(2, num+1):
# Check if num has remainder after the modulo of any previous numbers
if num % i == 0:
prime = False
# Num is only prime if no remainder and i is num
if i == num:
prime = True
break
if prime:
yield num
num += 1
else:
num += 1
prime = genPrime()
for _ in range(100):
print(next(prime))
Just studied the topic, look for the examples in the thread and try to make my version:
from collections import defaultdict
# from pprint import pprint
import re
def gen_primes(limit=None):
"""Sieve of Eratosthenes"""
not_prime = defaultdict(list)
num = 2
while limit is None or num <= limit:
if num in not_prime:
for prime in not_prime[num]:
not_prime[prime + num].append(prime)
del not_prime[num]
else: # Prime number
yield num
not_prime[num * num] = [num]
# It's amazing to debug it this way:
# pprint([num, dict(not_prime)], width=1)
# input()
num += 1
def is_prime(num):
"""Check if number is prime based on Sieve of Eratosthenes"""
return num > 1 and list(gen_primes(limit=num)).pop() == num
def oneliner_is_prime(num):
"""Simple check if number is prime"""
return num > 1 and not any([num % x == 0 for x in range(2, num)])
def regex_is_prime(num):
return re.compile(r'^1?$|^(11+)\1+$').match('1' * num) is None
def simple_is_prime(num):
"""Simple check if number is prime
More efficient than oneliner_is_prime as it breaks the loop
"""
for x in range(2, num):
if num % x == 0:
return False
return num > 1
def simple_gen_primes(limit=None):
"""Prime number generator based on simple gen"""
num = 2
while limit is None or num <= limit:
if simple_is_prime(num):
yield num
num += 1
if __name__ == "__main__":
less1000primes = list(gen_primes(limit=1000))
assert less1000primes == list(simple_gen_primes(limit=1000))
for num in range(1000):
assert (
(num in less1000primes)
== is_prime(num)
== oneliner_is_prime(num)
== regex_is_prime(num)
== simple_is_prime(num)
)
print("Primes less than 1000:")
print(less1000primes)
from timeit import timeit
print("\nTimeit:")
print(
"gen_primes:",
timeit(
"list(gen_primes(limit=1000))",
setup="from __main__ import gen_primes",
number=1000,
),
)
print(
"simple_gen_primes:",
timeit(
"list(simple_gen_primes(limit=1000))",
setup="from __main__ import simple_gen_primes",
number=1000,
),
)
print(
"is_prime:",
timeit(
"[is_prime(num) for num in range(2, 1000)]",
setup="from __main__ import is_prime",
number=100,
),
)
print(
"oneliner_is_prime:",
timeit(
"[oneliner_is_prime(num) for num in range(2, 1000)]",
setup="from __main__ import oneliner_is_prime",
number=100,
),
)
print(
"regex_is_prime:",
timeit(
"[regex_is_prime(num) for num in range(2, 1000)]",
setup="from __main__ import regex_is_prime",
number=100,
),
)
print(
"simple_is_prime:",
timeit(
"[simple_is_prime(num) for num in range(2, 1000)]",
setup="from __main__ import simple_is_prime",
number=100,
),
)
The result of running this code show interesting results:
$ python prime_time.py
Primes less than 1000:
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997]
Timeit:
gen_primes: 0.6738066330144648
simple_gen_primes: 4.738092333020177
is_prime: 31.83770858097705
oneliner_is_prime: 3.3708438930043485
regex_is_prime: 8.692703998007346
simple_is_prime: 0.4686249239894096
So I can see that we have right answers for different questions here; for a prime number generator gen_primes looks like the right answer; but for a prime number check, the simple_is_prime function is better suited.
This works, but I am always open to better ways to make is_prime function.
You need to make sure that all possible divisors don't evenly divide the number you're checking. In this case you'll print the number you're checking any time just one of the possible divisors doesn't evenly divide the number.
Also you don't want to use a continue statement because a continue will just cause it to check the next possible divisor when you've already found out that the number is not a prime.
This seems homework-y, so I'll give a hint rather than a detailed explanation. Correct me if I've assumed wrong.
You're doing fine as far as bailing out when you see an even divisor.
But you're printing 'count' as soon as you see even one number that doesn't divide into it. 2, for instance, does not divide evenly into 9. But that doesn't make 9 a prime. You might want to keep going until you're sure no number in the range matches.
(as others have replied, a Sieve is a much more efficient way to go... just trying to help you understand why this specific code isn't doing what you want)
You can create a list of primes using list comprehensions in a fairly elegant manner. Taken from here:
>>> noprimes = [j for i in range(2, 8) for j in range(i*2, 50, i)]
>>> primes = [x for x in range(2, 50) if x not in noprimes]
>>> print primes
>>> [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47]
How about this if you want to compute the prime directly:
def oprime(n):
counter = 0
b = 1
if n == 1:
print 2
while counter < n-1:
b = b + 2
for a in range(2,b):
if b % a == 0:
break
else:
counter = counter + 1
if counter == n-1:
print b
Similar to user107745, but using 'all' instead of double negation (a little bit more readable, but I think same performance):
import math
[x for x in xrange(2,10000) if all(x%t for t in xrange(2,int(math.sqrt(x))+1))]
Basically it iterates over the x in range of (2, 100) and picking only those that do not have mod == 0 for all t in range(2,x)
Another way is probably just populating the prime numbers as we go:
primes = set()
def isPrime(x):
if x in primes:
return x
for i in primes:
if not x % i:
return None
else:
primes.add(x)
return x
filter(isPrime, range(2,10000))
import time
maxnum=input("You want the prime number of 1 through....")
n=2
prime=[]
start=time.time()
while n<=maxnum:
d=2.0
pr=True
cntr=0
while d<n**.5:
if n%d==0:
pr=False
else:
break
d=d+1
if cntr==0:
prime.append(n)
#print n
n=n+1
print "Total time:",time.time()-start
For me, the below solution looks simple and easy to follow.
import math
def is_prime(num):
if num < 2:
return False
for i in range(2, int(math.sqrt(num) + 1)):
if num % i == 0:
return False
return True
If you wanted to find all the primes in a range you could do this:
def is_prime(num):
"""Returns True if the number is prime
else False."""
if num == 0 or num == 1:
return False
for x in range(2, num):
if num % x == 0:
return False
else:
return True
num = 0
itr = 0
tot = ''
while itr <= 100:
itr = itr + 1
num = num + 1
if is_prime(num) == True:
print(num)
tot = tot + ' ' + str(num)
print(tot)
Just add while its <= and your number for the range.
OUTPUT:
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 101
Using generator:
def primes(num):
if 2 <= num:
yield 2
for i in range(3, num + 1, 2):
if all(i % x != 0 for x in range(3, int(math.sqrt(i) + 1))):
yield i
Usage:
for i in primes(10):
print(i)
2, 3, 5, 7
The continue statement looks wrong.
You want to start at 2 because 2 is the first prime number.
You can write "while True:" to get an infinite loop.
def genPrimes():
primes = [] # primes generated so far
last = 1 # last number tried
while True:
last += 1
for p in primes:
if last % p == 0:
break
else:
primes.append(last)
yield last
def check_prime(x):
if (x < 2):
return 0
elif (x == 2):
return 1
t = range(x)
for i in t[2:]:
if (x % i == 0):
return 0
return 1
This is the fastest way to find primes up to n that I have seen. Up to 100m in 1.2 seconds.
It uses pure python without dependencies
def primes(lim):
if lim<7:
if lim<2: return []
if lim<3: return [2]
if lim<5: return [2, 3]
return [2, 3, 5]
n = (lim-1)//30
m = n+1
BA = bytearray
prime1 = BA([1])*m
prime7 = BA([1])*m
prime11 = BA([1])*m
prime13 = BA([1])*m
prime17 = BA([1])*m
prime19 = BA([1])*m
prime23 = BA([1])*m
prime29 = BA([1])*m
prime1[0] = 0
i = 0
try:
while 1:
if prime1[i]:
p = 30*i+1
l = i*(p+1)
prime1[l::p] = BA(1+(n-l)//p)
l += i*6
prime7[l::p] = BA(1+(n-l)//p)
l += i*4
prime11[l::p] = BA(1+(n-l)//p)
l += i*2
prime13[l::p] = BA(1+(n-l)//p)
l += i*4
prime17[l::p] = BA(1+(n-l)//p)
l += i*2
prime19[l::p] = BA(1+(n-l)//p)
l += i*4
prime23[l::p] = BA(1+(n-l)//p)
l += i*6
prime29[l::p] = BA(1+(n-l)//p)
if prime7[i]:
p = 30*i+7
l = i*(p+7)+1
prime19[l::p] = BA(1+(n-l)//p)
l += i*4+1
prime17[l::p] = BA(1+(n-l)//p)
l += i*2+1
prime1[l::p] = BA(1+(n-l)//p)
l += i*4
prime29[l::p] = BA(1+(n-l)//p)
l += i*2+1
prime13[l::p] = BA(1+(n-l)//p)
l += i*4+1
prime11[l::p] = BA(1+(n-l)//p)
l += i*6+1
prime23[l::p] = BA(1+(n-l)//p)
l += i*2+1
prime7[l::p] = BA(1+(n-l)//p)
if prime11[i]:
p = 30*i+11
l = i*(p+11)+4
prime1[l::p] = BA(1+(n-l)//p)
l += i*2
prime23[l::p] = BA(1+(n-l)//p)
l += i*4+2
prime7[l::p] = BA(1+(n-l)//p)
l += i*2
prime29[l::p] = BA(1+(n-l)//p)
l += i*4+2
prime13[l::p] = BA(1+(n-l)//p)
l += i*6+2
prime19[l::p] = BA(1+(n-l)//p)
l += i*2+1
prime11[l::p] = BA(1+(n-l)//p)
l += i*6+2
prime17[l::p] = BA(1+(n-l)//p)
if prime13[i]:
p = 30*i+13
l = i*(p+13)+5
prime19[l::p] = BA(1+(n-l)//p)
l += i*4+2
prime11[l::p] = BA(1+(n-l)//p)
l += i*2+1
prime7[l::p] = BA(1+(n-l)//p)
l += i*4+1
prime29[l::p] = BA(1+(n-l)//p)
l += i*6+3
prime17[l::p] = BA(1+(n-l)//p)
l += i*2+1
prime13[l::p] = BA(1+(n-l)//p)
l += i*6+3
prime1[l::p] = BA(1+(n-l)//p)
l += i*4+1
prime23[l::p] = BA(1+(n-l)//p)
if prime17[i]:
p = 30*i+17
l = i*(p+17)+9
prime19[l::p] = BA(1+(n-l)//p)
l += i*2+1
prime23[l::p] = BA(1+(n-l)//p)
l += i*4+3
prime1[l::p] = BA(1+(n-l)//p)
l += i*6+3
prime13[l::p] = BA(1+(n-l)//p)
l += i*2+1
prime17[l::p] = BA(1+(n-l)//p)
l += i*6+3
prime29[l::p] = BA(1+(n-l)//p)
l += i*4+3
prime7[l::p] = BA(1+(n-l)//p)
l += i*2+1
prime11[l::p] = BA(1+(n-l)//p)
if prime19[i]:
p = 30*i+19
l = i*(p+19)+12
prime1[l::p] = BA(1+(n-l)//p)
l += i*4+2
prime17[l::p] = BA(1+(n-l)//p)
l += i*6+4
prime11[l::p] = BA(1+(n-l)//p)
l += i*2+1
prime19[l::p] = BA(1+(n-l)//p)
l += i*6+4
prime13[l::p] = BA(1+(n-l)//p)
l += i*4+2
prime29[l::p] = BA(1+(n-l)//p)
l += i*2+2
prime7[l::p] = BA(1+(n-l)//p)
l += i*4+2
prime23[l::p] = BA(1+(n-l)//p)
if prime23[i]:
p = 30*i+23
l = i*(p+23)+17
prime19[l::p] = BA(1+(n-l)//p)
l += i*6+5
prime7[l::p] = BA(1+(n-l)//p)
l += i*2+1
prime23[l::p] = BA(1+(n-l)//p)
l += i*6+5
prime11[l::p] = BA(1+(n-l)//p)
l += i*4+3
prime13[l::p] = BA(1+(n-l)//p)
l += i*2+1
prime29[l::p] = BA(1+(n-l)//p)
l += i*4+4
prime1[l::p] = BA(1+(n-l)//p)
l += i*2+1
prime17[l::p] = BA(1+(n-l)//p)
if prime29[i]:
p = 30*i+29
l = i*(p+29)+28
prime1[l::p] = BA(1+(n-l)//p)
l += i*2+1
prime29[l::p] = BA(1+(n-l)//p)
l += i*6+6
prime23[l::p] = BA(1+(n-l)//p)
l += i*4+4
prime19[l::p] = BA(1+(n-l)//p)
l += i*2+2
prime17[l::p] = BA(1+(n-l)//p)
l += i*4+4
prime13[l::p] = BA(1+(n-l)//p)
l += i*2+2
prime11[l::p] = BA(1+(n-l)//p)
l += i*4+4
prime7[l::p] = BA(1+(n-l)//p)
i+=1
except:
pass
RES = [2, 3, 5]
A = RES.append
ti=0
try:
for i in range(n):
if prime1[i]:
A(ti+1)
if prime7[i]:
A(ti+7)
if prime11[i]:
A(ti+11)
if prime13[i]:
A(ti+13)
if prime17[i]:
A(ti+17)
if prime19[i]:
A(ti+19)
if prime23[i]:
A(ti+23)
if prime29[i]:
A(ti+29)
ti+=30
except:
pass
if prime1[n] and (30*n+1)<=lim:
A(30*n+1)
if prime7[n] and (30*n+7)<=lim:
A(30*n+7)
if prime11[n] and (30*n+11)<=lim:
A(30*n+11)
if prime13[n] and (30*n+13)<=lim:
A(30*n+13)
if prime17[n] and (30*n+17)<=lim:
A(30*n+17)
if prime19[n] and (30*n+19)<=lim:
A(30*n+19)
if prime23[n] and (30*n+23)<=lim:
A(30*n+23)
if prime29[n] and (30*n+29)<=lim:
A(30*n+29)
return RES
from time import time
n = time()
print (primes(100000000)[-1])
print (time() - n)

Categories