Fix logic error where loss by fraction not updated in multi-stage exclusions

This commit is contained in:
RunasSudo 2021-06-04 22:54:26 +10:00
parent ceba059c53
commit 830362416d
Signed by: RunasSudo
GPG Key ID: 7234E476BF21C61A
2 changed files with 12 additions and 7 deletions

View File

@ -825,8 +825,6 @@ where
let count_card = state.candidates.get_mut(excluded_candidate).unwrap(); let count_card = state.candidates.get_mut(excluded_candidate).unwrap();
checksum -= &result.total_votes; checksum -= &result.total_votes;
count_card.transfer(&-result.total_votes); count_card.transfer(&-result.total_votes);
// By definition, there is no loss by fraction
} }
} }
@ -837,14 +835,14 @@ where
count_card.transfers = -count_card.votes.clone(); count_card.transfers = -count_card.votes.clone();
count_card.votes = N::new(); count_card.votes = N::new();
// Update loss by fraction
state.loss_fraction.transfer(&-checksum);
if let ExclusionMethod::SingleStage = opts.exclusion { if let ExclusionMethod::SingleStage = opts.exclusion {
} else { } else {
state.logger.log_literal("Exclusion complete.".to_string()); state.logger.log_literal("Exclusion complete.".to_string());
} }
} }
// Update loss by fraction
state.loss_fraction.transfer(&-checksum);
} }
fn finished_before_stage<N: Number>(state: &CountState<N>) -> bool { fn finished_before_stage<N: Number>(state: &CountState<N>) -> bool {

View File

@ -80,12 +80,19 @@ where
fn validate_stage<N: Number>(idx: usize, state: &CountState<N>, records: &Vec<StringRecord>) { fn validate_stage<N: Number>(idx: usize, state: &CountState<N>, records: &Vec<StringRecord>) {
println!("Col at idx {}", idx); println!("Col at idx {}", idx);
// Validate candidate votes
//let mut candidate_votes: Vec<N> = records.iter().skip(2).map(|r| N::parse(&r[idx*2 + 1])).collect();
let mut candidate_votes: Vec<N> = records.iter().skip(2).map(|r| N::from(r[idx*2 + 1].parse::<f64>().expect("Syntax Error"))).collect(); let mut candidate_votes: Vec<N> = records.iter().skip(2).map(|r| N::from(r[idx*2 + 1].parse::<f64>().expect("Syntax Error"))).collect();
// Validate exhausted/LBF
let lbf_votes = candidate_votes.pop().unwrap();
let exhausted_votes = candidate_votes.pop().unwrap();
assert!(state.exhausted.votes == exhausted_votes);
assert!(state.loss_fraction.votes == lbf_votes);
// Remove exhausted/LBF rows // Remove exhausted/LBF rows
candidate_votes.truncate(candidate_votes.len() - 2); candidate_votes.truncate(candidate_votes.len() - 2);
// Validate candidate votes
for (candidate, votes) in state.election.candidates.iter().zip(candidate_votes) { for (candidate, votes) in state.election.candidates.iter().zip(candidate_votes) {
let count_card = state.candidates.get(candidate).unwrap(); let count_card = state.candidates.get(candidate).unwrap();
assert!(count_card.votes == votes, "Failed to validate votes for candidate {}. Expected {:}, got {:}", candidate.name, votes, count_card.votes); assert!(count_card.votes == votes, "Failed to validate votes for candidate {}. Expected {:}, got {:}", candidate.name, votes, count_card.votes);