Improve unit test and a bunch of I forget what.

This commit is contained in:
Olivia Brooks
2025-05-15 10:53:48 -04:00
parent fa183cbe91
commit b42203f9db
8 changed files with 57 additions and 48 deletions

View File

@@ -260,7 +260,7 @@
Play(
action: Unknown, // Original note: Same Failed Throw
down: Fourth,
terrain: Unknown,
terrain: None,
),
Quarter(Third),
Kickoff(Colorado),

View File

@@ -5,7 +5,7 @@ use std::{fmt, io};
pub enum LogFileError {
IOError(io::Error),
RonSpanned(ron::error::SpannedError),
TooManyTeams(usize),
TeamCount(usize),
}
impl fmt::Display for LogFileError {
@@ -13,7 +13,7 @@ impl fmt::Display for LogFileError {
match self {
Self::IOError(err) => write!(f, "{}", err),
Self::RonSpanned(err) => write!(f, "{}", err),
Self::TooManyTeams(err) => write!(f, "Expected two, found: {:?}", err),
Self::TeamCount(err) => write!(f, "Expected two, found: {:?}", err),
}
}
}

View File

@@ -1,5 +1,6 @@
use crate::{Down, Play, Quarter, TerrainState};
use serde::Deserialize;
use strum::EnumIter;
type Offence = Team;
@@ -86,7 +87,7 @@ impl Event {
}
}
#[derive(Debug, Deserialize, Clone, PartialEq, Default)]
#[derive(Debug, Deserialize, Clone, PartialEq, Default, EnumIter)]
pub enum Team {
ArizonaState,
#[deprecated(since = "0.2.0", note = "Team left the project.")]

View File

@@ -8,7 +8,7 @@ pub struct LogFile(pub Vec<Game>);
impl LogFile {
/// Returns the most common action for a given team.
pub fn most_frequent_action(&self, team: Team) -> Action {
pub fn most_frequent_action(&self, team: Team) -> (Action, usize) {
let mut most_freq_action = Action::default();
let mut frequency = usize::MIN;
let mut found = usize::MIN;
@@ -25,12 +25,12 @@ impl LogFile {
}
});
most_freq_action
(most_freq_action, frequency)
}
/// Returns the least common action for a given team.
/// This action has to have been played at least once.
pub fn least_frequent_action(&self, team: Team) -> Action {
pub fn least_frequent_action(&self, team: Team) -> (Action, usize) {
let mut least_freq_action = Action::default();
let mut frequency = usize::MAX;
let mut found = usize::MAX;
@@ -42,21 +42,20 @@ impl LogFile {
found = team_actions.clone().filter(|a| *a == action).count();
if (found != 0_usize) && (found < frequency) {
dbg!("hit");
frequency = found;
least_freq_action = action.to_owned();
}
});
least_freq_action
(least_freq_action, frequency)
}
pub fn most_effective_play(&self, team: Team) -> (Action, TerrainState) {
let deltas: Vec<Vec<i8>> = self
let deltas = self
.0
.iter()
.map(|game| game.deltas(team.to_owned()))
.collect();
.collect::<Vec<Vec<i8>>>();
let team_events: Vec<Vec<Event>> = self
.0
@@ -65,7 +64,7 @@ impl LogFile {
.collect::<Vec<TeamEvents>>()
.iter()
.map(|team_events| team_events.0.to_owned())
.collect::<Vec<Vec<Event>>>();
.collect();
let mut action_return = Action::Unknown;
let mut terrain_delta: u8 = 0;
@@ -87,15 +86,15 @@ impl LogFile {
}
}
event_idx += 1;
if (event_idx + 1) == game.len() {
event_idx = 0;
continue;
} else {
event_idx += 1;
}
}
game_idx += 1;
if (event_idx + 1) == game.len() {
event_idx = 0;
continue;
}
}
let sum: u8 = action_deltas.iter().sum::<i8>() as u8;
@@ -194,11 +193,11 @@ mod tests {
..Default::default()
}),
Event::Play(Play {
action: Action::Mesh,
action: Action::Curls,
..Default::default()
}),
Event::Play(Play {
action: Action::Curls,
action: Action::Mesh,
..Default::default()
}),
Event::Play(Play {
@@ -239,11 +238,11 @@ mod tests {
..Default::default()
}),
Event::Play(Play {
action: Action::Curls,
action: Action::SlotOut,
..Default::default()
}),
Event::Play(Play {
action: Action::SlotOut,
action: Action::Curls,
..Default::default()
}),
Event::Kickoff(Team::ArizonaState),

View File

@@ -37,7 +37,7 @@ impl Game {
if teams.len() == 2 || ignore.len() != 0 {
Ok(teams)
} else {
Err(error::LogFileError::TooManyTeams(teams.len()))
Err(error::LogFileError::TeamCount(teams.len()))
}
}
@@ -56,7 +56,13 @@ impl Game {
}
})
.collect();
let len = events.len() - 1;
let len = if events.len() == 0 {
return vec![0];
} else {
events.len() - 1
};
let mut idx: usize = 0;
let mut deltas: Vec<i8> = vec![];
@@ -326,7 +332,7 @@ impl Period {
#[derive(Debug, Deserialize, Clone, PartialEq)]
pub enum Flags {
ClockBleeding(Team),
ClockBleed(Team),
IgnoreActions,
IgnoreTeam(Team),
IgnoreScore,
@@ -400,15 +406,6 @@ mod tests {
};
let c = Game {
events: vec![
Event::Kickoff(Team::Nebraska),
Event::Turnover(Team::ArizonaState),
Event::Kickoff(Team::Nebraska),
],
..Default::default()
};
let d = Game {
flags: vec![Flags::IgnoreTeam(Team::Nebraska)],
events: vec![Event::Kickoff(Team::Nebraska)],
..Default::default()
@@ -416,8 +413,7 @@ mod tests {
assert!(a.teams().unwrap() == vec![Team::Nebraska, Team::ArizonaState]);
assert!(b.teams().is_err() == true);
assert!(c.teams().unwrap() == vec![Team::ArizonaState]);
assert!(d.teams().unwrap() == vec![]);
assert!(c.teams().unwrap() == vec![]);
}
#[test]

1
miller/Cargo.lock generated
View File

@@ -314,6 +314,7 @@ dependencies = [
"clap",
"gamelog",
"ratatui",
"strum 0.27.1",
]
[[package]]

View File

@@ -6,6 +6,7 @@ license = "MIT"
[dependencies]
ratatui = "0.29"
strum = "0.27"
[dependencies.clap]
version = "4.5"

View File

@@ -2,8 +2,9 @@ mod tui;
use clap::{ArgAction, Parser};
use core::panic;
use gamelog::{Action, Down, Flags, Key, LogFile, Team};
use gamelog::{Action, Down, Flags, Key, LogFile, Team, TerrainState};
use std::{io, path::PathBuf, sync::mpsc, thread};
use strum::IntoEnumIterator;
use tui::App;
#[derive(Debug, Parser)]
@@ -43,16 +44,14 @@ fn main() -> io::Result<()> {
TeamStats::new(Team::Iowa),
TeamStats::new(Team::Nebraska),
TeamStats::new(Team::Syracuse),
#[allow(deprecated)]
TeamStats::new(Team::SouthCarolina),
TeamStats::new(Team::TexasAnM),
];
// Work on knocking down the nesting here?
for game in log.0.iter() {
let teams = match game.teams() {
Ok(teams) => teams,
Err(_) => continue,
};
let teams = game.teams().unwrap();
for team in teams {
// Skip team if they are to be ignored this game.
@@ -89,6 +88,21 @@ fn main() -> io::Result<()> {
.penalties_per_game
.push(game.penalties(team.to_owned()));
}
for team in gamelog::Team::iter() {
let team_idx = stats
.iter()
.position(|stat| stat.team == team.to_owned())
.unwrap();
stats[team_idx].most_common_play = Some(log.most_frequent_action(team.to_owned()));
stats[team_idx].least_common_play =
Some(log.least_frequent_action(team.to_owned()));
/*
stats[team_idx].most_effective_play =
Some(log.most_effective_play(team.to_owned()));
*/
}
}
// :#? for pretty-printing.
@@ -127,14 +141,12 @@ struct TeamStats {
plays_per_game: Vec<usize>,
// Penalties
penalties_per_game: Vec<usize>,
// Score
points_per_quarter: Vec<u8>,
points_per_game: Vec<u8>,
// Biases
most_common_play: Option<Action>,
least_common_play: Option<Action>,
most_common_play: Option<(Action, usize)>,
least_common_play: Option<(Action, usize)>,
most_common_key: Option<Key>,
least_common_key: Option<Key>,
most_effective_play: Option<(Action, TerrainState)>,
// Traits
// Typical number of downs to achieve 10 yards.
time_to_first_down: Option<Down>,
@@ -150,12 +162,11 @@ impl TeamStats {
plays_per_quarter: vec![],
plays_per_game: vec![],
penalties_per_game: vec![],
points_per_quarter: vec![],
points_per_game: vec![],
most_common_play: None,
least_common_play: None,
most_common_key: None,
least_common_key: None,
most_effective_play: None,
time_to_first_down: None,
}
}