Reduce unnecessary verbosity when only 1 vacancy
This commit is contained in:
parent
ab0ec44049
commit
cece60dd69
|
@ -1,5 +1,5 @@
|
||||||
/* OpenTally: Open-source election vote counting
|
/* OpenTally: Open-source election vote counting
|
||||||
* Copyright © 2021–2022 Lee Yingtong Li (RunasSudo)
|
* Copyright © 2021–2023 Lee Yingtong Li (RunasSudo)
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Affero General Public License as published by
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
@ -326,7 +326,11 @@ impl<'a, N: Number> CountState<'a, N> {
|
||||||
total_vote += &self.loss_fraction.votes;
|
total_vote += &self.loss_fraction.votes;
|
||||||
result.push_str(&format!("Total votes: {:.dps$}\n", total_vote, dps=opts.pp_decimals));
|
result.push_str(&format!("Total votes: {:.dps$}\n", total_vote, dps=opts.pp_decimals));
|
||||||
|
|
||||||
|
if self.election.seats == 1 {
|
||||||
|
result.push_str(&format!("Majority: {:.dps$}\n", self.quota.as_ref().unwrap(), dps=opts.pp_decimals));
|
||||||
|
} else {
|
||||||
result.push_str(&format!("Quota: {:.dps$}\n", self.quota.as_ref().unwrap(), dps=opts.pp_decimals));
|
result.push_str(&format!("Quota: {:.dps$}\n", self.quota.as_ref().unwrap(), dps=opts.pp_decimals));
|
||||||
|
}
|
||||||
if stv::should_show_vre(opts) {
|
if stv::should_show_vre(opts) {
|
||||||
if let Some(vre) = &self.vote_required_election {
|
if let Some(vre) = &self.vote_required_election {
|
||||||
result.push_str(&format!("Vote required for election: {:.dps$}\n", vre, dps=opts.pp_decimals));
|
result.push_str(&format!("Vote required for election: {:.dps$}\n", vre, dps=opts.pp_decimals));
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* OpenTally: Open-source election vote counting
|
/* OpenTally: Open-source election vote counting
|
||||||
* Copyright © 2021–2022 Lee Yingtong Li (RunasSudo)
|
* Copyright © 2021–2023 Lee Yingtong Li (RunasSudo)
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Affero General Public License as published by
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
@ -645,13 +645,18 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
if let ExclusionMethod::SingleStage = opts.exclusion {
|
if let ExclusionMethod::SingleStage = opts.exclusion {
|
||||||
if total_ballots == N::one() {
|
if state.election.seats == 1 {
|
||||||
|
// Ballots can never have nonzero value with a single winner
|
||||||
|
state.logger.log_literal(format!("Transferring {:.dps$} votes.", total_votes, dps=opts.pp_decimals));
|
||||||
|
} else if total_ballots == N::one() {
|
||||||
state.logger.log_literal(format!("Transferring 1 ballot, totalling {:.dps$} votes.", total_votes, dps=opts.pp_decimals));
|
state.logger.log_literal(format!("Transferring 1 ballot, totalling {:.dps$} votes.", total_votes, dps=opts.pp_decimals));
|
||||||
} else {
|
} else {
|
||||||
state.logger.log_literal(format!("Transferring {:.0} ballots, totalling {:.dps$} votes.", total_ballots, total_votes, dps=opts.pp_decimals));
|
state.logger.log_literal(format!("Transferring {:.0} ballots, totalling {:.dps$} votes.", total_ballots, total_votes, dps=opts.pp_decimals));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if total_ballots.is_zero() {
|
if state.election.seats == 1 {
|
||||||
|
state.logger.log_literal(format!("Transferring {:.dps$} votes, received at value {:.dps2$}.", total_votes, value.unwrap(), dps=opts.pp_decimals, dps2=max(opts.pp_decimals, 2)));
|
||||||
|
} else if total_ballots.is_zero() {
|
||||||
state.logger.log_literal(format!("Transferring 0 ballots, totalling {:.dps$} votes.", 0, dps=opts.pp_decimals));
|
state.logger.log_literal(format!("Transferring 0 ballots, totalling {:.dps$} votes.", 0, dps=opts.pp_decimals));
|
||||||
} else if total_ballots == N::one() {
|
} else if total_ballots == N::one() {
|
||||||
state.logger.log_literal(format!("Transferring 1 ballot, totalling {:.dps$} votes, received at value {:.dps2$}.", total_votes, value.unwrap(), dps=opts.pp_decimals, dps2=max(opts.pp_decimals, 2)));
|
state.logger.log_literal(format!("Transferring 1 ballot, totalling {:.dps$} votes, received at value {:.dps2$}.", total_votes, value.unwrap(), dps=opts.pp_decimals, dps2=max(opts.pp_decimals, 2)));
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* OpenTally: Open-source election vote counting
|
/* OpenTally: Open-source election vote counting
|
||||||
* Copyright © 2021–2022 Lee Yingtong Li (RunasSudo)
|
* Copyright © 2021–2023 Lee Yingtong Li (RunasSudo)
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Affero General Public License as published by
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
@ -73,13 +73,21 @@ pub fn init_results_table<N: Number>(election: &Election<N>, opts: &stv::STVOpti
|
||||||
if report_style == "votes_transposed" {
|
if report_style == "votes_transposed" {
|
||||||
result.push(String::from(r#"<tr class="info transfers"><td>Loss by fraction</td></tr>"#));
|
result.push(String::from(r#"<tr class="info transfers"><td>Loss by fraction</td></tr>"#));
|
||||||
result.push(String::from(r#"<tr class="info transfers"><td>Total</td></tr>"#));
|
result.push(String::from(r#"<tr class="info transfers"><td>Total</td></tr>"#));
|
||||||
|
if election.seats == 1 {
|
||||||
|
result.push(String::from(r#"<tr class="info transfers"><td>Majority</td></tr>"#));
|
||||||
|
} else {
|
||||||
result.push(String::from(r#"<tr class="info transfers"><td>Quota</td></tr>"#));
|
result.push(String::from(r#"<tr class="info transfers"><td>Quota</td></tr>"#));
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
result.push(String::from(r#"<tr class="info transfers"><td rowspan="2">Loss by fraction</td></tr>"#));
|
result.push(String::from(r#"<tr class="info transfers"><td rowspan="2">Loss by fraction</td></tr>"#));
|
||||||
result.push(String::from(r#"<tr class="info votes"></tr>"#));
|
result.push(String::from(r#"<tr class="info votes"></tr>"#));
|
||||||
result.push(String::from(r#"<tr class="info transfers"><td>Total</td></tr>"#));
|
result.push(String::from(r#"<tr class="info transfers"><td>Total</td></tr>"#));
|
||||||
|
if election.seats == 1 {
|
||||||
|
result.push(String::from(r#"<tr class="info transfers"><td>Majority</td></tr>"#));
|
||||||
|
} else {
|
||||||
result.push(String::from(r#"<tr class="info transfers"><td>Quota</td></tr>"#));
|
result.push(String::from(r#"<tr class="info transfers"><td>Quota</td></tr>"#));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if stv::should_show_vre(opts) {
|
if stv::should_show_vre(opts) {
|
||||||
result.push(String::from(r#"<tr class="info transfers"><td>Vote required for election</td></tr>"#));
|
result.push(String::from(r#"<tr class="info transfers"><td>Vote required for election</td></tr>"#));
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* OpenTally: Open-source election vote counting
|
/* OpenTally: Open-source election vote counting
|
||||||
* Copyright © 2021–2022 Lee Yingtong Li (RunasSudo)
|
* Copyright © 2021–2023 Lee Yingtong Li (RunasSudo)
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Affero General Public License as published by
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
@ -378,7 +378,11 @@ fn calculate_quota<N: Number>(state: &mut CountState<N>, opts: &STVOptions) {
|
||||||
|
|
||||||
// Calculate the total vote
|
// Calculate the total vote
|
||||||
let total_vote = state.total_vote();
|
let total_vote = state.total_vote();
|
||||||
|
if state.election.seats == 1 {
|
||||||
|
log.push_str(format!("{:.dps$} usable votes, so a majority is ", total_vote, dps=opts.pp_decimals).as_str());
|
||||||
|
} else {
|
||||||
log.push_str(format!("{:.dps$} usable votes, so the quota is ", total_vote, dps=opts.pp_decimals).as_str());
|
log.push_str(format!("{:.dps$} usable votes, so the quota is ", total_vote, dps=opts.pp_decimals).as_str());
|
||||||
|
}
|
||||||
|
|
||||||
let quota = total_to_quota(total_vote, state.election.seats, opts);
|
let quota = total_to_quota(total_vote, state.election.seats, opts);
|
||||||
|
|
||||||
|
@ -393,7 +397,11 @@ fn calculate_quota<N: Number>(state: &mut CountState<N>, opts: &STVOptions) {
|
||||||
|
|
||||||
// Calculate the active vote
|
// Calculate the active vote
|
||||||
let active_vote = state.active_vote();
|
let active_vote = state.active_vote();
|
||||||
log.push_str(format!("Active vote is {:.dps$}, so the quota is is ", active_vote, dps=opts.pp_decimals).as_str());
|
if state.election.seats == 1 {
|
||||||
|
log.push_str(format!("Active vote is {:.dps$}, so a majority is ", active_vote, dps=opts.pp_decimals).as_str());
|
||||||
|
} else {
|
||||||
|
log.push_str(format!("Active vote is {:.dps$}, so the quota is ", active_vote, dps=opts.pp_decimals).as_str());
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Calculate according to --quota ?
|
// TODO: Calculate according to --quota ?
|
||||||
let quota = active_vote / N::from(state.election.seats - state.num_elected + 1);
|
let quota = active_vote / N::from(state.election.seats - state.num_elected + 1);
|
||||||
|
@ -414,7 +422,11 @@ fn calculate_quota<N: Number>(state: &mut CountState<N>, opts: &STVOptions) {
|
||||||
|
|
||||||
// Calculate the total vote
|
// Calculate the total vote
|
||||||
let total_vote = state.total_vote();
|
let total_vote = state.total_vote();
|
||||||
|
if state.election.seats == 1 {
|
||||||
|
log.push_str(format!("{:.dps$} usable votes, so a majority is ", total_vote, dps=opts.pp_decimals).as_str());
|
||||||
|
} else {
|
||||||
log.push_str(format!("{:.dps$} usable votes, so the quota is reduced to ", total_vote, dps=opts.pp_decimals).as_str());
|
log.push_str(format!("{:.dps$} usable votes, so the quota is reduced to ", total_vote, dps=opts.pp_decimals).as_str());
|
||||||
|
}
|
||||||
|
|
||||||
let quota = total_to_quota(total_vote, state.election.seats, opts);
|
let quota = total_to_quota(total_vote, state.election.seats, opts);
|
||||||
|
|
||||||
|
@ -612,11 +624,19 @@ fn elect_hopefuls<'a, N: Number>(state: &mut CountState<'a, N>, opts: &STVOption
|
||||||
if cmp_quota_criterion(state.quota.as_ref().unwrap(), count_card, opts) {
|
if cmp_quota_criterion(state.quota.as_ref().unwrap(), count_card, opts) {
|
||||||
// Elected with a quota
|
// Elected with a quota
|
||||||
elected_on_quota = true;
|
elected_on_quota = true;
|
||||||
|
if state.election.seats == 1 {
|
||||||
|
state.logger.log_smart(
|
||||||
|
"{} reaches a majority and is elected.",
|
||||||
|
"{} reach a majority and are elected.", // This one is impossible
|
||||||
|
vec![candidate.name.as_str()]
|
||||||
|
);
|
||||||
|
} else {
|
||||||
state.logger.log_smart(
|
state.logger.log_smart(
|
||||||
"{} meets the quota and is elected.",
|
"{} meets the quota and is elected.",
|
||||||
"{} meet the quota and are elected.",
|
"{} meet the quota and are elected.",
|
||||||
vec![candidate.name.as_str()]
|
vec![candidate.name.as_str()]
|
||||||
);
|
);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// Elected with vote required
|
// Elected with vote required
|
||||||
elected_on_quota = false;
|
elected_on_quota = false;
|
||||||
|
@ -966,11 +986,19 @@ where
|
||||||
|
|
||||||
let names: Vec<&str> = excluded_candidates.iter().map(|c| c.name.as_str()).sorted().collect();
|
let names: Vec<&str> = excluded_candidates.iter().map(|c| c.name.as_str()).sorted().collect();
|
||||||
state.title = StageKind::ExclusionOf(excluded_candidates.clone());
|
state.title = StageKind::ExclusionOf(excluded_candidates.clone());
|
||||||
|
if state.election.seats == 1 {
|
||||||
|
state.logger.log_smart(
|
||||||
|
"No candidate has a majority, so {} is excluded.",
|
||||||
|
"No candidate has a majority, so {} are excluded.",
|
||||||
|
names
|
||||||
|
);
|
||||||
|
} else {
|
||||||
state.logger.log_smart(
|
state.logger.log_smart(
|
||||||
"No surpluses to distribute, so {} is excluded.",
|
"No surpluses to distribute, so {} is excluded.",
|
||||||
"No surpluses to distribute, so {} are excluded.",
|
"No surpluses to distribute, so {} are excluded.",
|
||||||
names
|
names
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if opts.early_bulk_elect {
|
if opts.early_bulk_elect {
|
||||||
// Determine if the proposed exclusion would enable a bulk election
|
// Determine if the proposed exclusion would enable a bulk election
|
||||||
|
|
Loading…
Reference in New Issue