Package: bracketology
Welcome to Bracketology!The goal of bracketology is to speed up the analysis of NCAA march madness data
and help develop algorithms for filling out brackets.Documentation:https://bracketology.readthedocs.io/en/latest/GitHub Repo:https://github.com/stahl085/bracketologyIssue Tracker:https://github.com/stahl085/bracketology/issuesBacklog:https://github.com/stahl085/bracketology/projects/1?fullscreen=truePyPI:https://pypi.org/project/bracketology/Before You StartHere are the main things you need to know:The main parts of this package are theBracketobjects and simulator functions in thesimulatorsmoduleA Bracket is composed ofTeamandGameobjectsGame objects have two Team objects as attributes, and the round numberTeams have a name, seed, and dictionary for statisticsSimulator functions have 1 argument of type Game, and return the winning Team of that GameInstallationInstall frompippipinstallbracketologyOr download directly fromPyPiGetting StartedImport bracketology and create a bracket from last year.frombracketologyimportBracket,Game,Team# Create a bracket object from 2019year=2019b19=Bracket(year)TutorialInspecting the Bracket ObjectHere are three different ways you can inspect the Bracket.Inspect teams in each region (dictionary of actual results)Inspect actual results by round (dictionary)Inspect simulated results by round (list of Team attributes)Get Teams in each RegionPrint out all the teams in each region. Theregionsattribute is
a dictionary with the information of all the teams in each region.>>>print(b19.regions){'East':[{'Team':'Duke','Seed':1},{'Team':'Michigan St','Seed':2},{'Team':'LSU','Seed':3},...],'West':[{'Team':'Gonzaga','Seed':1},{'Team':'Michigan','Seed':2},{'Team':'Texas Tech','Seed':3},...],'Midwest':[{'Team':'North Carolina','Seed':1},{'Team':'Kentucky','Seed':2},{'Team':'Houston','Seed':3},...],'South':[{'Team':'Virginia','Seed':1},{'Team':'Tennessee','Seed':2},{'Team':'Purdue','Seed':3},...]}Actual Results by RoundTheresultattribute will return a dictionary (similar toregionsabove)
but will be broken out by which teams actually made it to each round. You can
use it to inspect the real tournament results.>>>print(b19.result.keys())dict_keys(['first','second','sweet16','elite8','final4','championship','winner'])>>>print(b19.result['final4'])[{'Team':'Michigan St','Seed':2},{'Team':'Virginia','Seed':1},{'Team':'Texas Tech','Seed':3},{'Team':'Auburn','Seed':5}]>>>print(b19.result.get('winner')){'Team':'Virginia','Seed':1}Simulation Results by RoundPrint out all the teams that are simulated to make it to each round.
The first round is filled out by default. This is a list ofTeamobjects
that are simulated to make it to each round. Right nowround2is an empty list
because we have not simulated the bracket yet.>>>print(b19.round1)[<1Duke>,<2MichiganSt>,<3LSU>,...,<1Gonzaga>,<2Michigan>,<3TexasTech>,...,<1NorthCarolina>,<2Kentucky>,<3Houston>,...,<1Virginia>,<2Tennessee>,<3Purdue>]>>>print(b19.round2)[]Creating a Simulator AlgorithmA simulator function needs to take in aGameand Return aTeam.First we create some faux teams and games to test our simulator function on.# Create teamsteam1=Team(name='Blue Mountain State',seed=1)team2=Team(name='School of Hard Knocks',seed=2)â€‹# Create a game between the teamsgame1=Game(team1,team2,round_number=1)Then we define the simulator function.importrandomdefpick_a_random_team(the_game):# Extract Teams from Gameteam1=the_game.top_teamteam2=the_game.bottom_teamâ€‹# Randomly select a winnerifrandom.random()<0.5:winner=team1else:winner=team2# Return the lucky teamreturnwinnerTest the function out on a game.>>>pick_a_random_team(game1)<2SchoolofHardKnocks>Let’s run some simulations with our function!# Initialize Simulation ParametersBMS_wins=0HardKnocks_wins=0n_games=1000â€‹# Loop through a bunch of gamesforiinrange(n_games):# Simulate the winnerwinner=pick_a_random_team(game1)# Increment win totalsifwinner.seed==1:BMS_wins+=1elifwinner.seed==2:HardKnocks_wins+=1else:raiseException("We have a tie??")â€‹# Calculate total win percentageBMS_win_pct=round(BMS_wins/n_games,4)*100HardKnocks_win_pct=round(HardKnocks_wins/n_games,4)*100â€‹# Print out resultsprint(f"Blue Mountain State Win Percentage:   %{BMS_win_pct}")print(f"School of Hard Knocks Win Percentage: %{HardKnocks_win_pct}")Output:BlueMountainStateWinPercentage:%50.9SchoolofHardKnocksWinPercentage:%49.1Evaluting Simulator ResultsLet’s evaluate our simulator function on some actual brackets.# Initialize simulation parametersn_sims=1000# number of times to simulate through all yearstotal_sims=(n_sims*len(brackets))scores=[]correct_games=[]# Loop through a plethora of bracketsforiinrange(n_sims):forbracketinbrackets:# Run the algorithm on the bracketbracket.score(sim_func=pick_a_random_team,verbose=False)# Save the scoring results in a listscores.append(bracket.total_score)correct_games.append(bracket.n_games_correct)# Calculate the average across all simulationsavg_score=round(sum(scores)/total_sims)avg_correct=round(sum(correct_games)/total_sims)# Print resultprint(f"Average number total score{avg_score}/192")print(f"Average number of games guessed correctly{avg_correct}/64")Output:Averagenumbertotalscore31/192Averagenumberofgamesguessedcorrectly21/64Easy, right!