Show only continuing candidates in detailed transfers table

This commit is contained in:
RunasSudo 2021-09-12 00:20:49 +10:00
parent 2c3470b91c
commit 59f79444e8
Signed by: RunasSudo
GPG Key ID: 7234E476BF21C61A
4 changed files with 26 additions and 16 deletions

View File

@ -394,7 +394,7 @@ fn print_stage<N: Number>(stage_num: u32, state: &CountState<N>, opts: &STVOptio
if opts.transfers_detail { if opts.transfers_detail {
if let Some(tt) = &state.transfer_table { if let Some(tt) = &state.transfer_table {
println!(); println!();
println!("{}", tt.render_text(state, opts)); println!("{}", tt.render_text(opts));
} }
} }

View File

@ -311,7 +311,10 @@ where
// Reweight and transfer parcels // 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 (value_fraction, result) in parcels_next_prefs {
for (candidate, entry) in result.candidates.into_iter() { 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 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 { for parcel in parcels {
// Count next preferences // Count next preferences

View File

@ -28,6 +28,9 @@ use std::collections::HashMap;
/// Table describing vote transfers during a surplus distribution or exclusion /// Table describing vote transfers during a surplus distribution or exclusion
pub struct TransferTable<'e, N: Number> { pub struct TransferTable<'e, N: Number> {
/// Continuing candidates
pub hopefuls: Vec<&'e Candidate>,
/// Columns in the table /// Columns in the table
pub columns: Vec<TransferTableColumn<'e, N>>, pub columns: Vec<TransferTableColumn<'e, N>>,
@ -46,8 +49,9 @@ pub struct TransferTable<'e, N: Number> {
impl<'e, N: Number> TransferTable<'e, N> { impl<'e, N: Number> TransferTable<'e, N> {
/// Return a new [TransferTable] for an exclusion /// Return a new [TransferTable] for an exclusion
pub fn new_exclusion() -> Self { pub fn new_exclusion(hopefuls: Vec<&'e Candidate>) -> Self {
TransferTable { TransferTable {
hopefuls,
columns: Vec::new(), columns: Vec::new(),
total: TransferTableColumn { total: TransferTableColumn {
value_fraction: N::new(), value_fraction: N::new(),
@ -63,8 +67,9 @@ impl<'e, N: Number> TransferTable<'e, N> {
} }
/// Return a new [TransferTable] for a surplus distribution /// Return a new [TransferTable] for a surplus distribution
pub fn new_surplus(surplus: N, surpfrac: Option<N>, surpfrac_numer: Option<N>, surpfrac_denom: Option<N>) -> Self { pub fn new_surplus(hopefuls: Vec<&'e Candidate>, surplus: N, surpfrac: Option<N>, surpfrac_numer: Option<N>, surpfrac_denom: Option<N>) -> Self {
TransferTable { TransferTable {
hopefuls,
columns: Vec::new(), columns: Vec::new(),
total: TransferTableColumn { total: TransferTableColumn {
value_fraction: N::new(), value_fraction: N::new(),
@ -291,7 +296,7 @@ impl<'e, N: Number> TransferTable<'e, N> {
} }
/// Render table as [Table] /// Render table as [Table]
fn render(&self, state: &CountState<N>, opts: &STVOptions) -> Table { fn render(&self, opts: &STVOptions) -> Table {
let mut table = Table::new(); let mut table = Table::new();
set_table_format(&mut table); set_table_format(&mut table);
@ -299,12 +304,12 @@ impl<'e, N: Number> TransferTable<'e, N> {
let num_cols; let num_cols;
if show_transfers_per_ballot { if show_transfers_per_ballot {
num_cols = state.candidates.len() * 3 + 4; num_cols = self.columns.len() * 3 + 4;
} else { } else {
if self.surpfrac.is_none() { if self.surpfrac.is_none() {
num_cols = state.candidates.len() * 2 + 3; num_cols = self.columns.len() * 2 + 3;
} else { } 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 // Candidate rows
for candidate in state.election.candidates.iter() { for candidate in self.hopefuls.iter() {
let mut row = Vec::with_capacity(num_cols); let mut row = Vec::with_capacity(num_cols);
row.push(Cell::new(&candidate.name)); row.push(Cell::new(&candidate.name));
for column in self.columns.iter() { 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_in = N::new();
let mut gt_votes_out = 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) { if let Some(cell) = self.total.cells.get(candidate) {
gt_ballots += &cell.ballots; gt_ballots += &cell.ballots;
gt_votes_in += &cell.votes_in; gt_votes_in += &cell.votes_in;
@ -456,13 +461,13 @@ impl<'e, N: Number> TransferTable<'e, N> {
/// Render table as plain text /// Render table as plain text
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
pub fn render_text(&self, state: &CountState<N>, opts: &STVOptions) -> String { pub fn render_text(&self, opts: &STVOptions) -> String {
return self.render(state, opts).to_string(); return self.render(opts).to_string();
} }
/// Render table as HTML /// Render table as HTML
pub fn render_html(&self, state: &CountState<N>, opts: &STVOptions) -> String { pub fn render_html(&self, opts: &STVOptions) -> String {
return self.render(state, opts).to_string(); return self.render(opts).to_string();
} }
} }

View File

@ -177,7 +177,7 @@ macro_rules! impl_type {
/// Call [render_html](crate::stv::transfers::TransferTable::render_html) on [CountState::transfer_table] /// Call [render_html](crate::stv::transfers::TransferTable::render_html) on [CountState::transfer_table]
pub fn transfer_table_render_html(&self, opts: &STVOptions) -> Option<String> { pub fn transfer_table_render_html(&self, opts: &STVOptions) -> Option<String> {
return match &self.0.transfer_table { 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, None => None,
}; };
} }