Skip to content

Instantly share code, notes, and snippets.

@PChild
Created May 16, 2019 03:20
Show Gist options
  • Save PChild/fbcd32b00b77e2ea01c85e0a6e1dc7ef to your computer and use it in GitHub Desktop.
Save PChild/fbcd32b00b77e2ea01c85e0a6e1dc7ef to your computer and use it in GitHub Desktop.
My bad implementation of the FRC DCMP division algo
import gen
import math
import numpy
import random
import statistics as stat
def chunk(l, n):
'''
Splits a list l into a list of n new lists
'''
return [list (i) for i in numpy.array_split(numpy.array(l),n)]
def snr(inList):
'''
Signal-to-Noise Ratio of a list of ints
'''
return 10 * math.log(stat.mean(inList) ** 2 / stat.stdev(inList) ** 2)
def distributeTeams(quartiles):
'''
Takes a list of four quartiles to be distributed into divisions
Returns list of two acceptable divisions
'''
allowedAvgStrDiff = 1.0
allowedStrDistDiff = 1.0
allowedTopStrDistDiff = 1.5
divA = []
divB = []
for teamSet in quartiles:
random.shuffle(teamSet)
splitSize = int(len(teamSet) / 2)
divA += teamSet[:splitSize]
divB += teamSet[splitSize:]
aPts = sorted([team['points'] for team in divA], reverse=True)
bPts = sorted([team['points'] for team in divB], reverse=True)
meanA = stat.mean(aPts)
meanB = stat.mean(bPts)
passesMeanCheck = abs(meanA - meanB) <= allowedAvgStrDiff
passesStrCheck = abs(snr(aPts) - snr(bPts)) <= allowedStrDistDiff
topA = chunk(aPts, 4)[0]
topB = chunk(bPts, 4)[0]
passesTopStrCheck = abs(snr(topA) - snr(topB)) <= allowedTopStrDistDiff
if passesMeanCheck and passesStrCheck and passesTopStrCheck:
return [sorted(divA, key= lambda k: int(k['team'][3:])), sorted(divB, key= lambda k: int(k['team'][3:]))]
else:
return distributeTeams(quartiles)
if __name__ == "__main__":
tba = gen.setup()
year = 2019
dist = 'chs'
dcmp = '2019chcmp'
distRanks = tba.district_rankings(str(year) + dist)
preDCMPstandings = []
for team in distRanks:
preDCMP = 0
for event in team['event_points']:
if event['event_key'] != dcmp:
preDCMP += event['total']
preDCMPstandings.append({'team': team['team_key'], 'points': preDCMP})
'''
Sort the pre-DCMP rankings, choose 80 top to send to DMCP, split into quartiles, find acceptable divisions
'''
preDCMPstandings = sorted(preDCMPstandings, key= lambda k: k['points'], reverse=True)[0:80]
quartiles = chunk(preDCMPstandings, 4)
divA, divB = distributeTeams(quartiles)
divs = []
for idx, i in enumerate(divA):
divs.append({'A': i['team'][3:], 'B': divB[idx]['team'][3:]})
gen.listOfDictToCSV(dcmp + ' Simulated Divisions', divs, ['A', 'B'])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment