From 59f79444e85ab76b42e67d930ad4d9bef685fd26 Mon Sep 17 00:00:00 2001 From: RunasSudo Date: Sun, 12 Sep 2021 00:20:49 +1000 Subject: [PATCH] Show only continuing candidates in detailed transfers table --- src/cli/stv.rs | 2 +- src/stv/gregory/mod.rs | 9 +++++++-- src/stv/gregory/transfers.rs | 29 +++++++++++++++++------------ src/stv/wasm.rs | 2 +- 4 files changed, 26 insertions(+), 16 deletions(-) diff --git a/src/cli/stv.rs b/src/cli/stv.rs index fd2255b..7a5bf11 100644 --- a/src/cli/stv.rs +++ b/src/cli/stv.rs @@ -394,7 +394,7 @@ fn print_stage(stage_num: u32, state: &CountState, opts: &STVOptio if opts.transfers_detail { if let Some(tt) = &state.transfer_table { println!(); - println!("{}", tt.render_text(state, opts)); + println!("{}", tt.render_text(opts)); } } diff --git a/src/stv/gregory/mod.rs b/src/stv/gregory/mod.rs index 46724df..0488bb4 100644 --- a/src/stv/gregory/mod.rs +++ b/src/stv/gregory/mod.rs @@ -311,7 +311,10 @@ where // Reweight and transfer parcels - let mut transfer_table = TransferTable::new_surplus(surplus.clone(), surplus_fraction.clone(), surplus_numer.clone(), surplus_denom.clone()); + let mut transfer_table = TransferTable::new_surplus( + state.election.candidates.iter().filter(|c| state.candidates[c].state == CandidateState::Hopeful || state.candidates[c].state == CandidateState::Guarded).collect(), + surplus.clone(), surplus_fraction.clone(), surplus_numer.clone(), surplus_denom.clone() + ); for (value_fraction, result) in parcels_next_prefs { for (candidate, entry) in result.candidates.into_iter() { @@ -563,7 +566,9 @@ where let value = match parcels.first() { Some(p) => Some(p.value_fraction.clone()), _ => None }; - let mut transfer_table = TransferTable::new_exclusion(); + let mut transfer_table = TransferTable::new_exclusion( + state.election.candidates.iter().filter(|c| state.candidates[c].state == CandidateState::Hopeful || state.candidates[c].state == CandidateState::Guarded).collect(), + ); for parcel in parcels { // Count next preferences diff --git a/src/stv/gregory/transfers.rs b/src/stv/gregory/transfers.rs index 2ce1446..038b876 100644 --- a/src/stv/gregory/transfers.rs +++ b/src/stv/gregory/transfers.rs @@ -28,6 +28,9 @@ use std::collections::HashMap; /// Table describing vote transfers during a surplus distribution or exclusion pub struct TransferTable<'e, N: Number> { + /// Continuing candidates + pub hopefuls: Vec<&'e Candidate>, + /// Columns in the table pub columns: Vec>, @@ -46,8 +49,9 @@ pub struct TransferTable<'e, N: Number> { impl<'e, N: Number> TransferTable<'e, N> { /// Return a new [TransferTable] for an exclusion - pub fn new_exclusion() -> Self { + pub fn new_exclusion(hopefuls: Vec<&'e Candidate>) -> Self { TransferTable { + hopefuls, columns: Vec::new(), total: TransferTableColumn { value_fraction: N::new(), @@ -63,8 +67,9 @@ impl<'e, N: Number> TransferTable<'e, N> { } /// Return a new [TransferTable] for a surplus distribution - pub fn new_surplus(surplus: N, surpfrac: Option, surpfrac_numer: Option, surpfrac_denom: Option) -> Self { + pub fn new_surplus(hopefuls: Vec<&'e Candidate>, surplus: N, surpfrac: Option, surpfrac_numer: Option, surpfrac_denom: Option) -> Self { TransferTable { + hopefuls, columns: Vec::new(), total: TransferTableColumn { value_fraction: N::new(), @@ -291,7 +296,7 @@ impl<'e, N: Number> TransferTable<'e, N> { } /// Render table as [Table] - fn render(&self, state: &CountState, opts: &STVOptions) -> Table { + fn render(&self, opts: &STVOptions) -> Table { let mut table = Table::new(); set_table_format(&mut table); @@ -299,12 +304,12 @@ impl<'e, N: Number> TransferTable<'e, N> { let num_cols; if show_transfers_per_ballot { - num_cols = state.candidates.len() * 3 + 4; + num_cols = self.columns.len() * 3 + 4; } else { if self.surpfrac.is_none() { - num_cols = state.candidates.len() * 2 + 3; + num_cols = self.columns.len() * 2 + 3; } else { - num_cols = state.candidates.len() * 2 + 4; + num_cols = self.columns.len() * 2 + 4; } } @@ -329,7 +334,7 @@ impl<'e, N: Number> TransferTable<'e, N> { // -------------- // Candidate rows - for candidate in state.election.candidates.iter() { + for candidate in self.hopefuls.iter() { let mut row = Vec::with_capacity(num_cols); row.push(Cell::new(&candidate.name)); for column in self.columns.iter() { @@ -432,7 +437,7 @@ impl<'e, N: Number> TransferTable<'e, N> { let mut gt_votes_in = N::new(); let mut gt_votes_out = N::new(); - for candidate in state.election.candidates.iter() { + for candidate in self.hopefuls.iter() { if let Some(cell) = self.total.cells.get(candidate) { gt_ballots += &cell.ballots; gt_votes_in += &cell.votes_in; @@ -456,13 +461,13 @@ impl<'e, N: Number> TransferTable<'e, N> { /// Render table as plain text #[cfg(not(target_arch = "wasm32"))] - pub fn render_text(&self, state: &CountState, opts: &STVOptions) -> String { - return self.render(state, opts).to_string(); + pub fn render_text(&self, opts: &STVOptions) -> String { + return self.render(opts).to_string(); } /// Render table as HTML - pub fn render_html(&self, state: &CountState, opts: &STVOptions) -> String { - return self.render(state, opts).to_string(); + pub fn render_html(&self, opts: &STVOptions) -> String { + return self.render(opts).to_string(); } } diff --git a/src/stv/wasm.rs b/src/stv/wasm.rs index a5a3814..02ca290 100644 --- a/src/stv/wasm.rs +++ b/src/stv/wasm.rs @@ -177,7 +177,7 @@ macro_rules! impl_type { /// Call [render_html](crate::stv::transfers::TransferTable::render_html) on [CountState::transfer_table] pub fn transfer_table_render_html(&self, opts: &STVOptions) -> Option { return match &self.0.transfer_table { - Some(tt) => Some(tt.render_html(&self.0, &opts.0)), // TODO + Some(tt) => Some(tt.render_html(&opts.0)), // TODO None => None, }; }