US Open Championship Python Script

FRV2

Semi-Pro
Python:
# chance nadal beats field
oddsNadalBeatsField = .9

# chance that djoker beats field
oddsDjokerBeatsField = .8

# chance that fed beats field
oddsFedBeatsField = .65




# chance that fed is in djoker's half
oddsFedInDjokersHalf = .5

# chance that fed is in nadal's half
oddsFedInNadalsHalf = .5




# chance that fed beats djokovic in meeting
oddsFedBeatsDjoker = .25

# chance that fed beats nadal in meeting
oddsFedBeatsNadal = .5

# chance that djokovic beats nadal in meeting
oddsDjokerBeatsNadal = .7


# chance nadal beats non-big3 finals opponent
oddsNadalBeatsNB3 = .9

# chance djokovic beats non-big3 finals opponent
oddsDjokerBeatsNB3 = .7

# chance fed beats non-big3 finals opponent
oddsFedBeatsNB3 = .55



o_FedBeatsFieldInDjokersHalf = oddsFedBeatsField * oddsFedInDjokersHalf
o_FedBeatsFieldInNadalsHalf = oddsFedBeatsField * oddsFedInNadalsHalf






def fedGoesThroughDjoker():
    return o_FedBeatsFieldInDjokersHalf * oddsDjokerBeatsField * oddsFedBeatsDjoker

def fedGoesThroughDjokerThenNadal():
    return fedGoesThroughDjoker() * (oddsFedBeatsNadal * oddsNadalBeatsField)

def fedGoesThroughNadal():
    return o_FedBeatsFieldInNadalsHalf * oddsNadalBeatsField * oddsFedBeatsNadal

def fedGoesThroughNadalThenDjoker():
    return fedGoesThroughNadal() * (oddsFedBeatsDjoker * oddsDjokerBeatsField)

def fedFacesNeither():
    return oddsFedBeatsField * (1 - oddsDjokerBeatsField) * (1 - oddsNadalBeatsField)

def fedNoDjoker():
    return o_FedBeatsFieldInDjokersHalf * (1 - oddsDjokerBeatsField)

def fedNoDjokerBeatsNadal():
    return fedNoDjoker() * (oddsFedBeatsNadal * oddsNadalBeatsField)

def fedNoNadal():
    return o_FedBeatsFieldInNadalsHalf * (1 - oddsNadalBeatsField)

def fedNoNadalBeatsDjoker():
    return fedNoNadal() * (oddsFedBeatsDjoker * oddsDjokerBeatsField)

def fedThroughNadalNoDjoker():
    return fedGoesThroughNadal() * (1 - oddsDjokerBeatsField) * oddsFedBeatsNB3

def fedThroughDjokerNoNadal():
    return fedGoesThroughDjoker() * (1 - oddsNadalBeatsField) * oddsFedBeatsNB3




def djokerGoesThroughFedThenNadal():
    return oddsDjokerBeatsField * o_FedBeatsFieldInDjokersHalf * (1 - oddsFedBeatsDjoker)\
     * oddsNadalBeatsField * oddsDjokerBeatsNadal

def djokerBeatsNadal():
    return oddsDjokerBeatsField * oddsFedInNadalsHalf * (1 - oddsFedBeatsField) * \
    (oddsNadalBeatsField) * (oddsDjokerBeatsNadal) \
    + oddsDjokerBeatsField * o_FedBeatsFieldInNadalsHalf * oddsNadalBeatsField * \
    (1 - oddsFedBeatsNadal) * oddsDjokerBeatsNadal

def djokerBeatsFed():
    return oddsDjokerBeatsField * fedGoesThroughNadal() * (1-oddsFedBeatsDjoker) + \
    oddsDjokerBeatsField * fedNoNadal() * (1-oddsFedBeatsDjoker)

def djokerFacesNeither():
    return oddsDjokerBeatsField * (1 - oddsNadalBeatsField) * (1 - oddsFedBeatsField)

def djokerNoFedBeatsNadal():
    return oddsDjokerBeatsField * oddsFedInDjokersHalf * (1 - oddsFedBeatsField) * \
    oddsNadalBeatsField * oddsDjokerBeatsNadal

def djokerThroughFedNoNadal():
    return oddsDjokerBeatsField * oddsFedBeatsField * oddsFedInDjokersHalf * \
    (1 - oddsFedBeatsDjoker) * (1 - oddsNadalBeatsField) * oddsDjokerBeatsNB3




def nadalGoesThroughFedThenDjoker():
    return oddsNadalBeatsField * o_FedBeatsFieldInNadalsHalf * (1-oddsFedBeatsNadal) * \
    oddsDjokerBeatsField * (1-oddsDjokerBeatsNadal)

def nadalBeatsDjoker():

    return oddsNadalBeatsField * oddsFedInDjokersHalf * oddsDjokerBeatsField * \
    (1 - oddsDjokerBeatsNadal) * ((1 - oddsFedBeatsField) + (1 - oddsFedBeatsDjoker)*oddsFedBeatsField)

def nadalBeatsFed():
    return oddsNadalBeatsField * fedGoesThroughDjoker() * (1-oddsFedBeatsNadal) + \
    oddsNadalBeatsField * fedNoDjoker() * (1-oddsFedBeatsNadal)
def nadalFacesNeither():
    return oddsNadalBeatsField * (1 - oddsDjokerBeatsField) * (1 - oddsFedBeatsField)

def nadalNoFedBeatsDjoker():
    return oddsNadalBeatsField * oddsFedInNadalsHalf * (1 - oddsFedBeatsField) * \
    oddsDjokerBeatsField * (1 - oddsDjokerBeatsNadal)

def nadalThroughFedNoDjoker():
    return oddsNadalBeatsField * o_FedBeatsFieldInNadalsHalf * (1 - oddsFedBeatsNadal) * \
    (1 - oddsDjokerBeatsField) * oddsNadalBeatsNB3







fed = fedGoesThroughDjokerThenNadal() + fedGoesThroughNadalThenDjoker() + fedNoNadalBeatsDjoker() \
+ fedNoDjokerBeatsNadal() + fedFacesNeither() \
+ fedThroughNadalNoDjoker() + fedThroughDjokerNoNadal()

djoker = djokerGoesThroughFedThenNadal() + djokerBeatsFed() \
+ djokerBeatsNadal() + djokerFacesNeither() + djokerNoFedBeatsNadal() + djokerThroughFedNoNadal()

nadal = nadalGoesThroughFedThenDjoker() + nadalBeatsFed() + nadalBeatsDjoker() \
+ nadalFacesNeither() + nadalNoFedBeatsDjoker() + nadalThroughFedNoDjoker()

field = 1 - fed - djoker - nadal



print("Fed's Chances: " + str(round(fed,3) * 100) + "%")
print("Djoker's Chances: " + str(round(djoker,3) * 100) + "%")
print("Nadal's Chances: " + str(round(nadal,3) * 100) + "%")
print("Field's Chances: " + str(round(((1- fed - djoker - nadal) * 100), 3)) + "%")


"""
Federer chances = 12.7%
Djokovic chances = 53.0%
Nadal chances = 31.1%
Non-Big3 chances = 3.186%
"""
 
Last edited:

FRV2

Semi-Pro
Starting numbers are based on opinion, but you can manipulate them yourself with this script. I don't know if it was done correctly, but the numbers seem legit enough. Still going with Fed.
 

FRV2

Semi-Pro
This can be updated after the draw. Current chances based on these calculations:

Federer chances = 10.725%
Djokovic chances = 51.64%
Nadal chances = 28.49%
Non-Big3 chances = 9.15%
 

BetaServe

Professional
Pretty bad coding :p . You didn't need that many parameters for each function and this problem can be done in a much simpler way.
 

FRV2

Semi-Pro
Pretty bad coding :p . You didn't need that many parameters for each function and this problem can be done in a much simpler way.
Yeah I just started learning it. Well not really, but I started from square one a couple months ago.

I know I didn't need that many parameters though, I was writing spaghetti code, copying and pasting the parameters, so that I could get this done quickly.
 

BetaServe

Professional
Yeah I just started learning it. Well not really, but I started from square one a couple months ago.

I know I didn't need that many parameters though, I was writing spaghetti code, copying and pasting the parameters, so that I could get this done quickly.
You can get rid of all the parameters from all functions since you didn't need to use them. def fedBeatDjoker() is good enough. Also avoid naming variables a,b,c,d...Variable names should be readable and expressive, e.g oddsFedBeatDjoker instead of f
 

FRV2

Semi-Pro
You can get rid of all the parameters from all functions since you didn't need to use them. def fedBeatDjoker() is good enough. Also avoid naming variables a,b,c,d...Variable names should be readable and expressive, e.g oddsFedBeatDjoker instead of f
I wasn't writing this to be maintained though. I just wanted to whip up something quick that could do the calculations. What is the simpler way?
 

FRV2

Semi-Pro
Anyways, this is wrong. I will edit it. I didn't account for them facing a Big 3 in the semis, but a non-Big3 in the finals.
 

FRV2

Semi-Pro
Well, I edited it. Don't like how the numbers look now, but I guess it's just due to the fact that I chose wrong initial values.
 

FRV2

Semi-Pro
Especially beating the field. I am likely being too generous there because that is 5 opponents, with the likes of Thiem, Medvedev, Kyrgios, etc.
 

metsman

G.O.A.T.
I don't get why you'd write a script for this instead of just doing it by calculator. I guess there are a lot of cases to keep track of.

And try not to use that many global variables. Wrap the whole thing in a function and pass the probabilities to that function (maybe in a dictionary). It's good style.
 

metsman

G.O.A.T.
Also you could do this in ways without so many functions, you're basically repeating similar orders of calculations for different players so you could combine all that into 1 function for each pattern instead of having 1 for each of the three players.
 

FRV2

Semi-Pro
I don't get why you'd write a script for this instead of just doing it by calculator.
Just so you can play around with the numbers and get the percentages based on new guesses for the probabilities. If you look at the script, variables a => k are all opinions of the probabilities, so I wanted to write a script so others can plug in their own numbers and get percentages. I am interested to see what TripleATeam comes up with.
 

JadeC

Hall of Fame
I took a beginner course in Python about 2 years ago, didn't work out as I don't think coding is really for me. But I appreciate the effort and discussion here. Nice, OP. Let's see what @TripleATeam will come up with.
 

megamind

Professional
So u think nadal is more likely to win against non-big-3 than Djokovic

What’s your reasoning for this claim?
 

megamind

Professional
Also you could do this in ways without so many functions, you're basically repeating similar orders of calculations for different players so you could combine all that into 1 function for each pattern instead of having 1 for each of the three players.
 

TripleATeam

Legend
So I ended up writing the code in Java, but now that I have a decent algorithm I can make it into a proper python or golang script, depending on what people want to see. I tried to make it into a .JAR but my manifest.mf is killing me right now, and I'd rather not get 3 hours of sleep over an executable.

Anyway, my repo is up - check it out.


I just named it Tennis_Odds_Calc for lack of a better term. Send me a message saying what language I should use for my script (might even just make it into a .exe for ease of use), or I guess you can propose changes to the code too. It's not particularly clean (No input validation, for one thing), but it definitely works and accepts input from std.in.
 

FRV2

Semi-Pro
So I ended up writing the code in Java, but now that I have a decent algorithm I can make it into a proper python or golang script, depending on what people want to see. I tried to make it into a .JAR but my manifest.mf is killing me right now, and I'd rather not get 3 hours of sleep over an executable.

Anyway, my repo is up - check it out.


I just named it Tennis_Odds_Calc for lack of a better term. Send me a message saying what language I should use for my script (might even just make it into a .exe for ease of use), or I guess you can propose changes to the code too. It's not particularly clean (No input validation, for one thing), but it definitely works and accepts input from std.in.
Nice! I'd personally prefer that you turn it into a python script, but I'm okay with whatever you choose to do. Why did you name the class Player2 instead of just Player? Were you working on several prototypes?
 

TripleATeam

Legend
Nice! I'd personally prefer that you turn it into a python script, but I'm okay with whatever you choose to do. Why did you name the class Player2 instead of just Player? Were you working on several prototypes?
Yup. Player held a map of matchups, and I determined that wasn't going to work nearly as well.
 

tennis_pro

Bionic Poster
Dude do this for every Slam (or every big tournament if you have the time). Very interesting.

Actually it would be very cool if you could create a program so that everyone can check for themselves what are the odds according to their point of view (like f.e. someone thinks that Federer against the field is 80% instead of 75%).
 

FRV2

Semi-Pro
Dude do this for every Slam (or every big tournament if you have the time). Very interesting.

Actually it would be very cool if you could create a program so that everyone can check for themselves what are the odds according to their point of view (like f.e. someone thinks that Federer against the field is 80% instead of 75%).
That was kind of the idea with the original script. If you copy and paste it into a text editor and have python installed, you can play around with the numbers. I don't think my script is all that good. It is bound to have mistakes as I am a novice at this. TripleATeam is working on something better.
 

FRV2

Semi-Pro
Dude do this for every Slam (or every big tournament if you have the time). Very interesting.

Actually it would be very cool if you could create a program so that everyone can check for themselves what are the odds according to their point of view (like f.e. someone thinks that Federer against the field is 80% instead of 75%).
You can actually just copy and paste the code into here if you don't want to install python or use a text editor: https://trinket.io/python
 

ADuck

Hall of Fame
I thought this looked like fun so I gave it a try. I made a script which calculates odds for the top 4 seeds winning, but also depending on which half of the draw Federer is in.

Python:
#Calculate US OPEN odds for each of the top 4 seeds prior to the draw
print('Enter the probability (between 0 and 1) of the top 4 seeds making the semi-finals')
nadal_semis = float(input("Nadal: "))
djokovic_semis = float(input("Djokovic: "))
federer_semis = float(input("Federer: "))
thiem_semis = float(input("Thiem: "))

#Odds of top 4 seeds beating random opposition based on their probability to make it through to the semi-finals
nadal_def_mug = nadal_semis**(1/5)
djokovic_def_mug = djokovic_semis**(1/5)
federer_def_mug = federer_semis**(1/5)
thiem_def_mug = thiem_semis**(1/5)

#organizing data in lists
nadal = [nadal_semis, nadal_def_mug]
djokovic = [djokovic_semis, djokovic_def_mug]
federer = [federer_semis, federer_def_mug]
thiem = [thiem_semis, thiem_def_mug]

#Odds of top 4 seeds beating each other
print('Enter the probability (between 0 and 1) of the top 4 seeds beating each other in any given match')
federer_def_djokovic = float(input('Federer defeats Djokovic: '))
federer_def_nadal = float(input('Federer defeats Nadal: '))
federer_def_thiem = float(input('Federer defeats Thiem: '))

nadal_def_djokovic = float(input('Nadal defeats Djokovic: '))
nadal_def_thiem = float(input('Nadal defeats Thiem: '))
nadal_def_federer = 1-federer_def_nadal

thiem_def_djokovic = float(input('Thiem defeats Djokovic: '))
thiem_def_nadal = 1-nadal_def_thiem
thiem_def_federer = 1-federer_def_thiem

djokovic_def_nadal = 1-nadal_def_djokovic
djokovic_def_federer = 1-federer_def_djokovic
djokovic_def_thiem = 1-thiem_def_djokovic

#Functions here:
def reachfinal(p1,p2,p1_def_p2):
    """Gives odds of player1 reaching the final if they are on the same side of the draw as player2

    """
    
    return p2[0]*(p1[0]*p1_def_p2) + (1 - p2[0])*(p1[0]*p1[1])

def win(p1, p2, p1_def_p2, p3, p1_def_p3):
    """Gives odds of player1 winning the event if player2 and player3 are the possible opponents
    in the final
    """
    return p2[2]*(p1[2] * p1_def_p2) + p3[2]*(p1[2]*p1_def_p3) + (1-p2[2]-p3[2])*(p1[2]*p1[1])
    
#If Federer is in Djokovic's half
nadal_final = reachfinal(nadal,thiem,nadal_def_thiem)
thiem_final = reachfinal(thiem,nadal,thiem_def_nadal)
federer_final = reachfinal(federer,djokovic,federer_def_djokovic)
djokovic_final = reachfinal(djokovic,federer,djokovic_def_federer)

#updating data
nadal += nadal_final,
thiem += thiem_final,
federer += federer_final,
djokovic += djokovic_final,

nadal_champ1 = win(nadal, federer, nadal_def_federer, djokovic, nadal_def_djokovic)
federer_champ1 = win(federer, nadal, federer_def_nadal, thiem, federer_def_thiem)
djokovic_champ1 = win(djokovic, nadal, djokovic_def_nadal, thiem, djokovic_def_thiem)
thiem_champ1 = win(thiem, djokovic, thiem_def_djokovic, federer, thiem_def_federer)

nonbig3_champ = 1 - nadal_champ1 - federer_champ1 - djokovic_champ1

print("\nIf Federer is put in Djokovic's half...")
print("Federer wins US Open = ",round(federer_champ1*100,2),'%',sep='')
print("Nadal wins US Open = ",round(nadal_champ1*100,2),'%',sep='')
print("Djokovic wins US Open = ",round(djokovic_champ1*100,2),'%',sep='')
print("Thiem wins US Open = ",round(thiem_champ1*100,2),'%',sep='')
print("A non-Big-3 player wins US Open = ",round(nonbig3_champ*100,2),'%\n',sep='')

#If Federer is in Nadal's half
nadal_final =   reachfinal(nadal,federer,nadal_def_federer)
federer_final = reachfinal(federer,nadal,federer_def_nadal)
djokovic_final = reachfinal(djokovic,thiem,djokovic_def_thiem)
thiem_final = reachfinal(thiem,djokovic,thiem_def_djokovic)

#Updating data
nadal[2] = nadal_final
thiem[2] = thiem_final
federer[2] = federer_final
djokovic[2] = djokovic_final

nadal_champ2 = win(nadal, djokovic, nadal_def_djokovic, thiem, nadal_def_thiem)
federer_champ2 = win(federer, djokovic, federer_def_djokovic, thiem, federer_def_thiem)
djokovic_champ2 = win(djokovic, nadal, djokovic_def_nadal, federer, djokovic_def_federer)
thiem_champ2 = win(thiem, nadal, thiem_def_nadal, federer, thiem_def_federer)
nonbig3_champ = 1 - nadal_champ2 - federer_champ2 - djokovic_champ2

print("If Federer is put in Nadal's half...")
print("Federer wins US Open = ",round(federer_champ2*100,2),'%',sep='')
print("Nadal wins US Open = ",round(nadal_champ2*100,2),'%',sep='')
print("Djokovic wins US Open = ",round(djokovic_champ2*100,2),'%',sep='')
print("Thiem wins US Open = ",round(thiem_champ2*100,2),'%',sep='')
print("A non-Big-3 player wins US Open = ",round(nonbig3_champ*100,2),'%\n',sep='')

#If Federer's half is unknown
nadal_champ3 = 0.5*nadal_champ1 + 0.5*nadal_champ2
federer_champ3 = 0.5*federer_champ1 + 0.5*federer_champ2
djokovic_champ3 = 0.5*djokovic_champ1 + 0.5*djokovic_champ2
thiem_champ3 = 0.5*thiem_champ1 + 0.5*thiem_champ2
nonbig3_champ = 1 - nadal_champ3 - federer_champ3 - djokovic_champ3

print("Odds without knowing which side Federer is on...")
print("Federer wins US Open = ",round(federer_champ3*100,2),'%',sep='')
print("Nadal wins US Open = ",round(nadal_champ3*100,2),'%',sep='')
print("Djokovic wins US Open = ",round(djokovic_champ3*100,2),'%',sep='')
print("Thiem wins US Open = ",round(thiem_champ3*100,2),'%',sep='')
print("A non-Big-3 player wins US Open = ",round(nonbig3_champ*100,2),'%',sep='')
 

FRV2

Semi-Pro
I thought this looked like fun so I gave it a try. I made a script which calculates odds for the top 4 seeds winning, but also depending on which half of the draw Federer is in.

Python:
#Calculate US OPEN odds for each of the top 4 seeds prior to the draw
print('Enter the probability (between 0 and 1) of the top 4 seeds making the semi-finals')
nadal_semis = float(input("Nadal: "))
djokovic_semis = float(input("Djokovic: "))
federer_semis = float(input("Federer: "))
thiem_semis = float(input("Thiem: "))

#Odds of top 4 seeds beating random opposition based on their probability to make it through to the semi-finals
nadal_def_mug = nadal_semis**(1/5)
djokovic_def_mug = djokovic_semis**(1/5)
federer_def_mug = federer_semis**(1/5)
thiem_def_mug = thiem_semis**(1/5)

#organizing data in lists
nadal = [nadal_semis, nadal_def_mug]
djokovic = [djokovic_semis, djokovic_def_mug]
federer = [federer_semis, federer_def_mug]
thiem = [thiem_semis, thiem_def_mug]

#Odds of top 4 seeds beating each other
print('Enter the probability (between 0 and 1) of the top 4 seeds beating each other in any given match')
federer_def_djokovic = float(input('Federer defeats Djokovic: '))
federer_def_nadal = float(input('Federer defeats Nadal: '))
federer_def_thiem = float(input('Federer defeats Thiem: '))

nadal_def_djokovic = float(input('Nadal defeats Djokovic: '))
nadal_def_thiem = float(input('Nadal defeats Thiem: '))
nadal_def_federer = 1-federer_def_nadal

thiem_def_djokovic = float(input('Thiem defeats Djokovic: '))
thiem_def_nadal = 1-nadal_def_thiem
thiem_def_federer = 1-federer_def_thiem

djokovic_def_nadal = 1-nadal_def_djokovic
djokovic_def_federer = 1-federer_def_djokovic
djokovic_def_thiem = 1-thiem_def_djokovic

#Functions here:
def reachfinal(p1,p2,p1_def_p2):
    """Gives odds of player1 reaching the final if they are on the same side of the draw as player2

    """
   
    return p2[0]*(p1[0]*p1_def_p2) + (1 - p2[0])*(p1[0]*p1[1])

def win(p1, p2, p1_def_p2, p3, p1_def_p3):
    """Gives odds of player1 winning the event if player2 and player3 are the possible opponents
    in the final
    """
    return p2[2]*(p1[2] * p1_def_p2) + p3[2]*(p1[2]*p1_def_p3) + (1-p2[2]-p3[2])*(p1[2]*p1[1])
   
#If Federer is in Djokovic's half
nadal_final = reachfinal(nadal,thiem,nadal_def_thiem)
thiem_final = reachfinal(thiem,nadal,thiem_def_nadal)
federer_final = reachfinal(federer,djokovic,federer_def_djokovic)
djokovic_final = reachfinal(djokovic,federer,djokovic_def_federer)

#updating data
nadal += nadal_final,
thiem += thiem_final,
federer += federer_final,
djokovic += djokovic_final,

nadal_champ1 = win(nadal, federer, nadal_def_federer, djokovic, nadal_def_djokovic)
federer_champ1 = win(federer, nadal, federer_def_nadal, thiem, federer_def_thiem)
djokovic_champ1 = win(djokovic, nadal, djokovic_def_nadal, thiem, djokovic_def_thiem)
thiem_champ1 = win(thiem, djokovic, thiem_def_djokovic, federer, thiem_def_federer)

nonbig3_champ = 1 - nadal_champ1 - federer_champ1 - djokovic_champ1

print("\nIf Federer is put in Djokovic's half...")
print("Federer wins US Open = ",round(federer_champ1*100,2),'%',sep='')
print("Nadal wins US Open = ",round(nadal_champ1*100,2),'%',sep='')
print("Djokovic wins US Open = ",round(djokovic_champ1*100,2),'%',sep='')
print("Thiem wins US Open = ",round(thiem_champ1*100,2),'%',sep='')
print("A non-Big-3 player wins US Open = ",round(nonbig3_champ*100,2),'%\n',sep='')

#If Federer is in Nadal's half
nadal_final =   reachfinal(nadal,federer,nadal_def_federer)
federer_final = reachfinal(federer,nadal,federer_def_nadal)
djokovic_final = reachfinal(djokovic,thiem,djokovic_def_thiem)
thiem_final = reachfinal(thiem,djokovic,thiem_def_djokovic)

#Updating data
nadal[2] = nadal_final
thiem[2] = thiem_final
federer[2] = federer_final
djokovic[2] = djokovic_final

nadal_champ2 = win(nadal, djokovic, nadal_def_djokovic, thiem, nadal_def_thiem)
federer_champ2 = win(federer, djokovic, federer_def_djokovic, thiem, federer_def_thiem)
djokovic_champ2 = win(djokovic, nadal, djokovic_def_nadal, federer, djokovic_def_federer)
thiem_champ2 = win(thiem, nadal, thiem_def_nadal, federer, thiem_def_federer)
nonbig3_champ = 1 - nadal_champ2 - federer_champ2 - djokovic_champ2

print("If Federer is put in Nadal's half...")
print("Federer wins US Open = ",round(federer_champ2*100,2),'%',sep='')
print("Nadal wins US Open = ",round(nadal_champ2*100,2),'%',sep='')
print("Djokovic wins US Open = ",round(djokovic_champ2*100,2),'%',sep='')
print("Thiem wins US Open = ",round(thiem_champ2*100,2),'%',sep='')
print("A non-Big-3 player wins US Open = ",round(nonbig3_champ*100,2),'%\n',sep='')

#If Federer's half is unknown
nadal_champ3 = 0.5*nadal_champ1 + 0.5*nadal_champ2
federer_champ3 = 0.5*federer_champ1 + 0.5*federer_champ2
djokovic_champ3 = 0.5*djokovic_champ1 + 0.5*djokovic_champ2
thiem_champ3 = 0.5*thiem_champ1 + 0.5*thiem_champ2
nonbig3_champ = 1 - nadal_champ3 - federer_champ3 - djokovic_champ3

print("Odds without knowing which side Federer is on...")
print("Federer wins US Open = ",round(federer_champ3*100,2),'%',sep='')
print("Nadal wins US Open = ",round(nadal_champ3*100,2),'%',sep='')
print("Djokovic wins US Open = ",round(djokovic_champ3*100,2),'%',sep='')
print("Thiem wins US Open = ",round(thiem_champ3*100,2),'%',sep='')
print("A non-Big-3 player wins US Open = ",round(nonbig3_champ*100,2),'%',sep='')
(y):)
 

OldschoolKIaus

Hall of Fame
I thought this looked like fun so I gave it a try. I made a script which calculates odds for the top 4 seeds winning, but also depending on which half of the draw Federer is in.

Python:
#Calculate US OPEN odds for each of the top 4 seeds prior to the draw
print('Enter the probability (between 0 and 1) of the top 4 seeds making the semi-finals')
nadal_semis = float(input("Nadal: "))
djokovic_semis = float(input("Djokovic: "))
federer_semis = float(input("Federer: "))
thiem_semis = float(input("Thiem: "))

#Odds of top 4 seeds beating random opposition based on their probability to make it through to the semi-finals
nadal_def_mug = nadal_semis**(1/5)
djokovic_def_mug = djokovic_semis**(1/5)
federer_def_mug = federer_semis**(1/5)
thiem_def_mug = thiem_semis**(1/5)

#organizing data in lists
nadal = [nadal_semis, nadal_def_mug]
djokovic = [djokovic_semis, djokovic_def_mug]
federer = [federer_semis, federer_def_mug]
thiem = [thiem_semis, thiem_def_mug]

#Odds of top 4 seeds beating each other
print('Enter the probability (between 0 and 1) of the top 4 seeds beating each other in any given match')
federer_def_djokovic = float(input('Federer defeats Djokovic: '))
federer_def_nadal = float(input('Federer defeats Nadal: '))
federer_def_thiem = float(input('Federer defeats Thiem: '))

nadal_def_djokovic = float(input('Nadal defeats Djokovic: '))
nadal_def_thiem = float(input('Nadal defeats Thiem: '))
nadal_def_federer = 1-federer_def_nadal

thiem_def_djokovic = float(input('Thiem defeats Djokovic: '))
thiem_def_nadal = 1-nadal_def_thiem
thiem_def_federer = 1-federer_def_thiem

djokovic_def_nadal = 1-nadal_def_djokovic
djokovic_def_federer = 1-federer_def_djokovic
djokovic_def_thiem = 1-thiem_def_djokovic

#Functions here:
def reachfinal(p1,p2,p1_def_p2):
    """Gives odds of player1 reaching the final if they are on the same side of the draw as player2

    """
   
    return p2[0]*(p1[0]*p1_def_p2) + (1 - p2[0])*(p1[0]*p1[1])

def win(p1, p2, p1_def_p2, p3, p1_def_p3):
    """Gives odds of player1 winning the event if player2 and player3 are the possible opponents
    in the final
    """
    return p2[2]*(p1[2] * p1_def_p2) + p3[2]*(p1[2]*p1_def_p3) + (1-p2[2]-p3[2])*(p1[2]*p1[1])
   
#If Federer is in Djokovic's half
nadal_final = reachfinal(nadal,thiem,nadal_def_thiem)
thiem_final = reachfinal(thiem,nadal,thiem_def_nadal)
federer_final = reachfinal(federer,djokovic,federer_def_djokovic)
djokovic_final = reachfinal(djokovic,federer,djokovic_def_federer)

#updating data
nadal += nadal_final,
thiem += thiem_final,
federer += federer_final,
djokovic += djokovic_final,

nadal_champ1 = win(nadal, federer, nadal_def_federer, djokovic, nadal_def_djokovic)
federer_champ1 = win(federer, nadal, federer_def_nadal, thiem, federer_def_thiem)
djokovic_champ1 = win(djokovic, nadal, djokovic_def_nadal, thiem, djokovic_def_thiem)
thiem_champ1 = win(thiem, djokovic, thiem_def_djokovic, federer, thiem_def_federer)

nonbig3_champ = 1 - nadal_champ1 - federer_champ1 - djokovic_champ1

print("\nIf Federer is put in Djokovic's half...")
print("Federer wins US Open = ",round(federer_champ1*100,2),'%',sep='')
print("Nadal wins US Open = ",round(nadal_champ1*100,2),'%',sep='')
print("Djokovic wins US Open = ",round(djokovic_champ1*100,2),'%',sep='')
print("Thiem wins US Open = ",round(thiem_champ1*100,2),'%',sep='')
print("A non-Big-3 player wins US Open = ",round(nonbig3_champ*100,2),'%\n',sep='')

#If Federer is in Nadal's half
nadal_final =   reachfinal(nadal,federer,nadal_def_federer)
federer_final = reachfinal(federer,nadal,federer_def_nadal)
djokovic_final = reachfinal(djokovic,thiem,djokovic_def_thiem)
thiem_final = reachfinal(thiem,djokovic,thiem_def_djokovic)

#Updating data
nadal[2] = nadal_final
thiem[2] = thiem_final
federer[2] = federer_final
djokovic[2] = djokovic_final

nadal_champ2 = win(nadal, djokovic, nadal_def_djokovic, thiem, nadal_def_thiem)
federer_champ2 = win(federer, djokovic, federer_def_djokovic, thiem, federer_def_thiem)
djokovic_champ2 = win(djokovic, nadal, djokovic_def_nadal, federer, djokovic_def_federer)
thiem_champ2 = win(thiem, nadal, thiem_def_nadal, federer, thiem_def_federer)
nonbig3_champ = 1 - nadal_champ2 - federer_champ2 - djokovic_champ2

print("If Federer is put in Nadal's half...")
print("Federer wins US Open = ",round(federer_champ2*100,2),'%',sep='')
print("Nadal wins US Open = ",round(nadal_champ2*100,2),'%',sep='')
print("Djokovic wins US Open = ",round(djokovic_champ2*100,2),'%',sep='')
print("Thiem wins US Open = ",round(thiem_champ2*100,2),'%',sep='')
print("A non-Big-3 player wins US Open = ",round(nonbig3_champ*100,2),'%\n',sep='')

#If Federer's half is unknown
nadal_champ3 = 0.5*nadal_champ1 + 0.5*nadal_champ2
federer_champ3 = 0.5*federer_champ1 + 0.5*federer_champ2
djokovic_champ3 = 0.5*djokovic_champ1 + 0.5*djokovic_champ2
thiem_champ3 = 0.5*thiem_champ1 + 0.5*thiem_champ2
nonbig3_champ = 1 - nadal_champ3 - federer_champ3 - djokovic_champ3

print("Odds without knowing which side Federer is on...")
print("Federer wins US Open = ",round(federer_champ3*100,2),'%',sep='')
print("Nadal wins US Open = ",round(nadal_champ3*100,2),'%',sep='')
print("Djokovic wins US Open = ",round(djokovic_champ3*100,2),'%',sep='')
print("Thiem wins US Open = ",round(thiem_champ3*100,2),'%',sep='')
print("A non-Big-3 player wins US Open = ",round(nonbig3_champ*100,2),'%',sep='')
Great stuff!
 

jimjam

Professional
I know it *feels* like the big 3 will take every GS till the end of time, but I can't agree with any calculation that puts non-big-3 chances at 3.186%!

It should be in the 15%-30% range.

PS: Don't listen to those saying your code is ****. You've definitely over-enginereed things but I can see signs of a very organized coder behind it. Could be way worse. You will definitely become a great coder.
 

FRV2

Semi-Pro
I know it *feels* like the big 3 will take every GS till the end of time, but I can't agree with any calculation that puts non-big-3 chances at 3.186%!

It should be in the 15%-30% range.
I agree. It is because of the numbers I initially chose. I already said that.
 

FRV2

Semi-Pro
PS: Don't listen to those saying your code is ****. You've definitely over-enginereed things but I can see signs of a very organized coder behind it. Could be way worse. You will definitely become a great coder.
Appreciate it. My code actually was pretty bad though. You are looking at an edited version after taking some of Betaserve's advice. I'm too lazy to implement the other advice in this thread.
 

TripleATeam

Legend
I finished the python version of my above script. Should be quite malleable, but still doesn't account for non-standard input.
Python:
def calculate(index, matches, low, high):
    size = int(high - low)
    chanceToReach = chanceToHere[index]
    if (size == 1):
        return chanceToReach
    half = low + int(size / 2)
    if size > 2:
        if index >= half:
            chanceToReach = calculate(index, matches, half, high)
        else:
            chanceToReach = calculate(index, matches, low, half)

    nonField = 0.0
    runningTotal = 0.0
    if index >= half:
        for i in range(low, half):
            chance = calculate(i, matches, low, half)
            nonField += chance
            runningTotal += chance * matches[index][i]
    else:
        for i in range(half, high):
            chance = calculate(i, matches, half, high)
            nonField += chance
            runningTotal += chance * matches[index][i]
    temp = float(chanceToReach * (runningTotal + (1.0-nonField) * matches[index][index]))
    return temp
    

size = int(input("Enter bracket size. "))
matchups = [[0.0 for i in range(size)] for j in range(size)]
names = ["" for i in range(size)]
chanceToHere = [0.0 for i in range(size)]

print("\nBracket of size " + str(size) + " selected.\n")
for i in range(size):
    name = input("Player name: ")
    chance = float(input("Chance of making it this far (0.XXX): "))
    field = float(input("Win rate against the field (0.XXX): "))
    names[i] = name
    chanceToHere[i] = chance
    matchups[i][i] = field
    print()

for i in range(size):
    for j in range(i + 1, size):
        chance = float(input("Chance of " + str(names[i]) + " beating " + str(names[j]) + " (0.XXX): "))
        matchups[i][j] = chance
        matchups[j][i] = 1 - chance
    print()

name = "y"
while name != "n":
    name = input("\nWhose chance of winning would you like to calculate? ")
    for i in range(size):
        if name == names[i]:
            percent = float(int(calculate(i, matchups, 0, size) * 10000 + 0.5))/100
            print(name + " has a " + str(percent) + "%% chance of winning.")
    name = input("Calculate another? (y/n): ")
Put this in a Tennis_Odds_Calc.py file and run it, and it should work as long as you follow the template.
 
Last edited:

FRV2

Semi-Pro
I finished the python version of my above script. Should be quite malleable, but still doesn't account for non-standard input.
Python:
def calculate(index, matches, low, high):
    size = int(high - low)
    chanceToReach = chanceToHere[index]
    if (size == 1):
        return chanceToReach
    half = low + int(size / 2)
    if size > 2:
        if index >= half:
            chanceToReach = calculate(index, matches, half, high)
        else:
            chanceToReach = calculate(index, matches, low, half)

    nonField = 0.0
    runningTotal = 0.0
    if index >= half:
        for i in range(low, half):
            chance = calculate(i, matches, low, half)
            nonField += chance
            runningTotal += chance * matches[index][i]
    else:
        for i in range(half, high):
            chance = calculate(i, matches, half, high)
            nonField += chance
            runningTotal += chance * matches[index][i]
    temp = float(chanceToReach * (runningTotal + (1.0-nonField) * matches[index][index]))
    return temp
  

size = int(input("Enter bracket size. "))
matchups = [[0.0 for i in range(size)] for j in range(size)]
names = ["" for i in range(size)]
chanceToHere = [0.0 for i in range(size)]

print("Computing on a bracket of size " + str(size))
for i in range(size):
    name = input("Player name: ")
    chance = float(input("Chance of making it this far (0.XXX): "))
    field = float(input("Win rate against the field (0.XXX): "))
    names[i] = name
    chanceToHere[i] = chance
    matchups[i][i] = field
    print()

for i in range(size):
    for j in range(i + 1, size):
        chance = float(input("Chance of " + str(names[i]) + " beating " + str(names[j]) + " (0.XXX): "))
        matchups[i][j] = chance
        matchups[j][i] = 1 - chance
    print()

name = "y"
while name != "n":
    name = input("\nWhose chance of winning would you like to calculate? ")
    for i in range(size):
        if name == names[i]:
            percent = float(int(calculate(i, matchups, 0, size) * 10000 + 0.5))/100
            print(name + " has a " + str(percent) + "%% chance of winning.")
    name = input("Calculate another? (y/n): ")
Put this in a Tennis_Odds_Calc.py file and run it, and it should work as long as you follow the template.
Like (y)
 

jimjam

Professional
Appreciate it. My code actually was pretty bad though. You are looking at an edited version after taking some of Betaserve's advice. I'm too lazy to implement the other advice in this thread.
Ah well, you're learning then!

A useful next exercise is to code this in a more generic fashion:

1) create a data structure representing a draw
2) create matrix representing the odds of any one player beating another
3) create function that takes 1 + 2 and spits out winning probabilities.

Total overkill but you'd get code that could work with any tournament. :)
 

FRV2

Semi-Pro
Ah well, you're learning then!

A useful next exercise is to code this in a more generic fashion:

1) create a data structure representing a draw
2) create matrix representing the odds of any one player beating another
3) create function that takes 1 + 2 and spits out winning probabilities.

Total overkill but you'd get code that could work with any tournament. :)
Thank you for the advice (y). I'm happy to let the other, more advanced, programmers on this forum who are interested tackle these problems. I'm still learning the basics of programming. (I have trouble reading the code of other posters on here, so I think diving into this further would be too advanced for me)
 

ADuck

Hall of Fame
Thank you for the advice (y). I'm happy to let the other, more advanced, programmers on this forum who are interested tackle these problems. I'm still learning the basics of programming. (I have trouble reading the code of other posters on here, so I think diving into this further would be too advanced for me)
I'm in the same boat as you man ;) TripleATeam seems like the more experienced one here but it was a fun concept for me to try. The maths involved in this question is actually more complex than anything I've coded so far so it was good practise thanks for the idea.
 

FRV2

Semi-Pro
I'm in the same boat as you man ;) TripleATeam seems like the more experienced one here but it was a fun concept for me to try. The maths involved in this question is actually more complex than anything I've coded so far so it was good practise thanks for the idea.
No problem. You came up with a great script.
 

TripleATeam

Legend
I'm in the same boat as you man ;) TripleATeam seems like the more experienced one here but it was a fun concept for me to try. The maths involved in this question is actually more complex than anything I've coded so far so it was good practise thanks for the idea.
You guys flatter me, really. Well done in your code, though. Very readable and easy to follow along. I also really enjoyed your way of calculating their odds of beating any random player they may encounter. Very resourceful, and it minimizes what the client needs to input.
 
Top