Skip to content

Instantly share code, notes, and snippets.

@kylesnowschwartz
Created December 1, 2016 04:02
Show Gist options
  • Save kylesnowschwartz/4a8e6037a2bf6b67c1e922661d0ff5ae to your computer and use it in GitHub Desktop.
Save kylesnowschwartz/4a8e6037a2bf6b67c1e922661d0ff5ae to your computer and use it in GitHub Desktop.
Justins League Simulator
#!/usr/bin/python
import numpy as np
import copy
num_simul = 10000
# get initial standings
init_standings, past_perform, playoff_count = dict(), dict(), dict()
f = open('2016_week12_standings.txt'); lines = f.readlines(); f.close()
for line in lines[1:]: #skips header
t = line.rstrip('\n').split('\t')
owner = t[0]
init_standings[ owner ] = [ int(t[1]), float(t[2]) ] #number of wins and total points
past_perform[ owner ] = map(float, t[3:5]) #average score and standard deviation
playoff_count[ owner ] = 0 # initialize counts to zero for each owner
# get list of matchups
matchups = list()
f = open('matchups_week13-14.txt'); lines = f.readlines(); f.close()
for line in lines:
matchups.append( tuple( line.rstrip('\n').split('\t') ) )
# run simulations
standings = dict()
for sim in range(num_simul):
# re-initialize standings
standings = copy.deepcopy(init_standings)
# play out matchups
for m in matchups:
# randomly chooses scores based on average and STDev for each person (normal distribution)
A = np.random.normal( past_perform[m[0]][0], past_perform[m[0]][1] )
B = np.random.normal( past_perform[m[1]][0], past_perform[m[1]][1] )
# updates total points
standings[ m[0] ][1] += A
standings[ m[1] ][1] += B
# updates standings
if A > B:
standings[ m[0] ][0] += 1
else:
standings[ m[1] ][0] += 1
# get 4 top finishers and add to playoff count
for winner in sorted(standings, key = lambda k: (standings[k][0], standings[k][1]), reverse = True)[:4]:
playoff_count[ winner ] += 1
# print results
for owner, count in sorted(playoff_count.items(), key = lambda k: k[1], reverse = True):
print owner + ':\t{:.2%}'.format( float(count) / num_simul )
@kylesnowschwartz
Copy link
Author

kylesnowschwartz commented Dec 1, 2016

f = open('2016_week12_standings.txt'); lines = f.readlines(); f.close()
should use the

with open('blah') as f
  lines = f.readlines()

syntax. and A and B can be given proper names

[4:21] hard when you're building off a the math but it's just unreadable in code form

[4:22] i can see your buddy is trying to optimise for numpy, but that's different from doing code golf

[4:22] i don't think the lambdas are actually any more peformant than unrolling them

@kylesnowschwartz
Copy link
Author

kylesnowschwartz commented Dec 1, 2016

one pattern i haven't seen is a way of using dict() style syntax with numpy arrays

[4:24] such that you get the speed optimisations of numpy

[4:24] but the readability of named keys

[4:24] and the only thing i can think of in the short term is the way nasm does structs

[4:24] for those of us who did linux assembly code in the 90's

[4:24] tl;dr you have a lookup dict that maps your keys to indices

[4:25] so if the 0th index means date and the 1st index means result

[4:25] you do data[lookup["date"]] instead of data[0]

[4:25] still not ideal but you start to build a bit more knowledge into the code itself

@kylesnowschwartz
Copy link
Author

kylesnowschwartz commented Dec 1, 2016

it's not clear why you're traversing a 2D array too though?

[4:32] like if it were ruby you'd have an object

[4:32] be doing Player.mean

[4:32] Player.standard_deviation

[4:32] Player.expected_score
and the matchups

[4:33] [0] and [1] have meanings

[4:33] are they player_one and player_two?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment