Skip to content

Instantly share code, notes, and snippets.

@NikhilNarayana
Last active November 5, 2019 22:14
Show Gist options
  • Save NikhilNarayana/b58e1b906c2ad0cbbf2ac09f0639fc31 to your computer and use it in GitHub Desktop.
Save NikhilNarayana/b58e1b906c2ad0cbbf2ac09f0639fc31 to your computer and use it in GitHub Desktop.
A program to compile how many and which events are missing match videos for FRC events.
#!/usr/bin/env python3
import sys
import tbapy # pip install tbapy
import collections as col # for OrderedDict
tba = tbapy.TBA("pI9kcg6VHPj7qySj5j467oOvmXlPPAbjF8n96CComaJod4mBxeCNRW5QE9i6YYh9")
def regionalStats(year):
"""
Stats for regional event match video uploads. reg and web are made up district abbreviations. web refers to all official events streamed officially by FIRST, reg is all other official events.
:param year: The year you want the stats from.
:return: A list with 5 pieces in a tuple. The data is as follows.
0. number of events (int)
1. names of the districts (list)
2. the number of missing match videos from each district (list)
3. total matches played in each district (list)
4. the event key of every event that missed any number of match videos (dictionary)
"""
numevents = 0
districts = ['reg', 'web']
missing = [0, 0]
totalmatches = [0, 0]
notallvids = col.OrderedDict()
notallvids.update(reg=[], web=[])
for event in tba.events(year):
if all(k != event.event_type_string for k in ("Regional", "Championship Finals", "Championship Division")):
continue
try:
channame = event.webcasts[0]["channel"].lower()
matches = tba.event_matches(event.key)
if matches != []:
numevents += 1
for match in matches:
if match['alliances']['blue']['score'] == -1 and match['alliances']['red']['score'] == -1:
continue
if "firstinspires" in channame and all(k not in channame for k in ("hawaii", "china")):
totalmatches[1] += 1
else:
totalmatches[0] += 1
if not match.videos:
if "firstinspires" in channame and all(k not in channame for k in ("hawaii", "china")):
missing[1] += 1
if event.key not in notallvids['web']:
notallvids['web'].append(str(event.key.strip()))
else:
missing[0] += 1
if event.key not in notallvids['reg']:
notallvids['reg'].append(str(event.key.strip()))
print(f"{event.key} is parsed")
else:
print(f"{event.key} has not happened yet")
except IndexError:
if any(k in event.event_type_string for k in ("Regional", "Championship Finals", "Division")):
matches = tba.event_matches(event.key)
if matches != []:
numevents += 1
for match in matches:
if match['alliances']['blue']['score'] == -1 and match['alliances']['red']['score'] == -1:
continue
totalmatches[0] += 1
if not match.videos:
missing[0] += 1
if event.key not in notallvids['reg']:
notallvids['reg'].append(str(event.key.strip()))
print(f"{event.key} had no webcast and is parsed")
else:
print(f"{event.key} has not happened yet")
return (numevents, districts, missing, totalmatches, notallvids)
def stats(year, verbose=None, districtset=None):
"""
Stats for district and regional events match video uploads.
:param year: The year you want the stats from.
:param verbose: Set to True to print the missing matches from every event. Suggest that you only use it with districtset.
:param districtset: A string with district abbreviations that you want stats for. Ex. pnw,pch,in,fim
:return: A list with 5 pieces of tuple. The data is as follows.
0. number of events (int)
1. names of the districts (list)
2. the number of missing match videos from each district (list)
3. total matches played in each district (list)
4. the event key of every event that missed any number of match videos (dictionary)
"""
"""init vars"""
districts = []
numevents = 0
notallvids = col.OrderedDict()
i = 0
missing = []
totalmatches = []
for district in tba.districts(year):
if districtset is not None and district.abbreviation not in districtset:
continue
districts.append(str(district.abbreviation))
notallvids[str(district.abbreviation)] = []
missing.append(0)
totalmatches.append(0)
for event in tba.district_events(district.key):
matches = tba.event_matches(event.key)
if matches != []:
if verbose:
print("")
print("")
print(event.key)
numevents += 1
for match in matches:
if match['alliances']['blue']['score'] == -1 and match['alliances']['red']['score'] == -1:
continue
totalmatches[i] += 1
if not match.videos:
if verbose:
if match.comp_level != "qm":
print(match.comp_level + str(match.set_number) + "m" + str(match.match_number), end=' ')
else:
print(match.comp_level + str(match.match_number), end=' ')
missing[i] += 1
if event.key not in notallvids[str(district.abbreviation)]:
notallvids[str(district.abbreviation)].append(str(event.key.strip()))
elif verbose:
print(f"{event.key} has not happened yet")
i += 1
if verbose:
print("")
print(f"{district.abbreviation} events are parsed")
return (numevents, districts, missing, totalmatches, notallvids)
def printer(numevents, districts, missing, totalmatches, notallvids, tab):
"""
The default printing option for this program.
:params: variables outputted by regionalStats and stats.
"""
for district in notallvids:
print("{0:4}: ".format(district), end='')
for event in notallvids[district]:
print(event + " ", end='')
if not notallvids[district]:
print("ALL MATCHES UPLOADED", end='')
print(" ")
numnotall = 0
for district in notallvids.values():
for event in district:
numnotall += 1
if numevents == 0:
print("No events parsed")
else:
totalTotalMatches = sum(totalmatches)
totalMissing = sum(missing)
print(f"Matches Missing: {totalMissing} / {totalTotalMatches} = ", end='')
print("{0:.4g}%".format(100 * (float(totalMissing) / float(totalTotalMatches))))
print(f"Events Missing Matches: {numnotall} / {numevents} = ", end='')
print("{0:.4g}%".format(100 * (float(numnotall) / float(numevents))))
print("districts: ", end='')
for district in districts:
print("{0:6}".format(district), end='')
if tab:
print("\t", end='')
print("")
print("missing : ", end='')
for val in missing:
print("{0:6}".format(str(val)), end='')
if tab:
print("\t", end='')
print("")
print("total : ", end='')
for val in totalmatches:
print("{0:6}".format(str(val)), end='')
if tab:
print("\t", end='')
print("")
print("percent : ", end='')
for miss, total in zip(missing, totalmatches):
num = 100 * (float(miss) / float(total)) if total else 0
if num:
print("{0:<6.1f}".format(num), end='')
if tab:
print("\t", end='')
else:
num = 0
print("{0:<6}".format(num), end='')
if tab:
print("\t", end='')
print("")
def main(year=None, districts=None, verbose=False, regional=False, district=False, tab=False):
"""
Run function for tbavids.
:param year: The year you want the info for.
:param districts: a string with district abbreviations for the events you want parsed.
:param verbose: Set to True to print every match that is missing a video for every event
:param regional: Set to True to get the data for regionals
:param district: Set to True to get the data for districts if regional is also set to True
"""
for arg in sys.argv[1:]:
if any(k in arg for k in ("chs", "fim", "fma", "in", "isr", "mar", "nc", "ne", "ont", "pch", "pnw", "tx")):
districts = arg
elif arg == "-v":
verbose = True
elif arg == "-r":
regional = True
elif arg == "-d":
district = True
elif arg == "-t":
tab = True
else:
try:
year = int(arg)
except (TypeError, ValueError):
pass
regStats = None
districtStats = None
if year:
if regional:
regStats = regionalStats(year)
if district or not regional:
districtStats = stats(year, verbose, districts)
else:
print("Verbose setting can be accessed by running tbavids.py -v [YEAR](DISTRICT ABBREVIATIONS,)*")
print("Verbose output is not available for regionals yet, use tbavids.py -r [YEAR] for regionals")
districtStats = stats(input("What year would you like the match video stats of districts for? "))
if regStats and districtStats:
toprint = []
for dist, reg in zip(districtStats, regStats):
if isinstance(dist, int):
toprint.append(dist + reg)
elif isinstance(dist, list):
dist.extend(reg)
toprint.append(dist)
elif isinstance(dist, dict):
dist.update(reg)
toprint.append(dist)
printer(*toprint, tab)
elif regStats:
printer(*regStats, tab)
else:
printer(*districtStats, tab)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment