Python programming probability marble out of a bag coding - python

Hey I'm new to programming but I cant seem to code probability questions. For example, how would I code this?
A box contains 12 transistors of type A and 18 of type B. one transistor is taken out at random and returned. This process is repeated. Determine the probability that the first chosen is type A and second is type B. Thanks!
This is my first try.
from scipy import stats as st
import numpy as np
import random
total=30
totalA=12
totalB=18
def transistor():
return random.choice("A","B")
random.seed(0)
for _in range(30):
try1=transistor()
try2=transistor()
if try1="A":
prob1=totalA/total
else:
prob1=totalB/total
if try2="A":
prob2=totalA/total
else:
prob2=totalB/total
if try1=="A" and try2=="A"
prob=2*totalA/total

If you're trying to run a simulation, this code will give you a probability from 10000 trials. It will generate a different result every time. The more trials, the more accurate it is. The correct, theoretical answer is 0.24.
import random
trials = 10000 # total number of trials
totalA = 12 # total number of A transistors
totalB = 18 # total number of B transistors
successes = 0 # variable keeping track of how many successful pulls there were
choicelist = list("A" * totalA + "B" * totalB) # list containing transitors to correct proportion
def transistor():
return random.choice(choicelist) # pick a random transistor from list
for i in range(trials):
try1 = transistor()
try2 = transistor()
if try1 == "A" and try2 == "B": # if first pull is type A and second is type B...
successes += 1 # ...then it's successful
print float(successes) / trials # print out the proportion of successes to trials

Related

Trying to add a progress bar as my python program runs

I am a beginner writing a Python code, where the computer generates a random number between 1 and 10, 1 and 100, 1 and 1000, 1 and 10000, 1 and 100000 and so on. The computer itself will guess the random number a number of times (a user input number), and every time there is a count of how many times the computer took to guess the random number. A mean of the count over the number of times will be calculated and put in an array, where matplotlib will generate a graph of x=log10(the upper bounds of the random number range, i.e. 10, 100, 1000,...)
At the moment, I print the log10 of each bound as it is processed, and that has been acting as my progress tracker. But I am thinking of adding my progress bar, and I don't know where to put it so that I can see how much of the overall program has run.
I have added tqdm.tqdm in all sorts of different places to no avail. I am expecting a progress bar increasing as the program runs.
My program is as shown.
# Importing the modules needed
import random
import time
import timeit
import numpy as np
import matplotlib.pyplot as plt
import tqdm
# Function for making the computer guess the number it itself has generated and seeing how many times it takes for it to guess the number
def computer_guess(x):
# Telling program that value "low" exists and it's 0
low = 0
# Telling program that value "high" exists and it's the arbitrary parameter x
high = x
# Storing random number with lower limit "low" and upper limit "high" as "ranno" for the while-loop later
ranno = random.randint(low, high)
# Setting initial value of "guess" for iteration
guess = -1
# Setting initial value of "count" for iteration
count = 1
# While-loop for all guessing conditions
while guess != ranno:
# Condition: As long as values of "low" and "high" aren't the same, keep guessing until the values are the same, in which case "guess" is same as "low" (or "high" becuase they are the same anyway)
if low != high:
guess = random.randint(low, high)
else:
guess = low
# Condition: If the guess if bigger than the random number, lower the "high" value to one less than 1, and add 1 to the guess count
if guess > ranno:
high = guess - 1
count += 1
# Condition: If the guess if smaller than the random number, increase the "low" value to one more than 1, and add 1 to the guess count
elif guess < ranno:
low = guess + 1
count += 1
# Condition: If it's not either of the above, i.e. the computer has guessed the number, return the guess count for this function
else:
return count
# Setting up a global array "upper_bounds" of the range of range of random numbers as a log array from 10^1 to 10^50
upper_bounds = np.logspace(1, 50, 50, 10)
def guess_avg(no_of_guesses):
# Empty array for all averages
list_of_averages = []
# For every value in the "upper_bounds" array,
for bound in upper_bounds:
# choose random number, "ranx", between 0 and the bound in the array
ranx = random.randint(0, bound)
# make an empty Numpy array, "guess_array", to insert the guesses into
guess_array = np.array([])
# For every value in whatever the no_of_guesses is when function called,
for i in np.arange(no_of_guesses):
# assign value, "guess", as calling function with value "ranx"
guess = computer_guess(ranx)
# stuff each resultant guess into the "guess_array" array
guess_array = np.append(guess_array, guess)
# Print log10 of each value in "upper_bound"
print(int(np.log10(bound)))
# Finding the mean of each value of the array of all guesses for the order of magnitude
average_of_guesses = np.mean(guess_array)
# Stuff the averages of guesses into the array the empty array made before
list_of_averages.append(average_of_guesses)
# Save the average of all averages in the list of averages into a single variable
average_of_averages = np.mean(list_of_averages)
# Print the list of averages
print(f"Your list of averages: {list_of_averages}")
# Print the average of averages
print(f"Average of averages: {average_of_averages}")
return list_of_averages
# Repeat the "guess_avg" function as long as the program is running
while True:
# Ask user to input a number for how many guesses they want the computer to make for each order of magnitude, and use that number for calling the function "guess_avg()"
resultant_average_numbers = guess_avg(
int(input("Input the number of guesses you want the computer to make: ")))
# Plot a graph with log10 of the order of magnitudes on the horizontal and the returned number of average of guesses
plt.plot(np.log10(upper_bounds), resultant_average_numbers)
# Show plot
plt.show()
I apologise if this is badly explained, it's my first time using Stackoverflow.
You can define the following progress_bar function, which you will call from wherever you want to monitor the advancement in you code:
import colorama
def progress_bar(progress, total, color=colorama.Fore.YELLOW):
percent = 100 * (progress / float(total))
bar = '█' * int(percent) + '-' * (100 - int(percent))
print(color + f'\r|{bar}| {percent:.2f}%', end='\r')
if progress == total:
print(colorama.Fore.GREEN + f'\r|{bar}| {percent:.2f}%', end='\r')
Hope this helps
You can also call tqdm by hand and then update it manually.
progress_bar = tqdm.tqdm(total=100)
progress_bar.update()
When you are finished, you can call progress_bar.clear() to start again.
You probably want two progress bars in the guess_avg() function. One to track the ranges and another to track the guesses.
In this example I've used the Enlighten progress bar library, but you can accomplish similar behavior with other libraries that support nested progress bars. One advantage Enlighten is going to have over others is you can print whatever you want while the progress bar is running, good for debugging.
You can make this simpler by using context managers and auto-updating counters, but I didn't do that here to make it clearer what's happening. You can also customize the template used for the progress bar.
import enlighten
def guess_avg(no_of_guesses):
# Empty array for all averages
list_of_averages = []
# For every value in the "upper_bounds" array,
# Create a progress bar manager manager
manager = enlighten.get_manager(leave=False)
# Create main progress bar for ranges
pbar_bounds = manager.counter(total=len(upper_bounds), desc='Bound ranges', unit='ranges')
for bound in upper_bounds:
# choose random number, "ranx", between 0 and the bound in the array
ranx = random.randint(0, bound)
# make an empty Numpy array, "guess_array", to insert the guesses into
guess_array = np.array([])
# For every value in whatever the no_of_guesses is when function called,
# Create nested progress bar for guesses, leave removes progress bar on close
pbar_guesses = manager.counter(total=no_of_guesses, desc='Guessing', unit='guesses', leave=False)
for i in np.arange(no_of_guesses):
# assign value, "guess", as calling function with value "ranx"
guess = computer_guess(ranx)
# stuff each resultant guess into the "guess_array" array
guess_array = np.append(guess_array, guess)
pbar_guesses.update() # Update nested progress bar
pbar_guesses.close() # Close nested progress bar
# Print log10 of each value in "upper_bound"
print(int(np.log10(bound))) # You can remove this now if you want
pbar_bounds.update() # Update main progress bar
# Finding the mean of each value of the array of all guesses for the order of magnitude
average_of_guesses = np.mean(guess_array)
# Stuff the averages of guesses into the array the empty array made before
list_of_averages.append(average_of_guesses)
manager.stop() # Stop the progress bar manager
# Save the average of all averages in the list of averages into a single variable
average_of_averages = np.mean(list_of_averages)
# Print the list of averages
print(f"Your list of averages: {list_of_averages}")
# Print the average of averages
print(f"Average of averages: {average_of_averages}")
return list_of_averages

Monte Carlo simulation of Birthday paradox in python 3

The birthday paradox is that everyone has equal probability of having a birthday on any given of 365 days. We start adding people in a room. What is the probability that 2 people have birthdays on same day as a function of number of people in the room? The code I wrote is as follows:
import numpy as np
import matplotlib.pyplot as plt
x=[0]
y=[0]
for j in range(1000):
if j!=0:
freq = []
L1 = list(np.random.randint(low = 1, high=366, size = j))
result = list((i, L1.count(i)) for i in L1)
for a_tuple in result:
freq.append(a_tuple[1])
print(freq)
rep = j - freq.count(1)
prob = rep/j
y = y + [prob]
x = x + [j]
print(prob)
plt.plot(x,y)
Here, in L1 = list(np.random.randint(low = 1, high=366, size = j)) I select the day on which someone would have a birthday and in result = list((i, L1.count(i)) for i in L1) I calculate the frequency of birthdays on each day. The entire thing is looped over to account for increasing number of people.
In the following for loop, I isolate the unique events and find repetitions and store the value in rep.
Next I calculated the probability as fraction of people sharing birthdays and plotted them as a function of number.
However, the question requires me to find the probability of just one shared birthday. How do I calculate that? I think I have to loop this entire thing for number of trials but that just gives an accurate solution with less variations of the same program. Currently my program gives fraction of people having shared birthdays I think.
Birthday problem Wikipedia for better reference
NOTE
I assume that when n persons have been in the room, they are all thrown out of the room and then n+1 persons enter the room.
========================================
I would think of it this way;
First, set probs = [0]*365. Now, say 2 persons get in the room - we then write their birthdays onto a piece of paper and check, if those two dates are equal. If they are, we increase probs[2] by 1 (yes, theres some indexes that we don't need, and Python is 0-indexed etc. but to keep it simple).
Now do the same for 3 persons, for 4 persons, for 5 persons ... all the way up to 365.
Your array might look something like probs==[0,0,0,0,0,1,0,1,1,0,1,1,1,1,0,1....].
You can now start over from 2 persons (still keeping the same array as before i.e don't create a new one with 0's!), then 3 persons etc. and start over 1000 times. Your array might look like
probs==[0,0,2,0,4,1,5,2,9,12,10,17....,967,998]
If you divide that array by 1000 (elementwise) you now have your simulated probability as a function of n persons.
import numpy as np
import matplotlib.pyplot as plt
N_TOTAL_PERS= 366
N_SIM = 10000 #number of simulations
counts = np.zeros(N_TOTAL_PERS)
for _ in range(N_SIM):
for n in range(2,N_TOTAL_PERS):
b_days = np.random.randint(1,366,size=n) #Get each persons birth-day
counts [n] += len(b_days) != len(set(b_days)) #Increment if some birthdays are equal
total_probs = counts/N_SIM #convert to probabilities
total_probs[70] #Get the probability when 70 persons are together (0.9988)
plt.plot(range(N_TOTAL_PERS),total_probs)
which generates a plot that looks like
You should run multiple experiments for different number of people in the room. Note that for N_people > 365, the probability should compute equal to 1.
Refactoring your code, and changing the logic a bit, I came up with the following:
import numpy as np
import matplotlib.pyplot as plt
def random_birthdays(n_people):
return list(np.random.randint(low=1, high=366, size=n_people))
def check_random_room(n_people):
"""
Generates a random sample of `n_people` and checks if at least two of them
have the same birthday
"""
birthdays = random_birthdays(n_people)
return len(birthdays) != len(set(birthdays))
def estimate_probability(n_people, n_experiments):
results = [check_random_room(n_people) for _ in range(n_experiments)]
return sum(results)/n_experiments
N_EXPERIMENTS = 1000
x = list(range(1, 400))
y = [estimate_probability(x_i, N_EXPERIMENTS) for x_i in x]
plt.plot(x, y)
plt.show()

How to combine two programs into a single one?

I am trying to figure out how to find the average of how many seconds it takes for 1000 horses. I figured out how to find find the average of 1000 random integers and the time for one horse to finish. I do not understand how to implement them together.
EDIT: Any advice to make my code neater is fine!
EDIT 2: Sorry it probably wasn't clear. Part A was to find the average of 1000 random integers from ranges 10-20 which should be around 15. Part B is to see how many seconds it takes for one horse to finish a race which averages out to 450-500 something. Part C is supposed to simulate 1000 races but find also find the average. *
Here are my codes:
#Main Program
#This program will find the average of 1000 random numbers.
from random import randrange
def main():
numbers = []
for count in range(1000):
number = random.randrange(10,21)
numbers.append(number)
print('{} is the average of 1000 random numbers from the range 10 to 20.'.format(sum(numbers)/len(numbers)))
main()
#Part B
#This program will similate one horse race.
from random import randrange
def race():
goal = 10560 #2 miles is 10,560 feet
current_position = 0
elapsed_seconds = 0
while current_position <= goal:
elapsed_seconds += 1
current_position += randrange(4,41)
print('{} seconds for one horse to finish the race.'.format(elapsed_seconds))
race()
#Part C
#This program will find the average of 1000 horse races.
def races():
numbers = []
goal = 10560
current_position = 0
elapsed_seconds = 0
I'm not following your program completely, but I have a few thoughts.
One thing you probably need to do is imbed the race() module within races(), so that when you call races() is executes race(). To get the data sent back to the races() module, replace the print() function with a return function (keep and mind that return functions terminate loops), and put something like the following code into races():
race_value = race()
numbers.append(race_value)

Genetic Algorithm - creatures in 2d world are not learning

Goal -
I am trying to implement a genetic algorithm to optimise the fitness of a
species of creatures in a simulated two-dimensional world. The world contains edible foods, placed at random, and a population of monsters (your basic zombies). I need the algorithm to find behaviours that keep the creatures well fed and not dead.
What i have done -
So i start off by generating a 11x9 2d array in numpy, this is filled with random floats between 0 and 1. I then use np.matmul to go through each row of the array and multiply all of the random weights by all of the percepts (w1+p1*w2+p2....w9+p9) = a1.
This first generation is run and I then evaluate the fitness of each creature using (energy + (time of death * 100)). From this I build a list of creatures who performed above the average fitness. I then take the best of these "elite" creatures and put them back into the next population. For the remaining space I use a crossover function which takes two randomly selected "elite" creatures and mixes their genes. I have tested two different crossover functions one which does a two point crossover on each row and one which takes a row from each parent until the new child has a complete chromosome. My issue is that the creatures just don't really seem to be learning, at 75 turns I will only get 1 survivor every so often.
I am fully aware this might not be enough to go off but I am truly stuck on this and cannot figure out how to get these creatures to learn even though I think I am implementing the correct procedures. Occasionally I will get a 3-4 survivors rather than 1 or 2 but it appears to occur completely randomly, doesn't seem like there is much learning happening.
Below is the main section of code, it includes everything I have done but none of the provided code for the simulation
#!/usr/bin/env python
from cosc343world import Creature, World
import numpy as np
import time
import matplotlib.pyplot as plt
import random
import itertools
# You can change this number to specify how many generations creatures are going to evolve over.
numGenerations = 2000
# You can change this number to specify how many turns there are in the simulation of the world for a given generation.
numTurns = 75
# You can change this number to change the world type. You have two choices - world 1 or 2 (described in
# the assignment 2 pdf document).
worldType=2
# You can change this number to modify the world size.
gridSize=24
# You can set this mode to True to have the same initial conditions for each simulation in each generation - good
# for development, when you want to have some determinism in how the world runs from generation to generation.
repeatableMode=False
# This is a class implementing you creature a.k.a MyCreature. It extends the basic Creature, which provides the
# basic functionality of the creature for the world simulation. Your job is to implement the AgentFunction
# that controls creature's behaviour by producing actions in response to percepts.
class MyCreature(Creature):
# Initialisation function. This is where your creature
# should be initialised with a chromosome in a random state. You need to decide the format of your
# chromosome and the model that it's going to parametrise.
#
# Input: numPercepts - the size of the percepts list that the creature will receive in each turn
# numActions - the size of the actions list that the creature must create on each turn
def __init__(self, numPercepts, numActions):
# Place your initialisation code here. Ideally this should set up the creature's chromosome
# and set it to some random state.
#self.chromosome = np.random.uniform(0, 10, size=numActions)
self.chromosome = np.random.rand(11,9)
self.fitness = 0
#print(self.chromosome[1][1].size)
# Do not remove this line at the end - it calls the constructors of the parent class.
Creature.__init__(self)
# This is the implementation of the agent function, which will be invoked on every turn of the simulation,
# giving your creature a chance to perform an action. You need to implement a model here that takes its parameters
# from the chromosome and produces a set of actions from the provided percepts.
#
# Input: percepts - a list of percepts
# numAction - the size of the actions list that needs to be returned
def AgentFunction(self, percepts, numActions):
# At the moment the percepts are ignored and the actions is a list of random numbers. You need to
# replace this with some model that maps percepts to actions. The model
# should be parametrised by the chromosome.
#actions = np.random.uniform(0, 0, size=numActions)
actions = np.matmul(self.chromosome, percepts)
return actions.tolist()
# This function is called after every simulation, passing a list of the old population of creatures, whose fitness
# you need to evaluate and whose chromosomes you can use to create new creatures.
#
# Input: old_population - list of objects of MyCreature type that participated in the last simulation. You
# can query the state of the creatures by using some built-in methods as well as any methods
# you decide to add to MyCreature class. The length of the list is the size of
# the population. You need to generate a new population of the same size. Creatures from
# old population can be used in the new population - simulation will reset them to their
# starting state (not dead, new health, etc.).
#
# Returns: a list of MyCreature objects of the same length as the old_population.
def selection(old_population, fitnessScore):
elite_creatures = []
for individual in old_population:
if individual.fitness > fitnessScore:
elite_creatures.append(individual)
elite_creatures.sort(key=lambda x: x.fitness, reverse=True)
return elite_creatures
def crossOver(creature1, creature2):
child1 = MyCreature(11, 9)
child2 = MyCreature(11, 9)
child1_chromosome = []
child2_chromosome = []
#print("parent1", creature1.chromosome)
#print("parent2", creature2.chromosome)
for row in range(11):
chromosome1 = creature1.chromosome[row]
chromosome2 = creature2.chromosome[row]
index1 = random.randint(1, 9 - 2)
index2 = random.randint(1, 9 - 2)
if index2 >= index1:
index2 += 1
else: # Swap the two cx points
index1, index2 = index2, index1
child1_chromosome.append(np.concatenate([chromosome1[:index1],chromosome2[index1:index2],chromosome1[index2:]]))
child2_chromosome.append(np.concatenate([chromosome2[:index1],chromosome1[index1:index2],chromosome2[index2:]]))
child1.chromosome = child1_chromosome
child2.chromosome = child2_chromosome
#print("child1", child1_chromosome)
return(child1, child2)
def crossOverRows(creature1, creature2):
child = MyCreature(11, 9)
child_chromosome = np.empty([11,9])
i = 0
while i < 11:
if i != 10:
child_chromosome[i] = creature1.chromosome[i]
child_chromosome[i+1] = creature2.chromosome[i+1]
else:
child_chromosome[i] = creature1.chromosome[i]
i += 2
child.chromosome = child_chromosome
return child
# print("parent1", creature1.chromosome[:3])
# print("parent2", creature2.chromosome[:3])
# print("crossover rows ", child_chromosome[:3])
def newPopulation(old_population):
global numTurns
nSurvivors = 0
avgLifeTime = 0
fitnessScore = 0
fitnessScores = []
# For each individual you can extract the following information left over
# from the evaluation. This will allow you to figure out how well an individual did in the
# simulation of the world: whether the creature is dead or not, how much
# energy did the creature have a the end of simulation (0 if dead), the tick number
# indicating the time of creature's death (if dead). You should use this information to build
# a fitness function that scores how the individual did in the simulation.
for individual in old_population:
# You can read the creature's energy at the end of the simulation - it will be 0 if creature is dead.
energy = individual.getEnergy()
# This method tells you if the creature died during the simulation
dead = individual.isDead()
# If the creature is dead, you can get its time of death (in units of turns)
if dead:
timeOfDeath = individual.timeOfDeath()
avgLifeTime += timeOfDeath
else:
nSurvivors += 1
avgLifeTime += numTurns
if individual.isDead() == False:
timeOfDeath = numTurns
individual.fitness = energy + (timeOfDeath * 100)
fitnessScores.append(individual.fitness)
fitnessScore += individual.fitness
#print("fitnessscore", individual.fitness, "energy", energy, "time of death", timeOfDeath, "is dead", individual.isDead())
fitnessScore = fitnessScore / len(old_population)
eliteCreatures = selection(old_population, fitnessScore)
print(len(eliteCreatures))
newSet = []
for i in range(int(len(eliteCreatures)/2)):
if eliteCreatures[i].isDead() == False:
newSet.append(eliteCreatures[i])
print(len(newSet), " elites added to pop")
remainingRequired = w.maxNumCreatures() - len(newSet)
i = 1
while i in range(int(remainingRequired)):
newSet.append(crossOver(eliteCreatures[i], eliteCreatures[i-1])[0])
if i >= (len(eliteCreatures)-2):
i = 1
i += 1
remainingRequired = w.maxNumCreatures() - len(newSet)
# Here are some statistics, which you may or may not find useful
avgLifeTime = float(avgLifeTime)/float(len(population))
print("Simulation stats:")
print(" Survivors : %d out of %d" % (nSurvivors, len(population)))
print(" Average Fitness Score :", fitnessScore)
print(" Avg life time: %.1f turns" % avgLifeTime)
# The information gathered above should allow you to build a fitness function that evaluates fitness of
# every creature. You should show the average fitness, but also use the fitness for selecting parents and
# spawning then new creatures.
# Based on the fitness you should select individuals for reproduction and create a
# new population. At the moment this is not done, and the same population with the same number
# of individuals is returned for the next generation.
new_population = newSet
return new_population
# Pygame window sometime doesn't spawn unless Matplotlib figure is not created, so best to keep the following two
# calls here. You might also want to use matplotlib for plotting average fitness over generations.
plt.close('all')
fh=plt.figure()
# Create the world. The worldType specifies the type of world to use (there are two types to chose from);
# gridSize specifies the size of the world, repeatable parameter allows you to run the simulation in exactly same way.
w = World(worldType=worldType, gridSize=gridSize, repeatable=repeatableMode)
#Get the number of creatures in the world
numCreatures = w.maxNumCreatures()
#Get the number of creature percepts
numCreaturePercepts = w.numCreaturePercepts()
#Get the number of creature actions
numCreatureActions = w.numCreatureActions()
# Create a list of initial creatures - instantiations of the MyCreature class that you implemented
population = list()
for i in range(numCreatures):
c = MyCreature(numCreaturePercepts, numCreatureActions)
population.append(c)
# Pass the first population to the world simulator
w.setNextGeneration(population)
# Runs the simulation to evaluate the first population
w.evaluate(numTurns)
# Show the visualisation of the initial creature behaviour (you can change the speed of the animation to 'slow',
# 'normal' or 'fast')
w.show_simulation(titleStr='Initial population', speed='normal')
for i in range(numGenerations):
print("\nGeneration %d:" % (i+1))
# Create a new population from the old one
population = newPopulation(population)
# Pass the new population to the world simulator
w.setNextGeneration(population)
# Run the simulation again to evaluate the next population
w.evaluate(numTurns)
# Show the visualisation of the final generation (you can change the speed of the animation to 'slow', 'normal' or
# 'fast')
if i==numGenerations-1:
w.show_simulation(titleStr='Final population', speed='normal')

Reproduce past simulation using random.seed(seed) but having issues as values turn out to differ

I'm trying to reproduce a simulation that I ran previously, such that I record down the seed of current date time inside a text file, and then use the recorded date time seed to get the same values that I got previously
However, I'm not sure why the values that come out isn't similar to the ones I ran in the previous simulation.
This is what I got when I tried to run the program:
=================== RESTART: /Users/ivanteong/Desktop/e.py ===================
Choose 1 to run simulation based on random seed of current time, or choose 2 to reproduce past simulation: 1
2017-05-20 18:55:51
0.902032491409618
0.33535058732344564
>>>
=================== RESTART: /Users/ivanteong/Desktop/e.py ===================
Choose 1 to run simulation based on random seed of current time, or choose 2 to reproduce past simulation: 2
Enter the seed of current time recorded: 2017-05-20-18-55-51
2017-05-20 18:55:51
0.759062526352241
0.058976331409061576
>>>
The code is below.
import math
import random
from datetime import datetime
# reproducibility
reproduce = int(input("Choose 1 to run simulation based on random seed of current time, or choose 2 to reproduce past simulation: "))
if reproduce == 1:
# seeding random based on current time and writing into text file for reproducibility
string_seed = datetime.strftime(datetime.now(), '%Y-%m-%d-%H-%M-%S')
f = open('seed.txt', 'a')
f.write(str(string_seed))
f.write('\n')
f.close()
seed = datetime.strptime(string_seed, '%Y-%m-%d-%H-%M-%S')
print(seed)
elif reproduce == 2:
stored_seed = str(input("Enter the seed of current time recorded: "))
seed = datetime.strptime(stored_seed, '%Y-%m-%d-%H-%M-%S')
print(seed)
def randExponential(rateLambda):
random.seed(seed)
print(random.random())
return -math.log(1.0 - random.random()) / rateLambda
print(randExponential(5))
When I tried to test this in the console with just numbers, it seems okay so not sure why I'm having trouble when using the datetime library.
>>> random.seed(3)
>>> random.random()
0.23796462709189137
>>> random.seed(3)
>>> random.random()
0.23796462709189137
>>>
Your variable seed isn't global, so when you use random.seed(seed) in your randExponential function, it gets passed a seed variable which hasn't been initialized yet, so it just passes None , which is the default and uses the current time instead. Just call random.seed(seed) before you call randExponential and get rid of the call in the function and it should work, or you can pass seed into the function
Edit:
For some reason I haven't been able to find out, the datetime.strptime() function seems to change the string slightly every time it is called, creating a different random generation, whereas removing those makes it work
Here is my code:
import math
import random
from datetime import datetime
reproduce = int(input("Choose 1 to run simulation based on random seed of current time, or choose 2 to reproduce past simulation: "))
if reproduce == 1:
seed = datetime.strftime(datetime.now(), '%Y-%m-%d-%H-%M-%S')
print(seed)
f = open('seed.txt', 'a')
f.write(str(seed))
f.write('\n')
f.close()
elif reproduce == 2:
seed = str(input("Enter the seed of current time recorded :"))
print(seed)
def randExponential(rateLambda, seed):
random.seed(seed)
print(random.random())
return -math.log(1.0 - random.random()) / rateLambda

Categories

Resources