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)
Related
I stumbled across an interesting probability problem about half an hour ago. https://en.wikipedia.org/wiki/100_prisoners_problem
Essentially, there are 100 boxes, drawers, etc, each with a unique number between 1-100 inside of them. There are also 100 prisoners. Each prisoner has 50 chances to find the box with their number. If even one does not, they all fail. The chances would be abysmally low if they all randomly picked 50 boxes, but there's a better strategy.
Each prisoner first opens the box labeled with their own number.
If this box contains their number, they are done and were successful.
Otherwise, the box contains the number of another prisoner, and they next open the drawer labeled with this number.
The prisoner repeats steps 2 and 3 until they find their own number, or fail because the number is not found in the first fifty opened drawers.
This should increase their chances to above 30 percent with the way everything can fall into a loop
I glanced through this and decided it was interesting enough to quickly code out in python, but I'm getting a really interesting (and probably wrong) result. Could someone take a look at the code?
import random
def begin(p=False): #print
prisoners = [i for i in range(100)]
boxes = prisoners.copy()
random.shuffle(boxes) #we now have a list of shuffled boxes. index represents box num
if p: #prints
for i,num in enumerate(boxes): #i=index, num=content of box. Just to print it out
print(i,num)
def run(p=True): #print
results ={"Success":False, "NumSucceed":0, "NumFail":0 }
for prisoner in prisoners: #Try every prisoner
fail = True #check if they fail
choice = boxes[prisoner] #initialize choice as box with prisoner num
for i in range(49): #49 becaues first choice counts as well
if choice==prisoner:
fail = False
break
choice = boxes[choice]
if fail:
results["NumFail"] +=1
else:
results["NumSucceed"]+=1
if results["NumSucceed"]==100:
results["Success"] = True
if p: #just if I choose not to print results
print(results)
return results
for i in range(100):
begin()
run()
How many ever times I run it I always get a failing result where 17 prisoners succeeded and the rest failed (I randomize the rotation of the boxes each time too). Does anyone know why? I hope I didn't just make some stupid error somewhere and waste your time lol, if you do look through this I'd appreciate it
Couple of notes first.
Make sure you keep locality/scope in mind with variables. You have a begin() function thats used to declare your variables for the entire script, but they aren't declared globally so when the other method runs, it won't be able to find the variables to declare in begin()
not sure how you got it to run as is tbh
so let's scrap the method and just initialize our prisoners and boxes
import random
prisoners = [i for i in range(100)]
boxes = [i for i in range(100)]
now you can put the shuffle in your run method, since only boxes need to be randomized and conceptually, randomizing boxes would be the first thing done each time the prisoner dilemma happens.
def run(p=True): #print
random.shuffle(boxes)
results ={"Success":False, "NumSucceed":0, "NumFail":0 }
# ...
I ran a couple times and got 20-40 out of 100 total runs where all prisoners found their tag
nice little riddle there.
I tried to execute your code, but ran into an NameError exception due to a name space problem. Basically both prisoners and boxes within your code are only defined while begin() is running.
I've used your solution and modified it a bit:
import random
from operator import countOf
PRISONERS = 100
class PrisonerProblemSolver:
def __init__(self) -> None:
# Generate prisoners and boxes
self.prisoners = list(range(PRISONERS))
self.boxes = self.prisoners.copy()
random.shuffle(self.boxes)
# collector for results
self.results = {"Success": False, "NumSucceed": 0, "NumFail": 0}
def solve(self):
for prisoner in self.prisoners:
fail = True
choice = self.boxes[prisoner] # tries own box first
for _ in range(49): # remaining attempts
if choice == prisoner:
fail = False # will not die
break
choice = self.boxes[choice] # follows and hopes
if fail:
self.results["NumFail"] += 1
else:
self.results["NumSucceed"] += 1
return self.results["NumSucceed"] == PRISONERS
if __name__ == '__main__':
solver = PrisonerProblemSolver()
results = []
# Let's look at 100 prisons
for _ in range(100):
solver = PrisonerProblemSolver()
results.append(solver.solve())
# how successful were they in dying?
print(countOf(results, True))
Hope this helps.
Best regards
Given a midi file, how can one convert the bar count to time?
Generally, how can one easily map the bar count, in entire numbers, to the time in seconds in the song
Using pretty midi, my solution
import pretty_midi as pm
def get_bar_to_time_dict(self,song,id):
def get_numerator_for_sig_change(signature_change,id):
# since sometime pretty midi count are wierd
if int(signature_change.numerator)==6 and int(signature_change.denominator)==8:
# 6/8 goes to 2 for sure
return 2
return signature_change.numerator
# we have to take into account time-signature-changes
changes = song.time_signature_changes
beats = song.get_beats()
bar_to_time_dict = dict()
# first bar is on first position
current_beat_index = 0
current_bar = 1
bar_to_time_dict[current_bar] = beats[current_beat_index]
for index_time_sig, _ in enumerate(changes):
numerator = get_numerator_for_sig_change(changes[index_time_sig],id)
# keep adding to dictionary until the time signature changes, or we are in the last change, in that case iterate till end of beats
while index_time_sig == len(changes) - 1 or beats[current_beat_index] < changes[index_time_sig + 1].time:
# we have to increase in numerator steps, minus 1 for counting logic of natural counting
current_beat_index += numerator
if current_beat_index > len(beats) - 1:
# we labeled all beats so end function
return bar_to_time_dict
current_bar += 1
bar_to_time_dict[current_bar] = beats[current_beat_index]
return bar_to_time_dict
song = pm.PrettyMIDI('some_midi_file.midi')
get_bar_to_time_dict(song)
If anyone knows a function in pretty midi or music21 that solves the same issue please let me know, couldn't find one.
EDIT: There was also an issue with 6/8 beats, I think this covers all edge cases(not 100% sure)
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
Goal: I would like to see how many times python is able to print something per 1 second.
For educational purposes I'm trying to make a script that shows how many times per every second a random module will appear in a loop. How to do it in a fastest pythonic way?
At first, to count seconds I wrote this code:
import time
sec = 0
while True:
print(sec)
time.sleep(1)
sec += 1
But this one seems slower than a real seconds.
So I decided to use local seconds. Also, before continue my script I wanted to count how many times python will print 'you fool' manually, so I wrote following code:
import time
def LocalSeconds():
local_seconds = time.gmtime()[5:-3]
local_seconds = int(local_seconds[0])
return local_seconds
while True:
print(LocalSeconds(), 'you fool')
Output:
first second - 14 times per second;
next second - 13 times;
next second - 12 times, etc. Why it goes slower?
Where I end / stuck right now:
import time, random
def RandomNumbers():
return random.randint(3,100)
def LocalSeconds():
local_seconds = time.gmtime()[5:-3]
local_seconds = int(local_seconds[0])
return local_seconds
def LocalSecondsWithPing():
local_seconds_ping = time.gmtime()[5:-3]
local_seconds_ping = int(local_seconds[0:1])
return local_seconds_ping
record_seconds = []
record_seconds_with_ping = []
while True:
record_seconds.append(LocalSeconds())
record_seconds_with_ping.append(LocalSecondsWithPing())
if record_seconds == record_seconds_with_ping:
RandomNumbers()
del record_seconds_with_ping[0]
del record_seconds[-1]
Also, I guess I need to use "for" loop, not "while"? How to do this script?
Counting a single second won't give you a good result. The number of prints in a single second may vary depending on things like other threads currently running on your system (for the OS or other programs) and may be influenced by other unknown factor.
Consider the followind code:
import calendar
import time
NumOfSeconds=100 #Number of seconds we average over
msg='Display this message' #Message to be displayed
count=0 #Number of time message will end up being displayed
#Time since the epoch in seconds + time of seconds in which we count
EndTime=calendar.timegm(time.gmtime()) + NumOfSeconds
while calendar.timegm(time.gmtime())<EndTime: #While we are not at the end point yet
print(msg) #Print message
count=count+1 #Count message printed
print(float(count)/NumOfSeconds) #Average number of prints per second
Here calendar.timegm(time.gmtime()) gives us the time in seconds since the epoch (if you don't know what that is, read this. But basically it's just a fixed point in time most computer system now days use as a reference point.
So we set the EndTime to that point + the number of seconds we want to average over. Then, in a loop, we print the message we want to test and count the number of times we do that, between every iteration checking that we are not past the end time.
Finally we print the average number of times per seconds that we printed the message. This helps with the fact that we may end up start counting near the end of a whole second since the epoch, in which case we won't actually have a whole second to print messages, but just a fraction of that. If we make sure NumOfSeconds is large enough, that error addition will be small (for example, for NumOfSeconds=100 that error is ~1%).
We should note that the actual number would also depend on the fact that we are constantly testing the current time and counting the number of prints, however, while I haven't tested that here, it is usually the case that printing to the screen takes significantly longer time than those operations.
I want to repeat a coin flip 500 times, and repeat that experiment 30 times and print the total amount of tails (1) per total run. Just running heads/tails is easy enough, but when I mess around to try to repeat this (first while loop) i get the exact same amount of tails each run, which shouldn't be possible.
While I'm a complete newbie, I can't figure out where I did something wrong here ... thanks!
import random
i=0
count_1=0
rand_count=0
while rand_count<31:
while i < 501:
y=random.randint(0,1)
if y ==1:
count_1=count_1+1
i=i+1
rand_count=rand_count+1
print(count_1)
You're only resetting count_1 and i once, outside both loops. They need to be reset inside the outer loop. It would help to use variable names and looping constructs that make the code easier to read:
import random
for trials in range(30):
count_1 = 0
for samples in range(500):
if 1 == random.randint(0, 1):
count_1 += 1
print(count_1)