This is what I have so far:
import random
for x in range(10):
tickets = [random.sample(range(0,59), 6)]
print (tickets)
But I need to make it so that all the numbers generated are different except for two numbers which are the same.
So that's my problem and would appreciate help before Friday! This is the question I was asked for reference: "My new year's resolution is to win the lottery. To do this I will buy 10 tickets each week. I shall choose 6 numbers at random for each ticket. The numbers range from 1 to 59. All the numbers can only be used once except for one which will need to be duplicated. Write a program in python to simulate this."
You can avoid repeated numbers by keeping track of those that have been used and disallowing them in later samples:
import random
def non_repeating_random_sample(population, k, seen):
while True:
sample = random.sample(population, k)
if not any(number in seen for number in sample):
seen.union(sample)
return sample
seen = set()
for _ in range(10):
tickets = [non_repeating_random_sample(range(0, 59), 6, seen)]
print(tickets)
When doing something like this, it may be important to understand that the samples returned—except for the first one—aren't really random because of the additional restraint.
Regardless, it would be simpler and faster to just shuffle the entire population, and then extract groups of of the desired size from it:
import random
number_of_samples = 10
number_per_sample = 6
samples = list(range(number_of_samples*number_per_sample))
random.shuffle(samples)
generator = zip(*[iter(samples)]*number_per_sample)
for _ in range(number_of_samples):
print(list(next(generator)))
Related
My goal is to generate a series of random numbers without allowing the same number repeating next to eachother but allowing the same number twice like 1,2,1,2 but not 1,1,2,2 and I'm just not really sure how to accomplish this.
Something like this?
import random
list = []
list.append(random.randrange(50))
for i in range(50):
x = random.randrange(50)
while x == list[i]:
x = random.randrange(50)
list.append(x)
print(list)
Also you should post your own attempt. It gives everyone a good reference and starting point to help you out in a meaning full and focused way.
I want a random generator that does not generate any numbers generated before. Calling this generator does not return a list. It returns 1 number every time and the number will be a totally new number not generated before.
My idea of implementing this so far is to generate a long non-repeating random list first and then retrieve from the list one by one.
Using Python, but I guess this is more of a general logic question.
edit:
Sorry for the confusion everyone. Clarification on the problem I am trying to implement: I am developing an app where a user can sign up and receive a hotel room number. The app has some hotels setup. Each new user will receive a unique hotel number of the hotel. The range will probably be from 0001 to 9999. My goal of this is to have an algorithm spit out a random number from 0001 to 9999 for that user, and this number has to be unique so that each room number of a hotel is occupied by one user only. I am using Django.
If you already know the numbers you need to select from,
import random
x = [4,3,6,7,2,...] # list of desired numbers
result = x.pop(random.randint(0, len(x) - 1))
You can do something like:
import numpy as np
random_nums = []
for _ in range(10):
while True:
x = np.random.randint(0,10)
if x not in random_nums:
random_nums.append(x)
break
import random
number=list(range(1,10))
weighted=[1]*2+[2]*2+[3]*2+[4]*2+[5]*2
number_weighted=random.choice(number,weighted,k=1) **#if k=4 then the same number is chosen sometimes**
I want to use loop 3 times to choose the each one number.
I want to choose the number that independent(not same), weighted.
In python, if you know this problem, I would appreciate it if you taught me
For example,
number=[1,2,3,4,5]
weighted=[0.1,0.1,0.4,0.3,0.1]
then choose two number
i want 3, 4 Probability)
but random.choice function is sometimes 1,1 selected.
so, i think
i take one number (suppose number 3) then
number=[1,2,4,5]
weighted=[0.1,0.1,0.3,0.1]
and i take one number (suppose number 4). use loop function
Your question isn't quite clear, so comment if it doesn't solve your problem.
Define functionn which returns random from the list and weight. another function to make sure you have n randoms from different weights.
And your weight and array was of different length I hope that was an error.
import random
def get_rand(num_list,weight_list,weight):
selection_from= [i for i,v in enumerate(weight_list) if v==weight]
print(selection_from)
rand_index =random.choice(selection_from)
return num_list[rand_index]
def get_n_rand(num_list,weight_list,n):
weights= list(set(weight_list))
random.shuffle(weights)
final_list=[]
# if you don't want numbers from same weight
for weight in weights[:n]:
final_list.append(get_rand(num_list,weight_list,weight))
#if same weight is also fine use this:
#for i in range(n):
# weight = random.choice(weights)
# final_list.append(get_rand(num_list,weight_list,weight))
return final_list
number=list(range(1,10))
weighted=[1]*2+[2]*2+[3]*2+[4]*2+[5]*1
assert(len(number)==len(weighted))
rand=get_n_rand(number,weighted,3)
print("selected numbers:",rand)
print("their weights:",[weighted[number.index(i)] for i in rand])
Since you had hard time understanding,
selection_from= [i for i,v in enumerate(weight_list) if v==weight]
is equivalent to:
selection_from= []
for i in range(len(weight_list)):
v= weight_list[i]
if v==weight:
selection_from.append(i)
Probably a simple answer, not sure what I am missing. For a homework assignment I have to use random.random() to generate numbers between 30 and 35. The seed has to be set to 70 to match the pseudo-random numbers with the grader. This wasn't in my lecture so I am a little stumped as to what to do.
I have:
import random
def problem2_4():
print(random.random(30,35))
But this is clearly wrong.
The assignment says the output should look like (note: for the problem i use def problem2_4() just for the assignment grading system)
problem2_4()
[34.54884618961936, 31.470395203793395, 32.297169396656095, 30.681793552717807,
34.97530360173135, 30.773219981037737, 33.36969776732032, 32.990127772708405,
33.57311858494461, 32.052629620057274]
The output [blah, blah, blah] indicates that it is a list of numbers rather than a series of numbers printed one-by-one.
In addition, if you want random floating point values, you'll need to transform the numbers from random.random (which are zero to one) into that range.
That means you'll probably need something like:
import random # Need this module.
def problem2_4():
random.seed(70) # Set initial seed.
nums = [] # Start with empty list.
for _ in range(10): # Will add ten values.
nums += [random.random() * 5 + 30] # Add one value in desired range.
print(nums) # Print resultant list.
Of course, the Pythonic way to do this would be:
import random
random.seed(70)
print([random.random() * 5 + 30 for _ in range(10)])
Bit that might be a bit ahead of where your educator is working. Still, it's good to learn this stuff as early as possile since you'll never be a Pythonista until you do :-)
The function that you are looking for is randint, which returns an integer (whole number) between the specified minimum and maximum values.
So the solution would be
random.randint(30, 35)
Python Docs
I am trying to generate random numbers that are used to generate a part of a world (I am working on world generation for a game). I could create these with something like [random.randint(0, 100) for n in range(1000)] to generate 1000 random numbers from 0 to 100, but I don't know how many numbers in a list I need. What I want is to be able to say something like random.nth_randint(0, 100, 5) which would generate the 5th random number from 0 to 100. (The same number every time as long as you use the same seed) How would I go about doing this? And if there is no way to do this, how else could I get the same behavior?
Python's random module produces deterministic pseudo random values.
In simpler words, it behaves as if it generated a list of predetermined values when a seed is provided (or when default seed is taken from OS), and those values will always be the same for a given seed.
Which is basically what we want here.
So to get nth random value you need to either remember its state for each generated value (probably just keeping track of the values would be less memory hungry) or you need to reset (reseed) the generator each time and produce N random numbers each time to get yours.
def randgen(a, b, n, seed=4):
# our default seed is random in itself as evidenced by https://xkcd.com/221/
random.seed(seed)
for i in range(n-1):
x = random.random()
return random.randint(a, b)
If I understood well your question you want every time the same n-th number. You may create a class where you keep track of the generated numbers (if you use the same seed).
The main idea is that, when you ask for then nth-number it will generate all the previous in order to be always the same for all the run of the program.
import random
class myRandom():
def __init__(self):
self.generated = []
#your instance of random.Random()
self.rand = random.Random(99)
def generate(self, nth):
if nth < len(self.generated) + 1:
return self.generated[nth - 1]
else:
for _ in range(len(self.generated), nth):
self.generated.append(self.rand.randint(1,100))
return self.generated[nth - 1]
r = myRandom()
print(r.generate(1))
print(r.generate(5))
print(r.generate(10))
Using a defaultdict, you can have a structure that generates a new number on the first access of each key.
from collections import defaultdict
from random import randint
random_numbers = defaultdict(lambda: randint(0, 100))
random_number[5] # 42
random_number[5] # 42
random_number[0] # 63
Numbers are thus lazily generated on access.
Since you are working on a game, it is likely you will then need to preserve random_numbers through interruptions of your program. You can use pickle to save your data.
import pickle
random_numbers[0] # 24
# Save the current state
with open('random', 'wb') as f:
pickle.dump(dict(random_numbers), f)
# Load the last saved state
with open('random', 'rb') as f:
opened_random_numbers = defaultdict(lambda: randint(0, 100), pickle.load(f))
opened_random_numbers[0] # 24
Numpy's new random BitGenerator interface provides a method advance(delta) some of the BitGenerator implementations (including the default BitGenerator used). This function allows you to seed and then advance to get the n-th random number.
From the docs:
Advance the underlying RNG as-if delta draws have occurred.
https://numpy.org/doc/stable/reference/random/bit_generators/generated/numpy.random.PCG64.advance.html#numpy.random.PCG64.advance