is there a way to let the program select a random number between say 1 and 1,000 without importing random
?
Based on random
source code:
def randint(a, b):
"Return random integer in range [a, b], including both end points."
return a + randbelow(b - a + 1)
def randbelow(n):
"Return a random int in the range [0,n). Raises ValueError if n<=0."
if n <= 0:
raise ValueError
k = n.bit_length()
numbytes = (k + 7) // 8
while True:
r = int.from_bytes(random_bytes(numbytes), 'big')
r >>= numbytes * 8 - k
if r < n:
return r
def random_bytes(n):
"Return n random bytes"
with open('/dev/urandom', 'rb') as file:
return file.read(n)
Example:
print(randint(1, 1000))
You could also implement random_bytes()
using PRNG.
There are many interesting ways to generate randomness without resorting to random (or numpy). For instance, you can use the built in hash function:
def rand_generator(seed, N=10**6, a=0, b=10, integer = True):
'''For a given seed, this function returns N pseudo-random between a and b'''
rands =[]
if integer:
for i in range(N):
num = int(a+(b-a)*(abs(hash(str(hash(str(seed)+str(i+1)))))%10**13)/10**13)
rands.append(num)
return rands
else:
for i in range(N):
num = a+(b-a)*(abs(hash(str(hash(str(seed)+str(i+1)))))%10**13)/10**13
rands.append(num)
return rands
This will generate a list of uniformly distributed pseudo-random numbers between 0 and 1. Like the random number generators in random and numpy the sequence is fully deterministic for a given seed.
Histogram of the function's output.
This algorithm is in no way cryptographically safe but it should be sufficient to answer your question.
If storing the entire list undesirable then the same idea can take the form of a generator expression. After setting the values for a, b, N, and seed as above:
randnum = (int(a+(b-a)*(abs(hash(str(hash(str(seed)+str(j+1))))) % 10**13)/ 10**13) for i in range(N))
is an iterator which generates the next number in the sequence via
>>> next(randnum)
5
This can be made even neater as follows:
def random(seed = None, a=0, b=10, N=10**12, integer=True):
'''Pass a seed to generate new sequence, otherwise next value is returned.'''
if seed:
print("Starting new sequence.")
global _rand_generator
if integer:
hash_plus = lambda j: int(a + (b-a)*(abs(hash(str(hash(str(seed) + str(j+1))))) % 10**13)/ 10**13)
else:
hash_plus = lambda j: a + (b-a)*(abs(hash(str(hash(str(seed) + str(j+1))))) % 10**13)/ 10**13
_rand_generator = (hash_plus(j) for j in range(N))
try:
return next(_rand_generator)
except:
print("Random seed required.")
To generate a random sequence pass a seed to the function.
>>> random(42)
Starting new sequence.
8
Call the function again without a seed to yield the next random number/integer in the sequence.
>>> for i in range(10):
... print(random())
3
4
6
5
5
9
2
2
4
0
To start a new sequence, simply call the function again with a new seed.
>>> random(666)
Starting new sequence.
5
assuming you want integers.
import numpy as np
np.random.randint(1,1000)
#method one, set new seed every time random is needed
seed = "seed" #can be int or string, varies between compilings of the game
possibilities = 3 #0,1,2
hash(str(seed))%possibilities
hash(str(0))%3 #single random number between 0,1,2 (inc) seed is 0
#method two, generate a random list of numbers
size = 100 #length of list
possibilities = 2 #0,1
[hash(str(seed))%possibilities for seed in range(size)]
[hash(str(seed))%5 for seed in range(100)] #generates a list of numbers between 0,1,2,3,4 (inc) with the size of 100
hash(" ")%6
[hash(str(seed))%2 for seed in range(100)].count(1) #validity check. output is ~50
i wrote this program to help with this problem
Lucky me, the environment I'm in happens to have datetime available already. Datetime would normally require an import so this doesn't solve the problem w/o any imports (which is what I think the OP was getting at)
And, let's be clear, this is not a truly random number but it's close enough for many practical applications.
int( str( datetime.now().microsecond )[-1] )
# yields a number from 0 through 9
int( str( datetime.now().microsecond )[-2:] )
# yields a number from 0 through 99
© 2022 - 2024 — McMap. All rights reserved.
random
? You could start writing your own random number generation code, but why would you? – Minatory