Report when and how ties are broken

This commit is contained in:
RunasSudo 2021-06-13 00:56:18 +10:00
parent daeb706b44
commit 266d8e2495
Signed by: RunasSudo
GPG Key ID: 7234E476BF21C61A
3 changed files with 21 additions and 7 deletions

View File

@ -81,8 +81,11 @@ impl<'a> SmartLogEntry<'a> {
} else if self.data.len() == 1 {
return String::from(self.template1).replace("{}", self.data.first().unwrap());
} else {
let rendered_list = format!("{} and {}", self.data[0..self.data.len()-1].join(", "), self.data.last().unwrap());
return String::from(self.template2).replace("{}", &rendered_list);
return String::from(self.template2).replace("{}", &smart_join(&self.data));
}
}
}
pub fn smart_join(data: &Vec<&str>) -> String {
return format!("{} and {}", data[0..data.len()-1].join(", "), data.last().unwrap());
}

View File

@ -1243,7 +1243,7 @@ fn finished_before_stage<N: Number>(state: &CountState<N>) -> bool {
return false;
}
fn choose_highest<'c, N: Number>(state: &CountState<N>, opts: &STVOptions, candidates: Vec<&'c Candidate>) -> Result<&'c Candidate, STVError> {
fn choose_highest<'c, N: Number>(state: &mut CountState<N>, opts: &STVOptions, candidates: Vec<&'c Candidate>) -> Result<&'c Candidate, STVError> {
for strategy in opts.ties.iter() {
match strategy.choose_highest(state, &candidates) {
Ok(c) => {
@ -1261,7 +1261,7 @@ fn choose_highest<'c, N: Number>(state: &CountState<N>, opts: &STVOptions, candi
panic!("Unable to resolve tie");
}
fn choose_lowest<'c, N: Number>(state: &CountState<N>, opts: &STVOptions, candidates: Vec<&'c Candidate>) -> Result<&'c Candidate, STVError> {
fn choose_lowest<'c, N: Number>(state: &mut CountState<N>, opts: &STVOptions, candidates: Vec<&'c Candidate>) -> Result<&'c Candidate, STVError> {
for strategy in opts.ties.iter() {
match strategy.choose_lowest(state, &candidates) {
Ok(c) => {

View File

@ -16,6 +16,7 @@
*/
use crate::election::{Candidate, CountState};
use crate::logger::smart_join;
use crate::numbers::Number;
use crate::stv::STVError;
@ -43,7 +44,7 @@ impl<'s> TieStrategy<'s> {
}.to_string()
}
pub fn choose_highest<'c, N: Number>(&self, state: &CountState<N>, candidates: &Vec<&'c Candidate>) -> Result<&'c Candidate, STVError> {
pub fn choose_highest<'c, N: Number>(&self, state: &mut CountState<N>, candidates: &Vec<&'c Candidate>) -> Result<&'c Candidate, STVError> {
match self {
Self::Forwards => {
let mut candidates = candidates.clone();
@ -55,6 +56,7 @@ impl<'s> TieStrategy<'s> {
if state.forwards_tiebreak.as_ref().unwrap().get(candidates[0]).unwrap() == state.forwards_tiebreak.as_ref().unwrap().get(candidates[1]).unwrap() {
return Err(STVError::UnresolvedTie);
} else {
state.logger.log_literal(format!("Tie between {} broken forwards.", smart_join(&candidates.iter().map(|c| c.name.as_str()).collect())));
return Ok(candidates[0]);
}
}
@ -67,17 +69,24 @@ impl<'s> TieStrategy<'s> {
if state.backwards_tiebreak.as_ref().unwrap().get(candidates[0]).unwrap() == state.backwards_tiebreak.as_ref().unwrap().get(candidates[1]).unwrap() {
return Err(STVError::UnresolvedTie);
} else {
state.logger.log_literal(format!("Tie between {} broken backwards.", smart_join(&candidates.iter().map(|c| c.name.as_str()).collect())));
return Ok(candidates[0]);
}
}
Self::Random(_seed) => { todo!() }
Self::Prompt => {
return prompt(candidates);
match prompt(candidates) {
Ok(c) => {
state.logger.log_literal(format!("Tie between {} broken by manual intervention.", smart_join(&candidates.iter().map(|c| c.name.as_str()).collect())));
return Ok(c);
}
Err(e) => { return Err(e); }
}
}
}
}
pub fn choose_lowest<'c, N: Number>(&self, state: &CountState<N>, candidates: &Vec<&'c Candidate>) -> Result<&'c Candidate, STVError> {
pub fn choose_lowest<'c, N: Number>(&self, state: &mut CountState<N>, candidates: &Vec<&'c Candidate>) -> Result<&'c Candidate, STVError> {
match self {
Self::Forwards => {
let mut candidates = candidates.clone();
@ -88,6 +97,7 @@ impl<'s> TieStrategy<'s> {
if state.forwards_tiebreak.as_ref().unwrap().get(candidates[0]).unwrap() == state.forwards_tiebreak.as_ref().unwrap().get(candidates[1]).unwrap() {
return Err(STVError::UnresolvedTie);
} else {
state.logger.log_literal(format!("Tie between {} broken forwards.", smart_join(&candidates.iter().map(|c| c.name.as_str()).collect())));
return Ok(candidates[0]);
}
}
@ -100,6 +110,7 @@ impl<'s> TieStrategy<'s> {
if state.backwards_tiebreak.as_ref().unwrap().get(candidates[0]).unwrap() == state.backwards_tiebreak.as_ref().unwrap().get(candidates[1]).unwrap() {
return Err(STVError::UnresolvedTie);
} else {
state.logger.log_literal(format!("Tie between {} broken backwards.", smart_join(&candidates.iter().map(|c| c.name.as_str()).collect())));
return Ok(candidates[0]);
}
}