What is the def paradox_stats() function in my code? - python

I am trying to learn how to write a function that could test the probability of same birthday of two people in a room.
The birthday paradox says that the probability that two people in a room will have the same birthday is more than half, provided n, the number of people in the room, is more than 23. This property is not really a paradox, but many people find it surprising. Design a Python program that can test this paradox by a series of experiments on randomly generated birthdays, which test this paradox for n = 5,10,15,20,... ,100.
Here is the code that showed in my book.
import random
def test_birthday_paradox(num_people):
birthdays = [random.randrange(0,365) for _ in range(num_people)]
birthday_set = set()
for bday in birthdays:
if bday in birthday_set: return True
else: birthday_set.add(bday)
return False
def paradox_stats(num_people = 23, num_trials = 100):
num_successes = 0
for _ in range(num_trials):
if test_birthday_paradox(num_people): num_successes += 1
return num_successes/num_trials
paradox_stats(31)
0.77
I can't understand the code from def paradox_stats to the end of code.
Can someone help me , please?

Guessing that paradox_state(31) is a mistake and you want to write paradox_stats(31):
def paradox_stats(num_people = 23, num_trials = 100): is the definition of the function where two variables could be inserted (these variables are optional).
num_successes = 0 the code are initializing the variable num_successes to zero.
for _ in range(num_trials):
if test_birthday_paradox(num_people): num_successes += 1
return num_successes/num_trials
Here the code is running throw a range from 0 to the number of trials which the user could define once is calling the function (remember it is an optional variable).
In this loop the code is using the previous function test_birthday_paradox (which I suppose you understand as far as you say in your question) to know if someone in the room has the same birthday. In the case that the function returns True (someone has the same birthday) the variable num_successes increase its value in one (this is how works += syntax, but if you need further explanation num_successes+=1 == num_successes = num_successes+1).
And once the loop is completed the function paradox_stats return the probability in the random sample as the number of successes vs number of trials.
Hope my answer can help you.

Related

How to optimize my code for the Kattis Accounting Question?

I am doing this Kattis accounting question but at test case 10, it has the error Time limit exceeded.
How can I optimize my code to make it run faster?
Here's the question!
Erika the economist studies economic inequality. Her model starts in a
situation where everybody has the same amount of money. After that,
people’s wealth changes in various complicated ways.
Erika needs to run a simulation a large number of times to check if
her model works. The simulation consists of people, each of whom
begins with kroners. Then events happen, of three different types:
An event of type “SET ” means that the th person’s wealth is set to .
An event of type “RESTART ” means that the simulation is restarted,
and everybody’s wealth is set to .
An event of type “PRINT ” reports the current wealth of the th person.
Unfortunately, Erika’s current implementation is very slow; it takes
far too much time to keep track of how much money everybody has. She
decides to use her algorithmic insights to speed up the simulation.
Input The first line includes two integers and , where and . The
following lines each start with a string that is either “SET”,
“RESTART”, or “PRINT”. There is guaranteed to be at least one event of
type “PRINT”.
If the string is “SET” then it is followed by two integers and with
and . If the string is “RESTART” then it is followed by an integer
with . If the string is “PRINT” then it is followed by an integer
with .
Output For each event of type “PRINT”, write the th person’s capital.
Sample Input 1: 3 5 SET 1 7 PRINT 1 PRINT 2
RESTART 33 PRINT 1
Sample Output 1: 7 0 33
Sample Input 2: 5 7 RESTART 5 SET 3 7 PRINT 1
PRINT 2 PRINT 3 PRINT 4 PRINT 5
Sample Output 2: 5 5 7 5 5
# print("Enter 2 numbers")
n, q = map(int, input().split())
# print(n , q)
people = {}
def createPeople(n):
for i in range(n):
number = i+1
people[number] = 0
return people
def restart(n,new):
for i in range(n):
number = i+1
people[number] = new
return people
def setPeople(d ,id , number):
d[id] = number
return d
# return d.update({id: number})
def logic(n,dict,q):
for i in range(q):
# print("enter Command")
r = input()
r = r.split()
# print("r" ,r)
if r[0] == "SET":
# print(people , "People list")
abc = setPeople(dict, int(r[1]), int(r[2]))
# print(list)
elif r[0] == "RESTART":
abc = restart(n, int(r[1]))
elif r[0] == "PRINT":
print(dict[int(r[1])])
# return abc
people = createPeople(n)
# print(people)
test = logic(n,people,q)
The input is too big to be doing anything linear, like looping over all of the people and setting their values by hand. If we have 105 queries and 106 people, the worst case scenario is resetting over and over again, 1011 operations.
Easier is to keep a variable to track the baseline value after resets. Whenever a reset occurs, dump all entries in the dictionary and set the baseline to the specified value. Assume any further lookups for people that aren't in the dictionary to have the most recent baseline value. Now, all operations are O(1) and we can handle 105 queries linearly.
people = {}
baseline = 0
n, q = map(int, input().split())
for _ in range(q):
command, *args = input().split()
if command == "SET":
people[int(args[0])] = int(args[1])
elif command == "RESTART":
people.clear()
baseline = int(args[0])
elif command == "PRINT":
print(people.get(int(args[0]), baseline))
As an aside, writing abstractions is great in a real program, but for these tiny code challenges I'd just focus on directly solving the problem. This reduces the potential for confusion with return values like abc that seem to have no clear purpose.
Per PEP-8, use snake_case rather than camelCase in Python.

How to create and call on a Python Class to calculate Kelly Criterion formula for sports betting?

I am trying to create a Python Class to calculate the Kelly Criterion formula in order to determine the precise bet size for an individual sport's investment. I am not very good with using the Class function or init function and could use some help.
The Class I am trying to create uses three functions:
Function 1 asks the user to input the estimated win percentage of the bet (saved to variable 'winP').
Function 2 asks the user to input the American odds for this particular bet. I then convert the American odds to Decimal odds to use with the Kelly Criterion formula (saved to variable 'odds').
Function 3 takes 'winP' and 'odds' and implements this data into the Kelly Criterion formula.
The Kelly Criterion formula that I am using is:
Kelly Criterion (kCrit) = ((odds - 1) * (1 - winP)) / (odds - 1)
'odds' is the Decimal form of the American odds after conversion. 'winP' in the expected winning probability of this particular bet.
I was able to get the 1st and 2nd function to work perfectly (win_percentage, convert_to_decimal), however I was unable to get the 3rd function to work (implement_kc)
Here is my code below:
class KellyCriterion:
def win_percentage(percent):
winP = int(input('What is your win percentage?: '))
return winP
def convert_to_decimal(odds):
odds = int(input('What are the American odds?: '))
if odds > 0:
odds = (odds/100) + 1
return odds
elif odds < 0:
odds = -(100/odds) + 1
return odds
def implement_kc(winP, odds):
kCrit = ((odds - 1) * (1-winP)) / (odds-1)
return kCrit
winPercent = KellyCriterion()
winPercent.win_percentage()
betSize = KellyCriterion()
betSize.convert_to_decimals()
I was not sure how to call on the 3rd function properly:
kelly = KellyCriterion()
kelly.implement_kc()
I received an error: NameError: name 'winP' is not defined.
I am a beginner with using Class functions and could use some help. I also tried using an init(self) function but not exactly sure how those work.
Any suggestions would be greatly appreciated. Thanks in advance for any help that you may offer.
Just to clarify the 1st function (win_percentage) and 2nd function (convert_to_decimal) work just fine. I am having issues with the 3rd function (implement_kc).
I would like to find a way to call on the KellyCriterion Class to: 1) ask the user what is their win percentage; 2) ask the user what are the American odds; 3) implement both of their responses into the Kelly Criterion formula to find out the appropriate bet size.
Thanks again!
If you want to write a class, you need to pass self to the functions. Moreover, the way you have winPercent = KellyCriterion() and betSize = KellyCriterion() means you have two separate instances of the KellyCriterion class, which don't communicate with one another. What you want, is a single instance so you can assign both winP and odds to that instance, otherwise any call to the implement_kc() method is going to be missing values and return an error.
As an aside, here's a post that shows a class-based implementation of the Kelly Criterion and some more background on how it's done. Could be helpful for reference.
Anyway, here's some code that will work, at least if I understand what you're trying to accomplish:
class KellyCriterion:
def win_percentage(self):
winP = int(input('What is your win percentage?: '))
self.winP = winP / 100
def convert_to_decimal(self):
odds = int(input('What are the American odds?: '))
if odds > 0:
self.odds = (odds/100) + 1
elif odds < 0:
self.odds = -(100/odds) + 1
def implement_kc(self):
kCrit = ((self.odds - 1) * (1-self.winP)) / (self.odds-1)
return kCrit
If we run it:
KC = KellyCriterion()
KC.win_percentage()
KC.convert_to_decimal()
print(f"Wager: {KC.implement_kc():.2f}%")
If we enter, say 51 and -110 when prompted for input, then we get:
Wager: 0.49%
Now each of the input functions you defined assign an attribute to the class (e.g. self.winP and self.odds) that the implement_kc() method will use later when you call it.

Using returned outputs from one function in another in Python

new to Python - struggling with functions. - Image of code attached.
It inputs the name & scores just fine with the validation checks.
I need to use the scores input by the user and total them.
However, when I've tried to sum(score) it doesn't like it.
I can't work out how to sum the 4 total scores.
Please help :) Also would love any feedback on the style of coding etc.
Thanks in advance x
Image: Code in Python
I would rewrite the main function to be something like:
def GetStudentInput():
score = 0
for i in range (4):
print("Mrs Pearson's Class Test Score Data")
name = CheckStringInput("What's Your Name: ")
score += CheckNumericInput("What's Your Score: ")
print(score)
This eliminates the need for an extra function and avoids using a list since you don't appear to need the individual values elsewhere -- only the sum total.
In the absense of code for people to see, we have something like
def get_stuff():
for i in rnage(4):
name = input("Name?")
score = int(input("Score?"))
and another function
def TotalScore():
pass
How do we call total score?
Answer: Make sure we don't forget the user inputs and return them:
def get_stuff():
names = []
scores = []
for i in range(4):
names.append(input("Name?"))
scores.append(int(input("Score?")))
return names, scores
and take the scores in the summing function:
def TotalScore(scores):
return sum(scores)
This, of course, changes the calling code.
For example, you need to capture the returns when you call get_stuff:
names, scores = get_stuff()
total = TotalScores(scores)

How do I keep track of score increments in Python?

I am writing a simple game program in Python where a user is prompted to select from "healthy" and "unhealthy" items in a grocery store. Each time the user selects a healthy item their "Health Score (initially 100) goes up. Each time they select from the unhealthy items their score goes down.
My code adds and subtracts from the initial Health Score of 100, but doesn't keep track of the most updated score after each selection. I want to give the user their new total after each transaction (new_hscore) and their grand total at the end (final_score), but I'm not sure how to do that.
Is it done with lists? Do I use .append? Any help would be greatly appreciated! Thanks in advance!
Here is my code: http://pastebin.com/TvyURsMb
You can see right away what I'm trying to do when you scroll down to the "def inner():" function.
EDIT: I got it working! Thank you all who contributed. I learned a lot. My final 'score-keeping' working code is here: http://pastebin.com/BVVJAnKa
You can do something simple like this:
hp_history = [10]
def initial_health():
return hp_history[0]
def cur_health():
return hp_history[-1]
def affect_health(delta):
hp_history.append(cur_health() + delta)
return cur_health()
Demonstration:
>>> cur_health()
10
>>> affect_health(20)
30
>>> affect_health(-5)
25
>>> affect_health(17)
42
>>> cur_health()
42
>>> print hp_history
[10, 30, 25, 42]
You can't store module level variables like that. Any attempt to write to that variable will create a local variable. Examine the behavior of this script:
s = 0
def f():
s = 10
print s
f()
print s
Output:
10
0
Instead you should be moving towards an object-oriented approach. Start placing your code in a class:
class HeathlyGame():
def __init__(self):
self.init_hscore = 100
self.final_score = 0
# Beginning. Proceed or quit game.
def start(self):
print "Your shopping habits will either help you live longer or they will help you die sooner. No kidding! Wanna find out which one of the two in your case?", yn
find_out = raw_input(select).upper()
...
game = HeathlyGame()
game.start()
This will allow you to create multiple versions of the game in memory at once, and each can store their own copy of the score.
For more on classes, try this link: http://en.wikibooks.org/wiki/A_Beginner%27s_Python_Tutorial/Classes
The problem seems to be you are always starting at init_hp, forgetting your cur_hp doing
init_hp = 10
while True:
food = choose_food()
if "cereal" in food:
cur_hp = init_hp - 5
# ..
But you need:
init_hp = 10
cur_hp = init_hp
while True:
food = choose_food()
if "cereal" in food:
cur_hp -= 5
# ..
You can use a generator!
A generator is basically a function that keeps track of the state of its objects even after you leave the function and call it again. Instead of using 'return' and the end, you use 'yield'. Try something like this:
def HealthScore(add):
score = 100
while 1:
score += add
yield score
if you call HealthScore(-5), it will return 95. If you then call HealthScore(5), it will return 100.

How to speed up Python string matching code

I have this code which computes the Longest Common Subsequence between random strings to see how accurately one can reconstruct an unknown region of the input. To get good statistics I need to iterate it many times but my current python implementation is far too slow. Even using pypy it currently takes 21 seconds to run once and I would ideally like to run it 100s of times.
#!/usr/bin/python
import random
import itertools
#test to see how many different unknowns are compatible with a set of LCS answers.
def lcs(x, y):
n = len(x)
m = len(y)
# table is the dynamic programming table
table = [list(itertools.repeat(0, n+1)) for _ in xrange(m+1)]
for i in range(n+1): # i=0,1,...,n
for j in range(m+1): # j=0,1,...,m
if i == 0 or j == 0:
table[i][j] = 0
elif x[i-1] == y[j-1]:
table[i][j] = table[i-1][j-1] + 1
else:
table[i][j] = max(table[i-1][j], table[i][j-1])
# Now, table[n, m] is the length of LCS of x and y.
return table[n][m]
def lcses(pattern, text):
return [lcs(pattern, text[i:i+2*l]) for i in xrange(0,l)]
l = 15
#Create the pattern
pattern = [random.choice('01') for i in xrange(2*l)]
#create text start and end and unknown.
start = [random.choice('01') for i in xrange(l)]
end = [random.choice('01') for i in xrange(l)]
unknown = [random.choice('01') for i in xrange(l)]
lcslist= lcses(pattern, start+unknown+end)
count = 0
for test in itertools.product('01',repeat = l):
test=list(test)
testlist = lcses(pattern, start+test+end)
if (testlist == lcslist):
count += 1
print count
I tried converting it to numpy but I must have done it badly as it actually ran more slowly. Can this code be sped up a lot somehow?
Update. Following a comment below, it would be better if lcses used a recurrence directly which gave the LCS between pattern and all sublists of text of the same length. Is it possible to modify the classic dynamic programming LCS algorithm somehow to do this?
The recurrence table table is being recomputed 15 times on every call to lcses() when it is only dependent upon m and n where m has a maximum value of 2*l and n is at most 3*l.
If your program only computed table once, it would be dynamic programming which it is not currently. A Python idiom for this would be
table = None
def use_lcs_table(m, n, l):
global table
if table is None:
table = lcs(2*l, 3*l)
return table[m][n]
Except using an class instance would be cleaner and more extensible than a global table declaration. But this gives you an idea of why its taking so much time.
Added in reply to comment:
Dynamic Programming is an optimization that requires a trade-off of extra space for less time. In your example you appear to be doing a table pre-computation in lcs() but you build the whole list on every single call and then throw it away. I don't claim to understand the algorithm you are trying to implement, but the way you have it coded, it either:
Has no recurrence relation, thus no grounds for DP optimization, or
Has a recurrence relation, the implementation of which you bungled.

Categories