Skip to content

Commit 82150fe

Browse files
authored
Merge pull request #40 from team4099/separate-scouting-accuracy
Separate scouting accuracy
2 parents 1a20326 + f4fd784 commit 82150fe

File tree

2 files changed

+149
-3
lines changed

2 files changed

+149
-3
lines changed

src/page_managers/scouting_accuracy_manager.py

Lines changed: 125 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
# TODO: Debug teleop and maybe auto later
2+
13
"""Creates the `ScoutingAccuracyManager` class used to set up the Scouting Accuracy page and generate its table."""
24
import pandas as pd
35
import streamlit as st
@@ -8,7 +10,8 @@
810
Queries,
911
retrieve_scouting_data,
1012
retrieve_match_schedule,
11-
retrieve_match_data
13+
retrieve_match_data,
14+
Criteria
1215
)
1316
import requests
1417
import os
@@ -45,6 +48,9 @@ def generate_accuracy_table(self, member_name) -> DataFrame:
4548
accuracy_dict = {
4649
'ScoutersNames': [],
4750
'CumulativeAccuracy': [],
51+
'AutoAccuracy': [],
52+
'TeleopAccuracy': [],
53+
'EndgameAccuracy': [],
4854
'NumberOfScoutedMatches': []
4955
}
5056

@@ -65,10 +71,16 @@ def generate_accuracy_table(self, member_name) -> DataFrame:
6571
if (match["comp_level"] + str(match["match_number"])) == match_key:
6672
red_total_score = match["score_breakdown"]["red"]["totalPoints"]
6773
red_foul_score = match["score_breakdown"]["red"]["foulPoints"]
74+
red_auto_score = match["score_breakdown"]["red"]["autoPoints"]
75+
red_teleop_score = match["score_breakdown"]["red"]["teleopPoints"]
76+
red_endgame_score = match["score_breakdown"]["red"]["endGameBargePoints"]
6877
red_calculated_score = red_total_score - red_foul_score
6978
break
7079

7180
red_scouting_alliance_score = 0
81+
red_scouting_auto_score = 0
82+
red_scouting_teleop_score = 0
83+
red_scouting_endgame_score = 0
7284

7385
scouters_names_list_r = []
7486

@@ -78,22 +90,73 @@ def generate_accuracy_table(self, member_name) -> DataFrame:
7890
match_index_list = scouting_team_filter.index[scouting_team_filter[Queries.MATCH_KEY] == match_key].tolist()
7991
if len(match_index_list) != 0:
8092
match_index = match_index_list[0]
93+
94+
# Auto Accuracy Retrieval
95+
auto_coral_per_match = [
96+
self.calculated_stats.cycles_by_structure_per_match(int(team_key), Queries.AUTO_CORAL_L1).values,
97+
self.calculated_stats.cycles_by_structure_per_match(int(team_key), Queries.AUTO_CORAL_L2).values,
98+
self.calculated_stats.cycles_by_structure_per_match(int(team_key), Queries.AUTO_CORAL_L3).values,
99+
self.calculated_stats.cycles_by_structure_per_match(int(team_key), Queries.AUTO_CORAL_L4).values
100+
]
101+
for i in range(len(auto_coral_per_match)):
102+
red_scouting_auto_score += auto_coral_per_match[i][match_index] * Criteria.AUTO_CORAL_POINTAGE[i + 1]
103+
auto_algae_per_match = [
104+
self.calculated_stats.cycles_by_structure_per_match(int(team_key), Queries.AUTO_BARGE).values,
105+
self.calculated_stats.cycles_by_structure_per_match(int(team_key), Queries.AUTO_PROCESSOR).values
106+
]
107+
for i in range(len(auto_algae_per_match)):
108+
red_scouting_auto_score += auto_algae_per_match[i][match_index] * Criteria.ALGAE_POINTAGE[i + 1]
109+
leave_points = self.calculated_stats.stat_per_match(int(team_key), Queries.LEFT_STARTING_ZONE, Criteria.BOOLEAN_CRITERIA).values
110+
red_scouting_auto_score += (leave_points[match_index] * 2)
111+
112+
# Teleop Accuracy Retrieval
113+
teleop_coral_per_match = [
114+
self.calculated_stats.cycles_by_structure_per_match(int(team_key), Queries.TELEOP_CORAL_L1).values,
115+
self.calculated_stats.cycles_by_structure_per_match(int(team_key), Queries.TELEOP_CORAL_L2).values,
116+
self.calculated_stats.cycles_by_structure_per_match(int(team_key), Queries.TELEOP_CORAL_L3).values,
117+
self.calculated_stats.cycles_by_structure_per_match(int(team_key), Queries.TELEOP_CORAL_L4).values
118+
]
119+
for i in range(len(teleop_coral_per_match)):
120+
red_scouting_teleop_score += teleop_coral_per_match[i][match_index] * Criteria.TELEOP_CORAL_POINTAGE[i + 1]
121+
teleop_algae_per_match = [
122+
self.calculated_stats.cycles_by_structure_per_match(int(team_key), Queries.TELEOP_BARGE).values,
123+
self.calculated_stats.cycles_by_structure_per_match(int(team_key), Queries.TELEOP_PROCESSOR).values
124+
]
125+
for i in range(len(teleop_algae_per_match)):
126+
red_scouting_teleop_score += teleop_algae_per_match[i][match_index] * Criteria.ALGAE_POINTAGE[i + 1]
127+
128+
# Endgame Accuracy Retrieval
129+
park_points = self.calculated_stats.stat_per_match(int(team_key), Queries.PARKED_UNDER_BARGE, Criteria.BOOLEAN_CRITERIA).values
130+
climb_points = self.calculated_stats.stat_per_match(int(team_key), Queries.CLIMBED_CAGE, Criteria.CLIMBING_POINTAGE).values
131+
red_scouting_endgame_score = park_points[match_index] * 2 + climb_points[match_index]
132+
133+
# Cumulative Accuracy Retrieval
81134
points_per_match = self.calculated_stats.points_contributed_by_match(int(team_key)).values
82135
red_scouting_alliance_score += points_per_match[match_index]
136+
83137
scout_name = scouting_team_filter.iloc[match_index][Queries.SCOUT_ID]
84138
scouters_names_list_r.append(scout_name.title().replace(" ", ""))
85139

86140
red_alliance_accuracy = (1 - abs((red_scouting_alliance_score-red_calculated_score)/red_calculated_score)) * 100
141+
red_auto_accuracy = (1 - abs((red_scouting_auto_score - red_auto_score)/red_auto_score)) * 100
142+
red_teleop_accuracy = (1 - abs((red_scouting_teleop_score - red_teleop_score)/red_teleop_score)) * 100
143+
red_endgame_accuracy = (1 - abs((red_scouting_endgame_score - red_endgame_score)/red_endgame_score)) * 100
87144
scouters_names = ", ".join(scouters_names_list_r)
88145

89146
if member_name.replace(" ", "").lower() in scouters_names.lower():
90147
if scouters_names not in accuracy_dict['ScoutersNames']:
91148
accuracy_dict['ScoutersNames'].append(scouters_names)
92149
accuracy_dict['CumulativeAccuracy'].append(red_alliance_accuracy)
150+
accuracy_dict['AutoAccuracy'].append(red_auto_accuracy)
151+
accuracy_dict['TeleopAccuracy'].append(red_teleop_accuracy)
152+
accuracy_dict['EndgameAccuracy'].append(red_endgame_accuracy)
93153
accuracy_dict['NumberOfScoutedMatches'].append(1)
94154
else:
95155
accuracy_scouts_index = accuracy_dict['ScoutersNames'].index(scouters_names)
96156
accuracy_dict['CumulativeAccuracy'][accuracy_scouts_index] += red_alliance_accuracy
157+
accuracy_dict['AutoAccuracy'][accuracy_scouts_index] += red_auto_accuracy
158+
accuracy_dict['TeleopAccuracy'][accuracy_scouts_index] += red_teleop_accuracy
159+
accuracy_dict['EndgameAccuracy'][accuracy_scouts_index] += red_endgame_accuracy
97160
accuracy_dict['NumberOfScoutedMatches'][accuracy_scouts_index] += 1
98161

99162
# Blue Alliance score from TBA
@@ -103,10 +166,16 @@ def generate_accuracy_table(self, member_name) -> DataFrame:
103166
if (match["comp_level"] + str(match["match_number"])) == match_key:
104167
blue_total_score = match["score_breakdown"]["blue"]["totalPoints"]
105168
blue_foul_score = match["score_breakdown"]["blue"]["foulPoints"]
169+
blue_auto_score = match["score_breakdown"]["blue"]["autoPoints"]
170+
blue_teleop_score = match["score_breakdown"]["blue"]["teleopPoints"]
171+
blue_endgame_score = match["score_breakdown"]["blue"]["endGameBargePoints"]
106172
blue_calculated_score = blue_total_score - blue_foul_score
107173
break
108174

109175
blue_scouting_alliance_score = 0
176+
blue_scouting_auto_score = 0
177+
blue_scouting_teleop_score = 0
178+
blue_scouting_endgame_score = 0
110179

111180
scouters_names_list_b = []
112181

@@ -116,30 +185,85 @@ def generate_accuracy_table(self, member_name) -> DataFrame:
116185
match_index_list = scouting_team_filter.index[scouting_team_filter[Queries.MATCH_KEY] == match_key].tolist()
117186
if len(match_index_list) != 0:
118187
match_index = match_index_list[0]
188+
189+
# Auto Accuracy Retrieval
190+
auto_coral_per_match = [
191+
self.calculated_stats.cycles_by_structure_per_match(int(team_key), Queries.AUTO_CORAL_L1).values,
192+
self.calculated_stats.cycles_by_structure_per_match(int(team_key), Queries.AUTO_CORAL_L2).values,
193+
self.calculated_stats.cycles_by_structure_per_match(int(team_key), Queries.AUTO_CORAL_L3).values,
194+
self.calculated_stats.cycles_by_structure_per_match(int(team_key), Queries.AUTO_CORAL_L4).values
195+
]
196+
for i in range(len(auto_coral_per_match)):
197+
blue_scouting_auto_score += auto_coral_per_match[i][match_index] * Criteria.AUTO_CORAL_POINTAGE[i + 1]
198+
algae_per_match = [
199+
self.calculated_stats.cycles_by_structure_per_match(int(team_key), Queries.AUTO_BARGE).values,
200+
self.calculated_stats.cycles_by_structure_per_match(int(team_key), Queries.AUTO_PROCESSOR).values
201+
]
202+
for i in range(len(algae_per_match)):
203+
blue_scouting_auto_score += algae_per_match[i][match_index] * Criteria.ALGAE_POINTAGE[i + 1]
204+
leave_points = self.calculated_stats.stat_per_match(int(team_key), Queries.LEFT_STARTING_ZONE, Criteria.BOOLEAN_CRITERIA).values
205+
blue_scouting_auto_score += (leave_points[match_index] * 2)
206+
207+
# Teleop Accuracy Retrieval
208+
teleop_coral_per_match = [
209+
self.calculated_stats.cycles_by_structure_per_match(int(team_key), Queries.TELEOP_CORAL_L1).values,
210+
self.calculated_stats.cycles_by_structure_per_match(int(team_key), Queries.TELEOP_CORAL_L2).values,
211+
self.calculated_stats.cycles_by_structure_per_match(int(team_key), Queries.TELEOP_CORAL_L3).values,
212+
self.calculated_stats.cycles_by_structure_per_match(int(team_key), Queries.TELEOP_CORAL_L4).values
213+
]
214+
for i in range(len(teleop_coral_per_match)):
215+
blue_scouting_teleop_score += teleop_coral_per_match[i][match_index] * Criteria.TELEOP_CORAL_POINTAGE[i + 1]
216+
teleop_algae_per_match = [
217+
self.calculated_stats.cycles_by_structure_per_match(int(team_key), Queries.TELEOP_BARGE).values,
218+
self.calculated_stats.cycles_by_structure_per_match(int(team_key), Queries.TELEOP_PROCESSOR).values
219+
]
220+
for i in range(len(teleop_algae_per_match)):
221+
blue_scouting_teleop_score += teleop_algae_per_match[i][match_index] * Criteria.ALGAE_POINTAGE[i + 1]
222+
223+
# Endgame Accuracy Retrieval
224+
park_points = self.calculated_stats.stat_per_match(int(team_key), Queries.PARKED_UNDER_BARGE, Criteria.BOOLEAN_CRITERIA).values
225+
climb_points = self.calculated_stats.stat_per_match(int(team_key), Queries.CLIMBED_CAGE, Criteria.CLIMBING_POINTAGE).values
226+
blue_scouting_endgame_score = park_points[match_index] * 2 + climb_points[match_index]
227+
228+
# Cumulative Accuracy Retrieval
119229
points_per_match = self.calculated_stats.points_contributed_by_match(int(team_key)).values
120230
blue_scouting_alliance_score += points_per_match[match_index]
231+
121232
scout_name = scouting_team_filter.iloc[match_index][Queries.SCOUT_ID]
122233
scouters_names_list_b.append(scout_name.title().replace(" ", ""))
123234

124235
self.calculated_stats.points_contributed_by_match(team_key)
125236
blue_scouting_alliance_score += self.calculated_stats.points_contributed_by_match(team_key).sum()
126237

127238
blue_alliance_accuracy = (1 - abs((blue_scouting_alliance_score-blue_calculated_score)/blue_calculated_score)) * 100
239+
blue_auto_accuracy = (1 - abs((blue_scouting_auto_score - blue_auto_score)/blue_auto_score)) * 100
240+
blue_teleop_accuracy = (1 - abs((blue_scouting_teleop_score - blue_teleop_score)/blue_teleop_score)) * 100
241+
blue_endgame_accuracy = (1 - abs((blue_scouting_endgame_score - blue_endgame_score)/blue_endgame_score)) * 100
128242

129243
scouters_names = ", ".join(scouters_names_list_b)
244+
130245
if member_name.replace(" ", "").lower() in scouters_names.lower():
131246
if scouters_names not in accuracy_dict['ScoutersNames']:
132247
accuracy_dict['ScoutersNames'].append(scouters_names)
133248
accuracy_dict['CumulativeAccuracy'].append(blue_alliance_accuracy)
249+
accuracy_dict['AutoAccuracy'].append(blue_auto_accuracy)
250+
accuracy_dict['TeleopAccuracy'].append(blue_teleop_accuracy)
251+
accuracy_dict['EndgameAccuracy'].append(blue_endgame_accuracy)
134252
accuracy_dict['NumberOfScoutedMatches'].append(1)
135253
else:
136254
accuracy_scouts_index = accuracy_dict['ScoutersNames'].index(scouters_names)
137255
accuracy_dict['CumulativeAccuracy'][accuracy_scouts_index] += blue_alliance_accuracy
256+
accuracy_dict['AutoAccuracy'][accuracy_scouts_index] += blue_auto_accuracy
257+
accuracy_dict['TeleopAccuracy'][accuracy_scouts_index] += blue_teleop_accuracy
258+
accuracy_dict['EndgameAccuracy'][accuracy_scouts_index] += blue_endgame_accuracy
138259
accuracy_dict['NumberOfScoutedMatches'][accuracy_scouts_index] += 1
139260

140261
df = pd.DataFrame(data={
141262
'Scouters': accuracy_dict['ScoutersNames'],
142263
'Average Accuracy %': [round(accuracy_dict['CumulativeAccuracy'][scouter_set]/accuracy_dict['NumberOfScoutedMatches'][scouter_set], 2) for scouter_set in range(len(accuracy_dict['NumberOfScoutedMatches']))],
264+
'Average Auto Accuracy %': [round(accuracy_dict['AutoAccuracy'][scouter_set]/accuracy_dict['NumberOfScoutedMatches'][scouter_set], 2) for scouter_set in range(len(accuracy_dict['NumberOfScoutedMatches']))],
265+
'Average Teleop Accuracy %': [round(accuracy_dict['TeleopAccuracy'][scouter_set]/accuracy_dict['NumberOfScoutedMatches'][scouter_set], 2) for scouter_set in range(len(accuracy_dict['NumberOfScoutedMatches']))],
266+
'Average Endgame Accuracy %': [round(accuracy_dict['EndgameAccuracy'][scouter_set]/accuracy_dict['NumberOfScoutedMatches'][scouter_set], 2) for scouter_set in range(len(accuracy_dict['NumberOfScoutedMatches']))],
143267
'NumberOfScoutedMatches': accuracy_dict['NumberOfScoutedMatches']
144268
})
145269

src/utils/constants.py

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,8 @@ class GeneralConstants:
5353

5454
class EventSpecificConstants:
5555
"""Constants specific to an event."""
56-
EVENT_CODE = "2025vabla"
57-
EVENT_NAME = "Duel on the Delaware"
56+
EVENT_CODE = "2025mdbob"
57+
EVENT_NAME = "Battle o Baltimore"
5858
URL = f"https://raw.githubusercontent.com/team4099/ScoutingAppData/main/{EVENT_CODE}_match_data.json"
5959
NOTE_SCOUTING_URL = f"https://raw.githubusercontent.com/team4099/ScoutingAppData/main/{EVENT_CODE}_qualitative_data.json"
6060
PIT_SCOUTING_URL = (
@@ -148,6 +148,28 @@ class Criteria:
148148
True: 1
149149
}
150150

151+
# Autogame Criteria
152+
AUTO_CORAL_POINTAGE = {
153+
1: 2,
154+
2: 3,
155+
3: 4,
156+
4: 5
157+
}
158+
159+
# Teleop Criteria
160+
TELEOP_CORAL_POINTAGE = {
161+
1: 3,
162+
2: 4,
163+
3: 6,
164+
4: 7
165+
}
166+
167+
# Algae Criteria
168+
ALGAE_POINTAGE = {
169+
1: 4,
170+
2: 6
171+
}
172+
151173
# Endgame Criteria
152174
CLIMBING_POINTAGE = {
153175
"No Climb": 2,

0 commit comments

Comments
 (0)