ballot-counter/src/counter.rs

65 lines
1.3 KiB
Rust

use crate::{ballot::{Ballot, BallotType}, header::Header};
#[derive(Debug)]
pub struct Counter {
pub header: Header,
pub ballots: Vec<Ballot>,
}
impl Counter {
pub fn new<T: std::io::BufRead>(mut csv: quick_csv::Csv<T>) -> Result<Self, Box<dyn std::error::Error>> {
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<T>(&self, ty: BallotType, running: &[bool]) -> Vec<T> 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<f64> {
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
}
}