use crate::{ballot::{Ballot, BallotType}, header::Header}; #[derive(Debug)] pub struct Counter { pub header: Header, pub ballots: Vec, } impl Counter { pub fn new(mut csv: quick_csv::Csv) -> Result> { let header = Header::parse(csv.next().ok_or("csv header missing")??)?; let mut ballots = Vec::new(); for row in csv { ballots.push(Ballot::parse(row?, &header)?.to_candidate_ballot(&header)); } Ok(Counter { header, ballots, }) } pub fn count_primaries(&self, ty: BallotType, running: &[bool]) -> Vec where T: num::Num + Copy + std::ops::AddAssign { let mut scores = vec![T::zero(); running.len()]; for ballot in self.ballots.iter() { if ballot.ty != ty { continue; } for &id in ballot.votes.iter() { if !running[id] { continue; } scores[id] += T::one(); break; } } scores } pub fn count_all_with_powers_of_2(&self, ty: BallotType, running: &[bool]) -> Vec { let mut scores = vec![0.0; running.len()]; for ballot in self.ballots.iter() { if ballot.ty != ty { continue; } let mut m = 0.5; for &id in ballot.votes.iter() { if !running[id] { continue; } scores[id] += m; m *= 0.5; } } scores } }