Skip to content

Commit

Permalink
Port Active Teams in District Table (#3332)
Browse files Browse the repository at this point in the history
This has some helper dependencies, and the event simulator/fixture loader.

I'd forgotten about this fixture loader from the old app, I'm not sure if this is better or worse than our existing situation with json API responses. I suppose we can keep both for now, since these tests were tricky to port anyway.

This will require the ndb stub at at least v0.0.14, as it requires phil-lopreiato/google-cloud-datastore-stub@790b69b (which was very fun to debug...)
  • Loading branch information
phil-lopreiato committed Jan 23, 2021
1 parent c919ce6 commit e893efc
Show file tree
Hide file tree
Showing 26 changed files with 27,709 additions and 33 deletions.
623 changes: 623 additions & 0 deletions src/backend/common/helpers/event_team_status_helper.py

Large diffs are not rendered by default.

254 changes: 254 additions & 0 deletions src/backend/common/helpers/rankings_helper.py
@@ -0,0 +1,254 @@
from typing import Dict, List, Optional

from backend.common.models.event_details import EventDetails
from backend.common.models.event_ranking import RankingSortInfo
from backend.common.models.keys import Year


class RankingsHelper:
SORT_ORDERS = {
2020: [2, 3, 4, 5, 6],
2019: [2, 3, 4, 5, 6],
2018: [2, 3, 4, 5, 6],
2017: [2, 3, 4, 5, 6, 7],
2016: [2, 3, 4, 5, 6],
2015: [2, 5, 3, 4, 7, 6],
2014: [2, 3, 4, 5, 6],
2013: [2, 3, 4, 5],
2012: [2, 3, 4, 5],
2011: [6, 7],
2010: [3, 4, 5],
2009: [6, 7, 8],
2008: [6, 7, 8],
2007: [6, 7, 8],
}

SORT_ORDER_INFO: Dict[Year, List[RankingSortInfo]] = {
2020: [
{"name": "Ranking Score", "precision": 2},
{"name": "Auto", "precision": 0},
{"name": "End Game", "precision": 0},
{"name": "Teleop Cell + CPanel", "precision": 0},
],
2019: [
{"name": "Ranking Score", "precision": 2},
{"name": "Cargo", "precision": 0},
{"name": "Hatch Panel", "precision": 0},
{"name": "HAB Climb", "precision": 0},
{"name": "Sandstorm Bonus", "precision": 0},
],
2018: [
{"name": "Ranking Score", "precision": 2},
{"name": "Park/Climb Points", "precision": 0},
{"name": "Auto", "precision": 0},
{"name": "Ownership", "precision": 0},
{"name": "Vault", "precision": 0},
],
2017: [
{"name": "Ranking Score", "precision": 2},
{"name": "Match Points", "precision": 0},
{"name": "Auto", "precision": 0},
{"name": "Rotor", "precision": 0},
{"name": "Touchpad", "precision": 0},
{"name": "Pressure", "precision": 0},
],
2016: [
{"name": "Ranking Score", "precision": 0},
{"name": "Auto", "precision": 0},
{"name": "Scale/Challenge", "precision": 0},
{"name": "Goals", "precision": 0},
{"name": "Defense", "precision": 0},
],
2015: [
{"name": "Qual Avg.", "precision": 1},
{"name": "Coopertition", "precision": 0},
{"name": "Auto", "precision": 0},
{"name": "Container", "precision": 0},
{"name": "Tote", "precision": 0},
{"name": "Litter", "precision": 0},
],
2014: [
{"name": "Qual Score", "precision": 0},
{"name": "Assist", "precision": 0},
{"name": "Auto", "precision": 0},
{"name": "Truss & Catch", "precision": 0},
{"name": "Teleop", "precision": 0},
],
2013: [
{"name": "Qual Score", "precision": 0},
{"name": "Auto", "precision": 0},
{"name": "Climb", "precision": 0},
{"name": "Teleop", "precision": 0},
],
2012: [
{"name": "Qual Score", "precision": 0},
{"name": "Hybrid", "precision": 0},
{"name": "Bridge", "precision": 0},
{"name": "Teleop", "precision": 0},
],
2011: [
{"name": "Qual Score", "precision": 0},
{"name": "Ranking Score", "precision": 2},
],
2010: [
{"name": "Seeding Score", "precision": 0},
{"name": "Coopertition Bonus", "precision": 0},
{"name": "Hanging Points", "precision": 0},
],
2009: [
{"name": "Qual Score", "precision": 0},
{"name": "Seeding Score", "precision": 2},
{"name": "Match Points", "precision": 0},
],
2008: [
{"name": "Qual Score", "precision": 0},
{"name": "Seeding Score", "precision": 2},
{"name": "Match Points", "precision": 0},
],
2007: [
{"name": "Qual Score", "precision": 0},
{"name": "Seeding Score", "precision": 2},
{"name": "Match Points", "precision": 0},
],
2006: [
{"name": "Qual Score", "precision": 0},
{"name": "Seeding Score", "precision": 2},
{"name": "Match Points", "precision": 0},
],
}

NO_RECORD_YEARS = {2010, 2015}

QUAL_AVERAGE_YEARS = {2015}

"""
@classmethod
def build_ranking(
cls,
year: Year,
rank: int,
team_key: TeamKey,
wins: int,
losses: int,
ties: int,
qual_average: Optional[float],
matches_played: int,
dq: int,
sort_orders: List,
) -> EventRanking:
if year in cls.NO_RECORD_YEARS:
record = None
else:
record = {
"wins": int(wins),
"losses": int(losses),
"ties": int(ties),
}
if year not in cls.QUAL_AVERAGE_YEARS:
qual_average = None
else:
qual_average = float(qual_average)
sort_orders_sanitized = []
for so in sort_orders:
try:
sort_orders_sanitized.append(float(so))
except:
sort_orders_sanitized.append(0.0)
return {
"rank": int(rank),
"team_key": team_key,
"record": record, # None if record doesn't affect rank (e.g. 2010, 2015)
"qual_average": qual_average, # None if qual_average doesn't affect rank (all years except 2015)
"matches_played": int(matches_played),
"dq": int(dq),
"sort_orders": sort_orders_sanitized,
}
"""

@classmethod
def get_sort_order_info(
cls, event_details: EventDetails
) -> Optional[List[RankingSortInfo]]:
year = event_details.year
if event_details.key.id() == "2015mttd": # 2015mttd played the 2014 game
year = 2014
return cls.SORT_ORDER_INFO.get(year)

"""
@classmethod
def convert_rankings(cls, event_details):
\"""
Converts event_details.rankings to event_details.rankings2
\"""
if not event_details.rankings:
return None
year = event_details.year
if event_details.key.id() == "2015mttd": # 2015mttd played the 2014 game
year = 2014
# Look up indexes
mp_index = RankingIndexes.MATCHES_PLAYED.get(year)
if mp_index is None:
return
ranking_index = RankingIndexes.RECORD_INDEXES.get(year)
dq_index = None
# Overwrite indexes in case thing are different
for i, name in enumerate(event_details.rankings[0]):
name = name.lower()
if name == "played":
mp_index = i
if name == "dq":
dq_index = i
sort_order_indices = cls.SORT_ORDERS[year]
# Special case for offseasons with different ordering
if year == 2015 and event_details.rankings[0][3].lower() == "coopertition":
sort_order_indices = [2, 3, 5, 4, 6, 7]
rankings2 = []
for row in event_details.rankings[1:]:
if ranking_index is None:
wins = 0
losses = 0
ties = 0
elif type(ranking_index) == tuple:
wins = row[ranking_index[0]]
losses = row[ranking_index[1]]
ties = row[ranking_index[2]]
else:
wins, losses, ties = row[ranking_index].split("-")
if dq_index is None:
dq = 0
else:
dq = int(row[dq_index])
if year == 2015:
qual_average = row[RankingIndexes.CUMULATIVE_RANKING_SCORE.get(year)]
else:
qual_average = None
sort_orders = [row[index] for index in sort_order_indices]
rankings2.append(
cls.build_ranking(
year,
int(row[0]),
"frc{}".format(row[1]),
wins,
losses,
ties,
qual_average,
row[mp_index],
dq,
sort_orders,
)
)
return rankings2
"""

0 comments on commit e893efc

Please sign in to comment.