Complete implementation and tests for NSW Local Government STV

This commit is contained in:
RunasSudo 2022-03-23 01:51:38 +11:00
parent c5d6b8d460
commit 8af0fa1178
No known key found for this signature in database
GPG Key ID: 7234E476BF21C61A
14 changed files with 8086 additions and 42 deletions

View File

@ -13,17 +13,17 @@ The preset dropdown allows you to choose from a hardcoded list of preloaded STV
| • Meek STV (2006) | Operates according to Hill's 2006 revisions ([*Voting Matters* 2006;(22):710](http://www.votingmatters.org.uk/ISSUE22/I22P2.pdf)). This is the algorithm referred to in OpenSTV/OpaVote as Meek STV, and forms the basis of New Zealand's Meek STV rules. | [E1] | ✓ | | • Meek STV (2006) | Operates according to Hill's 2006 revisions ([*Voting Matters* 2006;(22):710](http://www.votingmatters.org.uk/ISSUE22/I22P2.pdf)). This is the algorithm referred to in OpenSTV/OpaVote as Meek STV, and forms the basis of New Zealand's Meek STV rules. | [E1] | ✓ |
| • Meek STV (New Zealand) | Operates according to Schedule 1A of the [*Local Electoral Regulations 2001*](https://www.legislation.govt.nz/regulation/public/2001/0145/latest/DLM57125.html). | [E1] | ✓ | | • Meek STV (New Zealand) | Operates according to Schedule 1A of the [*Local Electoral Regulations 2001*](https://www.legislation.govt.nz/regulation/public/2001/0145/latest/DLM57125.html). | [E1] | ✓ |
| Australian Senate STV | Rules from the [*Commonwealth Electoral Act 1918*](https://www.legislation.gov.au/Details/C2020C00400/Html/Text#_Toc59107700), using the unweighted inclusive Gregory method. | [E2] [E3] [E4] | ✓ | | Australian Senate STV | Rules from the [*Commonwealth Electoral Act 1918*](https://www.legislation.gov.au/Details/C2020C00400/Html/Text#_Toc59107700), using the unweighted inclusive Gregory method. | [E2] [E3] [E4] | ✓ |
| NSW Local Government STV | Rules from the [*Local Government (General) Regulation 2021*](https://legislation.nsw.gov.au/view/html/inforce/current/sl-2021-0460), using the weighted inclusive Gregory method. | [E2] | | | NSW Local Government STV | Rules from the [*Local Government (General) Regulation 2021*](https://legislation.nsw.gov.au/view/html/inforce/current/sl-2021-0460), using the weighted inclusive Gregory method. | [E2] [E5] | |
| Western Australia STV | Rules from the [*Electoral Act 1907* (WA)](https://www.legislation.wa.gov.au/legislation/prod/filestore.nsf/FileURL/mrdoc_29498.pdf/$FILE/Electoral%20Act%201907%20-%20[17-a0-06].pdf), using the weighted inclusive Gregory method. | [E2] [E3] | | | Western Australia STV | Rules from the [*Electoral Act 1907* (WA)](https://www.legislation.wa.gov.au/legislation/prod/filestore.nsf/FileURL/mrdoc_29498.pdf/$FILE/Electoral%20Act%201907%20-%20[17-a0-06].pdf), using the weighted inclusive Gregory method. | [E2] [E3] | |
| Australian Capital Territory STV | Rules from the [*Electoral Act 1992* (ACT)](https://www.legislation.act.gov.au/View/a/1992-71/current/PDF/1992-71.PDF), using the exclusive Gregory method. | | ✓ | | Australian Capital Territory STV | Rules from the [*Electoral Act 1992* (ACT)](https://www.legislation.act.gov.au/View/a/1992-71/current/PDF/1992-71.PDF), using the exclusive Gregory method. | | ✓ |
| Minneapolis STV | Rules from chapter 167 of the [*Minneapolis Code of Ordinances*](https://library.municode.com/mn/minneapolis/codes/code_of_ordinances?nodeId=COOR_TIT8.5EL_CH167MUELRUCO), using the weighted inclusive Gregory method. | [E5] | ✓ | | Minneapolis STV | Rules from chapter 167 of the [*Minneapolis Code of Ordinances*](https://library.municode.com/mn/minneapolis/codes/code_of_ordinances?nodeId=COOR_TIT8.5EL_CH167MUELRUCO), using the weighted inclusive Gregory method. | [E6] | ✓ |
| Cambridge STV | Rules in force in Cambridge, Massachusetts, using random sample transfers. These rules are derived from the [former chapter 54A of the Massachusetts General Laws](https://www.cambridgema.gov/-/media/Files/electioncommission/massachusettsgenerallawschapter54a.pdf), but have by regulation been modified to incorporate the procedures set out in Article IX of the former [1938 Charter of the City of Cincinnati](https://catalog.hathitrust.org/Record/001754258). See also [here](https://web.archive.org/web/20081118104049/http://www.fairvote.org/media/1993countmanual.pdf). | | ✓ | | Cambridge STV | Rules in force in Cambridge, Massachusetts, using random sample transfers. These rules are derived from the [former chapter 54A of the Massachusetts General Laws](https://www.cambridgema.gov/-/media/Files/electioncommission/massachusettsgenerallawschapter54a.pdf), but have by regulation been modified to incorporate the procedures set out in Article IX of the former [1938 Charter of the City of Cincinnati](https://catalog.hathitrust.org/Record/001754258). See also [here](https://web.archive.org/web/20081118104049/http://www.fairvote.org/media/1993countmanual.pdf). | | ✓ |
| Dáil Éireann STV | Rules from the [*Electoral Act 1992* (Ireland)](http://www.irishstatutebook.ie/eli/1992/act/23/enacted/en/print), using stratified random sample transfers. | [E4] [E6] | ✓ | | Dáil Éireann STV | Rules from the [*Electoral Act 1992* (Ireland)](http://www.irishstatutebook.ie/eli/1992/act/23/enacted/en/print), using stratified random sample transfers. | [E4] [E7] | ✓ |
| [Wright STV](https://www.aph.gov.au/Parliamentary_Business/Committees/House_of_Representatives_Committees?url=em/elect07/subs/sub051.1.pdf) | Rules proposed by Anthony van der Craats designed for computer counting, involving reset and re-iteration of the count after each candidate exclusion. | | ✓ | | [Wright STV](https://www.aph.gov.au/Parliamentary_Business/Committees/House_of_Representatives_Committees?url=em/elect07/subs/sub051.1.pdf) | Rules proposed by Anthony van der Craats designed for computer counting, involving reset and re-iteration of the count after each candidate exclusion. | | ✓ |
| [PRSA 1977](https://www.prsa.org.au/rule1977.htm) | Simple rules designed for hand counting, using the exclusive Gregory method, with counting performed in thousandths of a vote. | | ✓ | | [PRSA 1977](https://www.prsa.org.au/rule1977.htm) | Simple rules designed for hand counting, using the exclusive Gregory method, with counting performed in thousandths of a vote. | | ✓ |
| [ERS97](https://www.electoral-reform.org.uk/latest-news-and-research/publications/how-to-conduct-an-election-by-the-single-transferable-vote-3rd-edition/) | More complex rules designed for hand counting, using the exclusive Gregory method. | [E7] | ✓ | | [ERS97](https://www.electoral-reform.org.uk/latest-news-and-research/publications/how-to-conduct-an-election-by-the-single-transferable-vote-3rd-edition/) | More complex rules designed for hand counting, using the exclusive Gregory method. | [E8] | ✓ |
| • ERS76 | Former rules from the 1976 2nd edition. | [E7] [E8] | ✓ | | • ERS76 | Former rules from the 1976 2nd edition. | [E8] [E9] | ✓ |
| • ERS73 | Former rules from the 1973 1st edition. | [E7] [E8] | | | • ERS73 | Former rules from the 1973 1st edition. | [E8] [E9] | |
| Church of England | Rules from the Church of England [*Single Transferable Vote Rules 2020*](https://www.churchofengland.org/sites/default/files/2020-02/STV%20Rules%202020%20-%20final.pdf), similar to ERS73. | | ✓ | | Church of England | Rules from the Church of England [*Single Transferable Vote Rules 2020*](https://www.churchofengland.org/sites/default/files/2020-02/STV%20Rules%202020%20-%20final.pdf), similar to ERS73. | | ✓ |
Exceptions: Exceptions:
@ -32,10 +32,11 @@ Exceptions:
* [E2] When breaking ties backwards, OpenTally selects the candidate who had more/fewer votes at the last stage when *any* tied candidate had more/fewer votes, rather than the method described in the legislation (when each all had unequal votes). The OpenTally developers regard the method described in the legislation as a defect. For an independent discussion, see <a href="https://dl.acm.org/doi/10.1145/3014812.3014837">Conway et al.</a> * [E2] When breaking ties backwards, OpenTally selects the candidate who had more/fewer votes at the last stage when *any* tied candidate had more/fewer votes, rather than the method described in the legislation (when each all had unequal votes). The OpenTally developers regard the method described in the legislation as a defect. For an independent discussion, see <a href="https://dl.acm.org/doi/10.1145/3014812.3014837">Conway et al.</a>
* [E3] A tie between 2 candidates for the final vacancy will be broken backwards then at random, rather than the method described in the legislation. * [E3] A tie between 2 candidates for the final vacancy will be broken backwards then at random, rather than the method described in the legislation.
* [E4] Bulk exclusion is not performed, as the prescribed rules are more conservative than OpenTally's. See also the section on *Bulk exclusion* for further discussion. * [E4] Bulk exclusion is not performed, as the prescribed rules are more conservative than OpenTally's. See also the section on *Bulk exclusion* for further discussion.
* [E5] The mathematically eliminated by the sum of all ranked-choice votes comparison is not implemented. * [E5] The legislation specifies that, when rounding subtransfers, surpluses are to be transferred by value while exclusions are to be transferred by value and source. One imagines this differing treatment was a drafting oversight, and the New South Wales Electoral Commission has instead applied the by value and source method for both in practice, which OpenTally follows. See also <a href="https://github.com/AndrewConway/ConcreteSTV/blob/main/nsw/NSWLocalCouncilLegislation2021Commentary.md">Conway</a>.
* [E6] The quarter of a quota provision is disregarded when determining whether to defer surplus distributions. * [E6] The mathematically eliminated by the sum of all ranked-choice votes comparison is not implemented.
* [E7] No distinction is made between stages and substages (during exclusion). This affects only the numbering of stages and not the result. * [E7] The quarter of a quota provision is disregarded when determining whether to defer surplus distributions.
* [E8] By default, the quota is always calculated to 2 decimal places. For full ERS76 (ERS73) compliance, set *Round quota to 0 d.p.* when the quota is more than 100 (100 or more). * [E8] No distinction is made between stages and substages (during exclusion). This affects only the numbering of stages and not the result.
* [E9] By default, the quota is always calculated to 2 decimal places. For full ERS76 (ERS73) compliance, set *Round quota to 0 d.p.* when the quota is more than 100 (100 or more).
For details of validation, see [validation.md](https://yingtongli.me/git/OpenTally/about/docs/validation.md). For details of validation, see [validation.md](https://yingtongli.me/git/OpenTally/about/docs/validation.md).
@ -278,6 +279,7 @@ When *Surplus method* is set to a Gregory method, this option allows you to spec
* *Single step* (default): The total value of all votes expressing a next available preference for that candidate is multiplied by the surplus fraction. The product (rounded if requested) is credited to that candidate. * *Single step* (default): The total value of all votes expressing a next available preference for that candidate is multiplied by the surplus fraction. The product (rounded if requested) is credited to that candidate.
* *By value*: The votes expressing a next available preference for that candidate are further divided according to value. For each group of votes at a particular value, the total value of all such votes is multiplied by the surplus fraction. The product (rounded if requested) is credited to that candidate. * *By value*: The votes expressing a next available preference for that candidate are further divided according to value. For each group of votes at a particular value, the total value of all such votes is multiplied by the surplus fraction. The product (rounded if requested) is credited to that candidate.
* *By value and source*: The votes are further divided according to value, and according to who they were received from by the elected/excluded candidate. Then as per *By value*.
* *Per ballot*: For each individual vote expressing a next available preference for that candidate, the value of the vote is multiplied by the surplus fraction. The product (rounded if requested) is credited to that candidate. * *Per ballot*: For each individual vote expressing a next available preference for that candidate, the value of the vote is multiplied by the surplus fraction. The product (rounded if requested) is credited to that candidate.
This option affects the result only as far as rounding (due to use of fixed-precision/floating-point arithmetic, or an explicit rounding option) is concerned. This option affects the result only as far as rounding (due to use of fixed-precision/floating-point arithmetic, or an explicit rounding option) is concerned.

View File

@ -299,6 +299,7 @@
<select id="selSumTransfers"> <select id="selSumTransfers">
<option value="single_step" selected>Single step</option> <option value="single_step" selected>Single step</option>
<option value="by_value">By value</option> <option value="by_value">By value</option>
<option value="by_value_and_source">By value and source</option>
<option value="per_ballot">Per ballot</option> <option value="per_ballot">Per ballot</option>
</select> </select>
</label> </label>

View File

@ -236,7 +236,7 @@ function changePreset() {
document.getElementById('txtRoundVotes').value = '0'; document.getElementById('txtRoundVotes').value = '0';
document.getElementById('chkRoundSFs').checked = false; document.getElementById('chkRoundSFs').checked = false;
document.getElementById('chkRoundValues').checked = false; document.getElementById('chkRoundValues').checked = false;
document.getElementById('selSumTransfers').value = 'per_ballot'; document.getElementById('selSumTransfers').value = 'by_value_and_source';
document.getElementById('selSurplus').value = 'by_order'; document.getElementById('selSurplus').value = 'by_order';
document.getElementById('selMethod').value = 'wig'; document.getElementById('selMethod').value = 'wig';
document.getElementById('selPapers').value = 'transferable'; document.getElementById('selPapers').value = 'transferable';

View File

@ -80,7 +80,7 @@ pub struct SubcmdOptions {
round_quota: Option<usize>, round_quota: Option<usize>,
/// (Gregory STV) How to round subtransfers during surpluses/exclusions /// (Gregory STV) How to round subtransfers during surpluses/exclusions
#[clap(help_heading=Some("ROUNDING"), long, possible_values=&["single_step", "per_ballot"], default_value="single_step", value_name="mode")] #[clap(help_heading=Some("ROUNDING"), long, possible_values=&["single_step", "by_value", "by_value_and_source", "per_ballot"], default_value="single_step", value_name="mode")]
round_subtransfers: String, round_subtransfers: String,
/// (Meek STV) Limit for stopping iteration of surplus distribution /// (Meek STV) Limit for stopping iteration of surplus distribution

View File

@ -1,5 +1,5 @@
/* OpenTally: Open-source election vote counting /* OpenTally: Open-source election vote counting
* Copyright © 2021 Lee Yingtong Li (RunasSudo) * Copyright © 20212022 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
@ -28,7 +28,7 @@ pub mod prettytable_html;
// -------- // --------
// STV code // STV code
use super::{ExclusionMethod, STVError, STVOptions, SurplusMethod, SurplusOrder}; use super::{ExclusionMethod, RoundSubtransfersMode, STVError, STVOptions, SurplusMethod, SurplusOrder};
use super::sample; use super::sample;
use crate::constraints; use crate::constraints;
@ -254,7 +254,7 @@ where
exhausted_ballots += &result.exhausted.num_ballots; exhausted_ballots += &result.exhausted.num_ballots;
exhausted_votes += &result.exhausted.num_ballots * &parcel.value_fraction; exhausted_votes += &result.exhausted.num_ballots * &parcel.value_fraction;
parcels_next_prefs.push((parcel.value_fraction, result)); parcels_next_prefs.push((parcel.value_fraction, parcel.source_order, result));
} }
// Calculate and print surplus fraction // Calculate and print surplus fraction
@ -316,10 +316,15 @@ where
surplus.clone(), surplus_fraction.clone(), surplus_numer.clone(), surplus_denom.clone() surplus.clone(), surplus_fraction.clone(), surplus_numer.clone(), surplus_denom.clone()
); );
for (value_fraction, result) in parcels_next_prefs { for (value_fraction, source_order, result) in parcels_next_prefs {
for (candidate, entry) in result.candidates.into_iter() { for (candidate, entry) in result.candidates.into_iter() {
// Record transfers // Record transfers
transfer_table.add_transfers(&value_fraction, candidate, &entry.num_ballots); transfer_table.add_transfers(
&value_fraction,
if opts.round_subtransfers == RoundSubtransfersMode::ByValueAndSource { Some(source_order) } else { None },
candidate,
&entry.num_ballots
);
let mut new_value_fraction; let mut new_value_fraction;
if opts.surplus.is_weighted() { if opts.surplus.is_weighted() {
@ -351,7 +356,11 @@ where
} }
// Record exhausted votes // Record exhausted votes
transfer_table.add_exhausted(&value_fraction, &result.exhausted.num_ballots); transfer_table.add_exhausted(
&value_fraction,
if opts.round_subtransfers == RoundSubtransfersMode::ByValueAndSource { Some(source_order) } else { None },
&result.exhausted.num_ballots
);
// Transfer exhausted votes // Transfer exhausted votes
let parcel = Parcel { let parcel = Parcel {
@ -571,23 +580,28 @@ where
state.election.candidates.iter().filter(|c| state.candidates[c].state == CandidateState::Hopeful || state.candidates[c].state == CandidateState::Guarded).collect(), state.election.candidates.iter().filter(|c| state.candidates[c].state == CandidateState::Hopeful || state.candidates[c].state == CandidateState::Guarded).collect(),
); );
for parcel in parcels { for src_parcel in parcels {
// Count next preferences // Count next preferences
let result = super::next_preferences(state, parcel.votes); let result = super::next_preferences(state, src_parcel.votes);
total_ballots += &result.total_ballots; total_ballots += &result.total_ballots;
total_votes += &result.total_ballots * &parcel.value_fraction; total_votes += &result.total_ballots * &src_parcel.value_fraction;
// Transfer candidate votes // Transfer candidate votes
for (candidate, entry) in result.candidates.into_iter() { for (candidate, entry) in result.candidates.into_iter() {
let parcel = Parcel { let parcel = Parcel {
votes: entry.votes, votes: entry.votes,
value_fraction: parcel.value_fraction.clone(), value_fraction: src_parcel.value_fraction.clone(),
source_order: state.num_elected + state.num_excluded, source_order: state.num_elected + state.num_excluded,
}; };
// Record transfers // Record transfers
transfer_table.add_transfers(&parcel.value_fraction, candidate, &entry.num_ballots); transfer_table.add_transfers(
&parcel.value_fraction,
if opts.round_subtransfers == RoundSubtransfersMode::ByValueAndSource { Some(src_parcel.source_order) } else { None },
candidate,
&entry.num_ballots
);
let count_card = state.candidates.get_mut(candidate).unwrap(); let count_card = state.candidates.get_mut(candidate).unwrap();
count_card.parcels.push(parcel); count_card.parcels.push(parcel);
@ -596,12 +610,16 @@ where
// Transfer exhausted votes // Transfer exhausted votes
let parcel = Parcel { let parcel = Parcel {
votes: result.exhausted.votes, votes: result.exhausted.votes,
value_fraction: parcel.value_fraction, value_fraction: src_parcel.value_fraction,
source_order: state.num_elected + state.num_excluded, source_order: state.num_elected + state.num_excluded,
}; };
// Record transfers // Record transfers
transfer_table.add_exhausted(&parcel.value_fraction, &result.exhausted.num_ballots); transfer_table.add_exhausted(
&parcel.value_fraction,
if opts.round_subtransfers == RoundSubtransfersMode::ByValueAndSource { Some(src_parcel.source_order) } else { None },
&result.exhausted.num_ballots
);
state.exhausted.parcels.push(parcel); state.exhausted.parcels.push(parcel);
} }

View File

@ -56,6 +56,7 @@ impl<'e, N: Number> TransferTable<'e, N> {
columns: Vec::new(), columns: Vec::new(),
total: TransferTableColumn { total: TransferTableColumn {
value_fraction: N::new(), value_fraction: N::new(),
source_order: None,
cells: HashMap::new(), cells: HashMap::new(),
exhausted: TransferTableCell { ballots: N::new(), votes_in: N::new(), votes_out: N::new() }, exhausted: TransferTableCell { ballots: N::new(), votes_in: N::new(), votes_out: N::new() },
total: TransferTableCell { ballots: N::new(), votes_in: N::new(), votes_out: N::new() }, total: TransferTableCell { ballots: N::new(), votes_in: N::new(), votes_out: N::new() },
@ -74,6 +75,7 @@ impl<'e, N: Number> TransferTable<'e, N> {
columns: Vec::new(), columns: Vec::new(),
total: TransferTableColumn { total: TransferTableColumn {
value_fraction: N::new(), value_fraction: N::new(),
source_order: None,
cells: HashMap::new(), cells: HashMap::new(),
exhausted: TransferTableCell { ballots: N::new(), votes_in: N::new(), votes_out: N::new() }, exhausted: TransferTableCell { ballots: N::new(), votes_in: N::new(), votes_out: N::new() },
total: TransferTableCell { ballots: N::new(), votes_in: N::new(), votes_out: N::new() }, total: TransferTableCell { ballots: N::new(), votes_in: N::new(), votes_out: N::new() },
@ -86,9 +88,9 @@ impl<'e, N: Number> TransferTable<'e, N> {
} }
/// Record the specified transfer /// Record the specified transfer
pub fn add_transfers(&mut self, value_fraction: &N, candidate: &'e Candidate, ballots: &N) { pub fn add_transfers(&mut self, value_fraction: &N, source_order: Option<usize>, candidate: &'e Candidate, ballots: &N) {
for col in self.columns.iter_mut() { for col in self.columns.iter_mut() {
if &col.value_fraction == value_fraction { if &col.value_fraction == value_fraction && col.source_order == source_order {
col.add_transfers(candidate, ballots); col.add_transfers(candidate, ballots);
return; return;
} }
@ -96,6 +98,7 @@ impl<'e, N: Number> TransferTable<'e, N> {
let mut col = TransferTableColumn { let mut col = TransferTableColumn {
value_fraction: value_fraction.clone(), value_fraction: value_fraction.clone(),
source_order: source_order,
cells: HashMap::new(), cells: HashMap::new(),
exhausted: TransferTableCell { ballots: N::new(), votes_in: N::new(), votes_out: N::new() }, exhausted: TransferTableCell { ballots: N::new(), votes_in: N::new(), votes_out: N::new() },
total: TransferTableCell { ballots: N::new(), votes_in: N::new(), votes_out: N::new() }, total: TransferTableCell { ballots: N::new(), votes_in: N::new(), votes_out: N::new() },
@ -105,9 +108,9 @@ impl<'e, N: Number> TransferTable<'e, N> {
} }
/// Record the specified exhaustion /// Record the specified exhaustion
pub fn add_exhausted(&mut self, value_fraction: &N, ballots: &N) { pub fn add_exhausted(&mut self, value_fraction: &N, source_order: Option<usize>, ballots: &N) {
for col in self.columns.iter_mut() { for col in self.columns.iter_mut() {
if &col.value_fraction == value_fraction { if &col.value_fraction == value_fraction && col.source_order == source_order {
col.exhausted.ballots += ballots; col.exhausted.ballots += ballots;
return; return;
} }
@ -115,6 +118,7 @@ impl<'e, N: Number> TransferTable<'e, N> {
let col = TransferTableColumn { let col = TransferTableColumn {
value_fraction: value_fraction.clone(), value_fraction: value_fraction.clone(),
source_order: source_order,
cells: HashMap::new(), cells: HashMap::new(),
exhausted: TransferTableCell { ballots: ballots.clone(), votes_in: N::new(), votes_out: N::new() }, exhausted: TransferTableCell { ballots: ballots.clone(), votes_in: N::new(), votes_out: N::new() },
total: TransferTableCell { ballots: N::new(), votes_in: N::new(), votes_out: N::new() }, total: TransferTableCell { ballots: N::new(), votes_in: N::new(), votes_out: N::new() },
@ -199,7 +203,7 @@ impl<'e, N: Number> TransferTable<'e, N> {
self.total.exhausted.votes_out.floor_mut(dps); self.total.exhausted.votes_out.floor_mut(dps);
} }
} }
RoundSubtransfersMode::ByValue => { RoundSubtransfersMode::ByValue | RoundSubtransfersMode::ByValueAndSource => {
// Calculate votes_out for each column // Calculate votes_out for each column
for column in self.columns.iter_mut() { for column in self.columns.iter_mut() {
// Calculate votes_out per candidate in the column // Calculate votes_out per candidate in the column
@ -245,7 +249,7 @@ impl<'e, N: Number> TransferTable<'e, N> {
// Sum total votes_out per candidate // Sum total votes_out per candidate
for (candidate, cell) in self.total.cells.iter_mut() { for (candidate, cell) in self.total.cells.iter_mut() {
cell.votes_out = self.columns.iter().fold(N::new(), |acc, col| acc + &col.cells[candidate].votes_out); cell.votes_out = self.columns.iter().fold(N::new(), |acc, col| if let Some(cell) = col.cells.get(candidate) { acc + &cell.votes_out } else { acc });
} }
// Sum total exhausted votes // Sum total exhausted votes
@ -307,13 +311,12 @@ impl<'e, N: Number> TransferTable<'e, N> {
// Sum total votes_out per candidate // Sum total votes_out per candidate
for (candidate, cell) in self.total.cells.iter_mut() { for (candidate, cell) in self.total.cells.iter_mut() {
cell.votes_out = self.columns.iter().fold(N::new(), |acc, col| acc + &col.cells[candidate].votes_out); cell.votes_out = self.columns.iter().fold(N::new(), |acc, col| if let Some(cell) = col.cells.get(candidate) { acc + &cell.votes_out } else { acc });
} }
// Sum total exhausted votes // Sum total exhausted votes
self.total.exhausted.votes_out = self.columns.iter().fold(N::new(), |acc, col| acc + &col.exhausted.votes_out); self.total.exhausted.votes_out = self.columns.iter().fold(N::new(), |acc, col| acc + &col.exhausted.votes_out);
} }
_ => todo!()
} }
} }
@ -562,6 +565,9 @@ pub struct TransferTableColumn<'e, N: Number> {
/// Value fraction of ballots counted in this column /// Value fraction of ballots counted in this column
pub value_fraction: N, pub value_fraction: N,
/// Number to separate parcels in modes where subtransfers by parcel, or `None` if unused
pub source_order: Option<usize>,
/// Cells in this column /// Cells in this column
pub cells: HashMap<&'e Candidate, TransferTableCell<N>>, pub cells: HashMap<&'e Candidate, TransferTableCell<N>>,

View File

@ -224,7 +224,8 @@ impl STVOptions {
//if self.sample == SampleMethod::StratifyFloor && self.sample_per_ballot { return Err(STVError::InvalidOptions("--sample stratify_floor is incompatible with --sample-per-ballot")); } //if self.sample == SampleMethod::StratifyFloor && self.sample_per_ballot { return Err(STVError::InvalidOptions("--sample stratify_floor is incompatible with --sample-per-ballot")); }
if self.sample_per_ballot && !self.immediate_elect { return Err(STVError::InvalidOptions("--sample-per-ballot is incompatible with --no-immediate-elect")); } if self.sample_per_ballot && !self.immediate_elect { return Err(STVError::InvalidOptions("--sample-per-ballot is incompatible with --no-immediate-elect")); }
} }
if self.min_threshold != "0" && self.defer_surpluses { return Err(STVError::InvalidOptions("--min-threshold is incompatible with --defer-surpluses")); } // TODO: Permit this if self.min_threshold != "0" && self.defer_surpluses { return Err(STVError::InvalidOptions("--min-threshold is incompatible with --defer-surpluses (not yet implemented)")); } // TODO: NYI
if self.round_subtransfers == RoundSubtransfersMode::ByValueAndSource && self.bulk_exclude { return Err(STVError::InvalidOptions("--round-subtransfers by_value_and_source is incompatible with --bulk-exclude (not yet implemented)")); } // TODO: NYI
return Ok(()); return Ok(());
} }
} }
@ -248,10 +249,10 @@ impl RoundSubtransfersMode {
/// Convert to CLI argument representation /// Convert to CLI argument representation
fn describe(self) -> String { fn describe(self) -> String {
match self { match self {
RoundSubtransfersMode::SingleStep => "--sum-surplus-transfers single_step", RoundSubtransfersMode::SingleStep => "--round-subtransfers single_step",
RoundSubtransfersMode::ByValue => "--sum-surplus-transfers by_value", RoundSubtransfersMode::ByValue => "--round-subtransfers by_value",
RoundSubtransfersMode::ByValueAndSource => "--sum-surplus-transfers by_value_and_source", RoundSubtransfersMode::ByValueAndSource => "--round-subtransfers by_value_and_source",
RoundSubtransfersMode::PerBallot => "--sum-surplus-transfers per_ballot", RoundSubtransfersMode::PerBallot => "--round-subtransfers per_ballot",
}.to_string() }.to_string()
} }
} }

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,53 @@
Stage:,1,,2,,3,,4,,5,,6,,7,,8,,9,,10,,11,,12,,13,,14,,15,,16,,17,,18,,19,,20,,21,,22,,23,,24,,25,,26,,27,,28,,29,,30,,31,,32,,33,,34,,35,,36,,37,,38,,39,,40,,41,,42,,43,,44,,45,,46,,47,,48,,49,
Comment:,First preferences,,Surplus of KING Kylie,,Surplus of BAKER Stuart,,Surplus of GLACHAN Alice,,Surplus of EDWARDS Ashley,,Surplus of BOWEN Steve,,Exclusion of HARTNETT Diann,,Exclusion of MOORE John,,Exclusion of STAR C,,Exclusion of HEATHER Esther,,Exclusion of MARTIN Christopher,,Exclusion of BARBER Trevor,,Exclusion of VAN NOORDENNEN Bill,,Exclusion of PATTINSON Jill,,Exclusion of MACHIN Michael,,Exclusion of HAMILTON Claire,,Exclusion of ALLEN Geoffrey,,Exclusion of WALLIS Lucie,,Exclusion of TRATZ Mathew,,Exclusion of MONTE Susie,,Exclusion of PEARCE Garry,,Exclusion of DOYLE Mark,,Exclusion of SINGH Naziya,,Exclusion of RYAN Christopher,,Exclusion of PEMBERTON Louise,,Exclusion of WATKINS Sarah,,Exclusion of SMITH Taneesha,,Exclusion of GRELLMAN Emily,,Exclusion of ARMSTRONG Paul,,Exclusion of DUNN Jackie,,Exclusion of CALE Danielle,,Exclusion of ROWLAND Marcus,,Exclusion of GRENFELL Brian,,Exclusion of CHAN Aimee,,Exclusion of HULL Barbara,,Exclusion of THOMAS Dianne,,Exclusion of HOOD Peter,,Exclusion of CAMERON Amelia,,Exclusion of TIERNAN Jodie,,Exclusion of DOCKSEY Graham,,Exclusion of ISAACS Kofi,,Exclusion of COHN Amanda,,Exclusion of MAMOUNEY Stephen,,Exclusion of VENESS Rhiannon,,Exclusion of BARBER Andrew,,Exclusion of PEARSON Lindsay,,Surplus of BETTERIDGE Daryl,,Surplus of CAMERON Darren,,Exclusion of VAN DE VEN Henk,
BETTERIDGE Daryl,2526,H,2539,H,2583,H,2606,H,2606,H,2632,H,2632,H,2632,H,2632,H,2632,H,2633,H,2633,H,2633,H,2634,H,2634,H,2634,H,2634,H,2636,H,2638,H,2638,H,2639,H,2639,H,2640,H,2640,H,2640,H,2640,H,2641,H,2641,H,2644,H,2644,H,2646,H,2648,H,2660,H,2660,H,2675,H,2681,H,2687,H,2688,H,2721,H,2726,H,2726,H,2733,H,2770,H,2788,H,2826,H,2864,EL,2838,EL,2838,EL,2838,EL
HULL Barbara,38,H,38,H,39,H,39,H,39,H,39,H,39,H,39,H,39,H,39,H,39,H,39,H,39,H,39,H,39,H,39,H,39,H,39,H,40,H,40,H,41,H,42,H,42,H,42,H,43,H,43,H,44,H,45,H,45,H,45,H,45,H,46,H,47,H,47,H,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX
TIERNAN Jodie,51,H,51,H,59,H,61,H,61,H,65,H,65,H,65,H,65,H,65,H,65,H,65,H,65,H,65,H,65,H,66,H,66,H,66,H,66,H,67,H,67,H,67,H,67,H,67,H,68,H,69,H,69,H,70,H,70,H,70,H,70,H,71,H,77,H,77,H,85,H,86,H,88,H,94,H,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX
GRENFELL Brian,32,H,32,H,34,H,34,H,34,H,35,H,35,H,35,H,35,H,35,H,35,H,35,H,37,H,37,H,37,H,37,H,38,H,38,H,40,H,40,H,40,H,40,H,40,H,40,H,40,H,40,H,40,H,42,H,42,H,42,H,43,H,43,H,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX
TRATZ Mathew,14,H,14,H,14,H,14,H,14,H,14,H,14,H,14,H,14,H,14,H,14,H,14,H,14,H,14,H,14,H,14,H,14,H,14,H,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX
CAMERON Darren,2595,H,2602,H,2613,H,2617,H,2617,H,2623,H,2623,H,2623,H,2623,H,2623,H,2623,H,2623,H,2623,H,2623,H,2623,H,2623,H,2625,H,2625,H,2625,H,2625,H,2625,H,2625,H,2625,H,2631,H,2631,H,2632,H,2632,H,2633,H,2634,H,2634,H,2634,H,2649,H,2653,H,2654,H,2657,H,2658,H,2665,H,2722,H,2724,H,2729,H,2731,H,2754,H,2757,H,2769,H,2812,H,2833,H,2839,EL,2838,EL,2838,EL
ROWLAND Marcus,39,H,39,H,40,H,40,H,40,H,40,H,40,H,40,H,40,H,40,H,40,H,40,H,40,H,40,H,40,H,40,H,40,H,40,H,40,H,40,H,40,H,40,H,40,H,40,H,40,H,40,H,40,H,40,H,40,H,40,H,40,H,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX
CAMERON Amelia,51,H,51,H,51,H,51,H,51,H,51,H,51,H,51,H,51,H,51,H,51,H,51,H,51,H,52,H,52,H,52,H,56,H,56,H,59,H,59,H,59,H,59,H,59,H,72,H,72,H,72,H,73,H,76,H,76,H,76,H,76,H,83,H,83,H,83,H,86,H,86,H,86,H,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX
ALLEN Geoffrey,13,H,13,H,13,H,13,H,13,H,13,H,13,H,13,H,13,H,13,H,13,H,13,H,13,H,13,H,13,H,13,H,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX
RYAN Christopher,16,H,16,H,16,H,16,H,16,H,16,H,16,H,16,H,16,H,16,H,16,H,16,H,16,H,16,H,16,H,16,H,19,H,19,H,20,H,21,H,21,H,21,H,21,H,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX
HAMILTON Ross,1244,H,1252,H,1265,H,1270,H,1270,H,1277,H,1277,H,1277,H,1277,H,1277,H,1277,H,1277,H,1278,H,1278,H,1278,H,1279,H,1280,H,1282,H,1284,H,1284,H,1286,H,1286,H,1286,H,1286,H,1286,H,1288,H,1288,H,1295,H,1296,H,1296,H,1296,H,1297,H,1300,H,1301,H,1303,H,1329,H,1331,H,1333,H,1338,H,1339,H,1341,H,1354,H,1360,H,1371,H,1452,H,1473,H,1478,H,1478,H,1530,H
THOMAS Dianne,40,H,40,H,45,H,47,H,47,H,49,H,49,H,49,H,49,H,49,H,49,H,49,H,49,H,49,H,49,H,50,H,50,H,52,H,52,H,53,H,53,H,53,H,53,H,53,H,53,H,54,H,54,H,61,H,61,H,61,H,61,H,62,H,62,H,63,H,66,H,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX
GRELLMAN Emily,18,H,18,H,18,H,18,H,18,H,18,H,18,H,18,H,18,H,18,H,18,H,19,H,19,H,20,H,20,H,22,H,23,H,27,H,27,H,27,H,27,H,27,H,27,H,27,H,27,H,27,H,27,H,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX
WALLIS Lucie,12,H,12,H,12,H,12,H,12,H,12,H,12,H,12,H,12,H,12,H,12,H,12,H,12,H,12,H,12,H,14,H,14,H,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX
HAMILTON Claire,10,H,10,H,11,H,11,H,11,H,11,H,11,H,11,H,11,H,11,H,12,H,12,H,12,H,12,H,12,H,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX
KING Kylie,5517,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL
BOWEN Steve,884,H,3476,EL,3476,EL,3476,EL,3476,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL
VENESS Rhiannon,5,H,11,H,11,H,11,H,11,H,501,H,501,H,501,H,501,H,502,H,502,H,502,H,502,H,502,H,502,H,502,H,502,H,502,H,502,H,502,H,502,H,502,H,502,H,502,H,503,H,503,H,509,H,509,H,509,H,509,H,509,H,510,H,511,H,541,H,543,H,546,H,548,H,550,H,553,H,553,H,553,H,558,H,562,H,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX
CHAN Aimee,12,H,15,H,15,H,15,H,15,H,30,H,30,H,30,H,30,H,30,H,30,H,30,H,30,H,30,H,30,H,30,H,30,H,30,H,30,H,30,H,30,H,30,H,30,H,30,H,30,H,31,H,39,H,40,H,40,H,43,H,43,H,43,H,43,H,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX
SMITH Taneesha,8,H,11,H,11,H,11,H,11,H,23,H,23,H,23,H,23,H,23,H,23,H,23,H,23,H,23,H,23,H,23,H,23,H,23,H,23,H,23,H,23,H,23,H,24,H,25,H,25,H,27,H,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX
BARBER Andrew,737,H,743,H,754,H,759,H,759,H,763,H,763,H,763,H,763,H,763,H,763,H,768,H,768,H,768,H,768,H,769,H,769,H,770,H,770,H,770,H,770,H,771,H,771,H,771,H,771,H,781,H,781,H,781,H,782,H,782,H,784,H,784,H,784,H,784,H,784,H,784,H,786,H,788,H,789,H,793,H,794,H,804,H,809,H,819,H,0,EX,0,EX,0,EX,0,EX,0,EX
WATKINS Sarah,19,H,20,H,21,H,21,H,21,H,21,H,21,H,21,H,22,H,22,H,22,H,22,H,22,H,22,H,22,H,22,H,22,H,23,H,23,H,23,H,23,H,23,H,23,H,23,H,24,H,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX
BARBER Trevor,6,H,6,H,6,H,6,H,6,H,6,H,7,H,7,H,9,H,9,H,9,H,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX
STAR C,4,H,4,H,4,H,4,H,4,H,4,H,5,H,6,H,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX
HARTNETT Diann,2,H,2,H,2,H,2,H,2,H,2,H,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX
EDWARDS Ashley,2913,EL,2913,EL,2913,EL,2913,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL
ISAACS Kofi,33,H,33,H,35,H,35,H,104,H,106,H,106,H,106,H,107,H,107,H,107,H,107,H,107,H,109,H,110,H,110,H,110,H,110,H,110,H,115,H,115,H,115,H,115,H,115,H,116,H,116,H,116,H,116,H,116,H,116,H,117,H,117,H,119,H,119,H,120,H,120,H,122,H,125,H,127,H,127,H,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX
PATTINSON Jill,9,H,9,H,9,H,9,H,9,H,9,H,9,H,9,H,9,H,9,H,9,H,9,H,9,H,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX
MONTE Susie,14,H,14,H,14,H,14,H,14,H,14,H,14,H,14,H,14,H,14,H,14,H,14,H,14,H,16,H,16,H,16,H,16,H,16,H,16,H,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX
COHN Amanda,105,H,107,H,113,H,115,H,116,H,120,H,120,H,120,H,120,H,120,H,120,H,120,H,120,H,121,H,121,H,121,H,121,H,122,H,123,H,130,H,130,H,130,H,131,H,131,H,133,H,133,H,134,H,134,H,135,H,138,H,138,H,138,H,139,H,139,H,140,H,144,H,148,H,149,H,154,H,154,H,244,H,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX
GLACHAN Alice,3837,EL,3837,EL,3837,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL
PEARSON Lindsay,47,H,48,H,53,H,914,H,914,H,919,H,919,H,919,H,920,H,920,H,921,H,921,H,921,H,921,H,923,H,923,H,923,H,923,H,924,H,924,H,924,H,924,H,928,H,928,H,928,H,928,H,929,H,929,H,929,H,941,H,944,H,945,H,946,H,946,H,947,H,948,H,951,H,954,H,956,H,981,H,985,H,990,H,992,H,1015,H,1056,H,0,EX,0,EX,0,EX,0,EX
DOCKSEY Graham,39,H,39,H,48,H,66,H,66,H,68,H,68,H,68,H,68,H,68,H,68,H,68,H,68,H,68,H,68,H,68,H,68,H,68,H,68,H,68,H,68,H,68,H,71,H,71,H,71,H,72,H,72,H,72,H,74,H,82,H,83,H,86,H,90,H,90,H,90,H,90,H,92,H,94,H,96,H,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX
SINGH Naziya,13,H,13,H,14,H,19,H,19,H,19,H,19,H,19,H,19,H,20,H,20,H,20,H,20,H,20,H,20,H,20,H,20,H,20,H,20,H,20,H,20,H,20,H,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX
DUNN Jackie,23,H,23,H,24,H,29,H,29,H,29,H,29,H,29,H,30,H,30,H,30,H,30,H,30,H,30,H,30,H,30,H,30,H,30,H,30,H,30,H,30,H,30,H,35,H,35,H,35,H,35,H,35,H,35,H,35,H,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX
BAKER Stuart,4494,EL,4494,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL,2838,EL
KELLAHAN Jessica,104,H,104,H,1486,H,1488,H,1488,H,1491,H,1491,H,1491,H,1491,H,1491,H,1491,H,1492,H,1492,H,1492,H,1492,H,1492,H,1492,H,1492,H,1492,H,1492,H,1492,H,1492,H,1492,H,1492,H,1495,H,1495,H,1495,H,1497,H,1497,H,1498,H,1512,H,1513,H,1513,H,1514,H,1515,H,1518,H,1521,H,1522,H,1526,H,1531,H,1532,H,1540,H,1723,H,1752,H,1792,H,1872,H,1876,H,1876,H,1941,EL
MAMOUNEY Stephen,224,H,225,H,278,H,283,H,283,H,288,H,288,H,288,H,288,H,288,H,289,H,289,H,290,H,290,H,290,H,290,H,290,H,290,H,290,H,291,H,291,H,291,H,291,H,291,H,296,H,297,H,297,H,298,H,301,H,304,H,314,H,314,H,315,H,316,H,316,H,319,H,320,H,321,H,322,H,325,H,326,H,331,H,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX
CALE Danielle,24,H,24,H,33,H,33,H,33,H,33,H,33,H,33,H,33,H,33,H,33,H,33,H,33,H,33,H,34,H,35,H,36,H,36,H,36,H,36,H,36,H,37,H,38,H,38,H,39,H,39,H,40,H,40,H,40,H,40,H,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX
PEMBERTON Louise,17,H,17,H,22,H,22,H,22,H,22,H,22,H,22,H,22,H,22,H,22,H,22,H,22,H,22,H,22,H,22,H,22,H,22,H,22,H,22,H,22,H,22,H,22,H,22,H,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX
VAN DE VEN Henk,1240,H,1247,H,1280,H,1300,H,1300,H,1307,H,1307,H,1307,H,1307,H,1307,H,1308,H,1309,H,1310,H,1311,H,1311,H,1311,H,1311,H,1311,H,1311,H,1311,H,1318,H,1319,H,1319,H,1319,H,1320,H,1320,H,1321,H,1322,H,1335,H,1336,H,1337,H,1338,H,1338,H,1338,H,1338,H,1342,H,1344,H,1345,H,1348,H,1361,H,1362,H,1368,H,1380,H,1385,H,1405,H,1431,H,1433,H,1433,H,0,EX
PEARCE Garry,13,H,13,H,14,H,14,H,14,H,15,H,15,H,15,H,15,H,15,H,16,H,16,H,17,H,17,H,17,H,17,H,17,H,17,H,17,H,17,H,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX
ARMSTRONG Paul,25,H,25,H,26,H,28,H,28,H,28,H,28,H,28,H,28,H,28,H,29,H,29,H,30,H,30,H,30,H,30,H,30,H,30,H,30,H,30,H,33,H,33,H,33,H,33,H,33,H,33,H,33,H,33,H,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX
VAN NOORDENNEN Bill,9,H,9,H,9,H,9,H,9,H,9,H,9,H,9,H,9,H,9,H,9,H,9,H,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX
MARTIN Christopher,7,H,7,H,7,H,7,H,7,H,7,H,7,H,8,H,8,H,8,H,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX
THURLEY David,1211,H,1221,H,1250,H,1272,H,1272,H,1280,H,1280,H,1280,H,1280,H,1282,H,1282,H,1283,H,1285,H,1285,H,1288,H,1289,H,1289,H,1290,H,1290,H,1290,H,1290,H,1304,H,1304,H,1304,H,1305,H,1306,H,1306,H,1306,H,1311,H,1311,H,1312,H,1313,H,1314,H,1314,H,1314,H,1318,H,1333,H,1334,H,1338,H,1348,H,1350,H,1379,H,1394,H,1399,H,1438,H,1465,H,1467,H,1467,H,1617,EL
DOYLE Mark,16,H,16,H,16,H,17,H,17,H,17,H,17,H,17,H,17,H,18,H,18,H,18,H,18,H,18,H,19,H,19,H,19,H,19,H,19,H,19,H,19,H,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX
HEATHER Esther,5,H,5,H,5,H,5,H,5,H,5,H,5,H,6,H,6,H,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX
MOORE John,4,H,4,H,4,H,4,H,4,H,4,H,4,H,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX
MACHIN Michael,8,H,8,H,8,H,8,H,8,H,8,H,8,H,8,H,8,H,9,H,10,H,10,H,10,H,10,H,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX
HOOD Peter,51,H,51,H,54,H,54,H,54,H,56,H,56,H,57,H,57,H,57,H,57,H,57,H,57,H,57,H,59,H,60,H,60,H,60,H,61,H,61,H,61,H,61,H,61,H,61,H,62,H,62,H,63,H,63,H,64,H,64,H,65,H,66,H,66,H,66,H,67,H,69,H,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX,0,EX
1 Stage: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
2 Comment: First preferences Surplus of KING Kylie Surplus of BAKER Stuart Surplus of GLACHAN Alice Surplus of EDWARDS Ashley Surplus of BOWEN Steve Exclusion of HARTNETT Diann Exclusion of MOORE John Exclusion of STAR C Exclusion of HEATHER Esther Exclusion of MARTIN Christopher Exclusion of BARBER Trevor Exclusion of VAN NOORDENNEN Bill Exclusion of PATTINSON Jill Exclusion of MACHIN Michael Exclusion of HAMILTON Claire Exclusion of ALLEN Geoffrey Exclusion of WALLIS Lucie Exclusion of TRATZ Mathew Exclusion of MONTE Susie Exclusion of PEARCE Garry Exclusion of DOYLE Mark Exclusion of SINGH Naziya Exclusion of RYAN Christopher Exclusion of PEMBERTON Louise Exclusion of WATKINS Sarah Exclusion of SMITH Taneesha Exclusion of GRELLMAN Emily Exclusion of ARMSTRONG Paul Exclusion of DUNN Jackie Exclusion of CALE Danielle Exclusion of ROWLAND Marcus Exclusion of GRENFELL Brian Exclusion of CHAN Aimee Exclusion of HULL Barbara Exclusion of THOMAS Dianne Exclusion of HOOD Peter Exclusion of CAMERON Amelia Exclusion of TIERNAN Jodie Exclusion of DOCKSEY Graham Exclusion of ISAACS Kofi Exclusion of COHN Amanda Exclusion of MAMOUNEY Stephen Exclusion of VENESS Rhiannon Exclusion of BARBER Andrew Exclusion of PEARSON Lindsay Surplus of BETTERIDGE Daryl Surplus of CAMERON Darren Exclusion of VAN DE VEN Henk
3 BETTERIDGE Daryl 2526 H 2539 H 2583 H 2606 H 2606 H 2632 H 2632 H 2632 H 2632 H 2632 H 2633 H 2633 H 2633 H 2634 H 2634 H 2634 H 2634 H 2636 H 2638 H 2638 H 2639 H 2639 H 2640 H 2640 H 2640 H 2640 H 2641 H 2641 H 2644 H 2644 H 2646 H 2648 H 2660 H 2660 H 2675 H 2681 H 2687 H 2688 H 2721 H 2726 H 2726 H 2733 H 2770 H 2788 H 2826 H 2864 EL 2838 EL 2838 EL 2838 EL
4 HULL Barbara 38 H 38 H 39 H 39 H 39 H 39 H 39 H 39 H 39 H 39 H 39 H 39 H 39 H 39 H 39 H 39 H 39 H 39 H 40 H 40 H 41 H 42 H 42 H 42 H 43 H 43 H 44 H 45 H 45 H 45 H 45 H 46 H 47 H 47 H 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX
5 TIERNAN Jodie 51 H 51 H 59 H 61 H 61 H 65 H 65 H 65 H 65 H 65 H 65 H 65 H 65 H 65 H 65 H 66 H 66 H 66 H 66 H 67 H 67 H 67 H 67 H 67 H 68 H 69 H 69 H 70 H 70 H 70 H 70 H 71 H 77 H 77 H 85 H 86 H 88 H 94 H 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX
6 GRENFELL Brian 32 H 32 H 34 H 34 H 34 H 35 H 35 H 35 H 35 H 35 H 35 H 35 H 37 H 37 H 37 H 37 H 38 H 38 H 40 H 40 H 40 H 40 H 40 H 40 H 40 H 40 H 40 H 42 H 42 H 42 H 43 H 43 H 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX
7 TRATZ Mathew 14 H 14 H 14 H 14 H 14 H 14 H 14 H 14 H 14 H 14 H 14 H 14 H 14 H 14 H 14 H 14 H 14 H 14 H 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX
8 CAMERON Darren 2595 H 2602 H 2613 H 2617 H 2617 H 2623 H 2623 H 2623 H 2623 H 2623 H 2623 H 2623 H 2623 H 2623 H 2623 H 2623 H 2625 H 2625 H 2625 H 2625 H 2625 H 2625 H 2625 H 2631 H 2631 H 2632 H 2632 H 2633 H 2634 H 2634 H 2634 H 2649 H 2653 H 2654 H 2657 H 2658 H 2665 H 2722 H 2724 H 2729 H 2731 H 2754 H 2757 H 2769 H 2812 H 2833 H 2839 EL 2838 EL 2838 EL
9 ROWLAND Marcus 39 H 39 H 40 H 40 H 40 H 40 H 40 H 40 H 40 H 40 H 40 H 40 H 40 H 40 H 40 H 40 H 40 H 40 H 40 H 40 H 40 H 40 H 40 H 40 H 40 H 40 H 40 H 40 H 40 H 40 H 40 H 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX
10 CAMERON Amelia 51 H 51 H 51 H 51 H 51 H 51 H 51 H 51 H 51 H 51 H 51 H 51 H 51 H 52 H 52 H 52 H 56 H 56 H 59 H 59 H 59 H 59 H 59 H 72 H 72 H 72 H 73 H 76 H 76 H 76 H 76 H 83 H 83 H 83 H 86 H 86 H 86 H 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX
11 ALLEN Geoffrey 13 H 13 H 13 H 13 H 13 H 13 H 13 H 13 H 13 H 13 H 13 H 13 H 13 H 13 H 13 H 13 H 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX
12 RYAN Christopher 16 H 16 H 16 H 16 H 16 H 16 H 16 H 16 H 16 H 16 H 16 H 16 H 16 H 16 H 16 H 16 H 19 H 19 H 20 H 21 H 21 H 21 H 21 H 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX
13 HAMILTON Ross 1244 H 1252 H 1265 H 1270 H 1270 H 1277 H 1277 H 1277 H 1277 H 1277 H 1277 H 1277 H 1278 H 1278 H 1278 H 1279 H 1280 H 1282 H 1284 H 1284 H 1286 H 1286 H 1286 H 1286 H 1286 H 1288 H 1288 H 1295 H 1296 H 1296 H 1296 H 1297 H 1300 H 1301 H 1303 H 1329 H 1331 H 1333 H 1338 H 1339 H 1341 H 1354 H 1360 H 1371 H 1452 H 1473 H 1478 H 1478 H 1530 H
14 THOMAS Dianne 40 H 40 H 45 H 47 H 47 H 49 H 49 H 49 H 49 H 49 H 49 H 49 H 49 H 49 H 49 H 50 H 50 H 52 H 52 H 53 H 53 H 53 H 53 H 53 H 53 H 54 H 54 H 61 H 61 H 61 H 61 H 62 H 62 H 63 H 66 H 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX
15 GRELLMAN Emily 18 H 18 H 18 H 18 H 18 H 18 H 18 H 18 H 18 H 18 H 18 H 19 H 19 H 20 H 20 H 22 H 23 H 27 H 27 H 27 H 27 H 27 H 27 H 27 H 27 H 27 H 27 H 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX
16 WALLIS Lucie 12 H 12 H 12 H 12 H 12 H 12 H 12 H 12 H 12 H 12 H 12 H 12 H 12 H 12 H 12 H 14 H 14 H 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX
17 HAMILTON Claire 10 H 10 H 11 H 11 H 11 H 11 H 11 H 11 H 11 H 11 H 12 H 12 H 12 H 12 H 12 H 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX
18 KING Kylie 5517 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL
19 BOWEN Steve 884 H 3476 EL 3476 EL 3476 EL 3476 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL
20 VENESS Rhiannon 5 H 11 H 11 H 11 H 11 H 501 H 501 H 501 H 501 H 502 H 502 H 502 H 502 H 502 H 502 H 502 H 502 H 502 H 502 H 502 H 502 H 502 H 502 H 502 H 503 H 503 H 509 H 509 H 509 H 509 H 509 H 510 H 511 H 541 H 543 H 546 H 548 H 550 H 553 H 553 H 553 H 558 H 562 H 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX
21 CHAN Aimee 12 H 15 H 15 H 15 H 15 H 30 H 30 H 30 H 30 H 30 H 30 H 30 H 30 H 30 H 30 H 30 H 30 H 30 H 30 H 30 H 30 H 30 H 30 H 30 H 30 H 31 H 39 H 40 H 40 H 43 H 43 H 43 H 43 H 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX
22 SMITH Taneesha 8 H 11 H 11 H 11 H 11 H 23 H 23 H 23 H 23 H 23 H 23 H 23 H 23 H 23 H 23 H 23 H 23 H 23 H 23 H 23 H 23 H 23 H 24 H 25 H 25 H 27 H 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX
23 BARBER Andrew 737 H 743 H 754 H 759 H 759 H 763 H 763 H 763 H 763 H 763 H 763 H 768 H 768 H 768 H 768 H 769 H 769 H 770 H 770 H 770 H 770 H 771 H 771 H 771 H 771 H 781 H 781 H 781 H 782 H 782 H 784 H 784 H 784 H 784 H 784 H 784 H 786 H 788 H 789 H 793 H 794 H 804 H 809 H 819 H 0 EX 0 EX 0 EX 0 EX 0 EX
24 WATKINS Sarah 19 H 20 H 21 H 21 H 21 H 21 H 21 H 21 H 22 H 22 H 22 H 22 H 22 H 22 H 22 H 22 H 22 H 23 H 23 H 23 H 23 H 23 H 23 H 23 H 24 H 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX
25 BARBER Trevor 6 H 6 H 6 H 6 H 6 H 6 H 7 H 7 H 9 H 9 H 9 H 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX
26 STAR C 4 H 4 H 4 H 4 H 4 H 4 H 5 H 6 H 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX
27 HARTNETT Diann 2 H 2 H 2 H 2 H 2 H 2 H 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX
28 EDWARDS Ashley 2913 EL 2913 EL 2913 EL 2913 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL
29 ISAACS Kofi 33 H 33 H 35 H 35 H 104 H 106 H 106 H 106 H 107 H 107 H 107 H 107 H 107 H 109 H 110 H 110 H 110 H 110 H 110 H 115 H 115 H 115 H 115 H 115 H 116 H 116 H 116 H 116 H 116 H 116 H 117 H 117 H 119 H 119 H 120 H 120 H 122 H 125 H 127 H 127 H 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX
30 PATTINSON Jill 9 H 9 H 9 H 9 H 9 H 9 H 9 H 9 H 9 H 9 H 9 H 9 H 9 H 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX
31 MONTE Susie 14 H 14 H 14 H 14 H 14 H 14 H 14 H 14 H 14 H 14 H 14 H 14 H 14 H 16 H 16 H 16 H 16 H 16 H 16 H 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX
32 COHN Amanda 105 H 107 H 113 H 115 H 116 H 120 H 120 H 120 H 120 H 120 H 120 H 120 H 120 H 121 H 121 H 121 H 121 H 122 H 123 H 130 H 130 H 130 H 131 H 131 H 133 H 133 H 134 H 134 H 135 H 138 H 138 H 138 H 139 H 139 H 140 H 144 H 148 H 149 H 154 H 154 H 244 H 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX
33 GLACHAN Alice 3837 EL 3837 EL 3837 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL
34 PEARSON Lindsay 47 H 48 H 53 H 914 H 914 H 919 H 919 H 919 H 920 H 920 H 921 H 921 H 921 H 921 H 923 H 923 H 923 H 923 H 924 H 924 H 924 H 924 H 928 H 928 H 928 H 928 H 929 H 929 H 929 H 941 H 944 H 945 H 946 H 946 H 947 H 948 H 951 H 954 H 956 H 981 H 985 H 990 H 992 H 1015 H 1056 H 0 EX 0 EX 0 EX 0 EX
35 DOCKSEY Graham 39 H 39 H 48 H 66 H 66 H 68 H 68 H 68 H 68 H 68 H 68 H 68 H 68 H 68 H 68 H 68 H 68 H 68 H 68 H 68 H 68 H 68 H 71 H 71 H 71 H 72 H 72 H 72 H 74 H 82 H 83 H 86 H 90 H 90 H 90 H 90 H 92 H 94 H 96 H 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX
36 SINGH Naziya 13 H 13 H 14 H 19 H 19 H 19 H 19 H 19 H 19 H 20 H 20 H 20 H 20 H 20 H 20 H 20 H 20 H 20 H 20 H 20 H 20 H 20 H 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX
37 DUNN Jackie 23 H 23 H 24 H 29 H 29 H 29 H 29 H 29 H 30 H 30 H 30 H 30 H 30 H 30 H 30 H 30 H 30 H 30 H 30 H 30 H 30 H 30 H 35 H 35 H 35 H 35 H 35 H 35 H 35 H 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX
38 BAKER Stuart 4494 EL 4494 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL 2838 EL
39 KELLAHAN Jessica 104 H 104 H 1486 H 1488 H 1488 H 1491 H 1491 H 1491 H 1491 H 1491 H 1491 H 1492 H 1492 H 1492 H 1492 H 1492 H 1492 H 1492 H 1492 H 1492 H 1492 H 1492 H 1492 H 1492 H 1495 H 1495 H 1495 H 1497 H 1497 H 1498 H 1512 H 1513 H 1513 H 1514 H 1515 H 1518 H 1521 H 1522 H 1526 H 1531 H 1532 H 1540 H 1723 H 1752 H 1792 H 1872 H 1876 H 1876 H 1941 EL
40 MAMOUNEY Stephen 224 H 225 H 278 H 283 H 283 H 288 H 288 H 288 H 288 H 288 H 289 H 289 H 290 H 290 H 290 H 290 H 290 H 290 H 290 H 291 H 291 H 291 H 291 H 291 H 296 H 297 H 297 H 298 H 301 H 304 H 314 H 314 H 315 H 316 H 316 H 319 H 320 H 321 H 322 H 325 H 326 H 331 H 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX
41 CALE Danielle 24 H 24 H 33 H 33 H 33 H 33 H 33 H 33 H 33 H 33 H 33 H 33 H 33 H 33 H 34 H 35 H 36 H 36 H 36 H 36 H 36 H 37 H 38 H 38 H 39 H 39 H 40 H 40 H 40 H 40 H 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX
42 PEMBERTON Louise 17 H 17 H 22 H 22 H 22 H 22 H 22 H 22 H 22 H 22 H 22 H 22 H 22 H 22 H 22 H 22 H 22 H 22 H 22 H 22 H 22 H 22 H 22 H 22 H 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX
43 VAN DE VEN Henk 1240 H 1247 H 1280 H 1300 H 1300 H 1307 H 1307 H 1307 H 1307 H 1307 H 1308 H 1309 H 1310 H 1311 H 1311 H 1311 H 1311 H 1311 H 1311 H 1311 H 1318 H 1319 H 1319 H 1319 H 1320 H 1320 H 1321 H 1322 H 1335 H 1336 H 1337 H 1338 H 1338 H 1338 H 1338 H 1342 H 1344 H 1345 H 1348 H 1361 H 1362 H 1368 H 1380 H 1385 H 1405 H 1431 H 1433 H 1433 H 0 EX
44 PEARCE Garry 13 H 13 H 14 H 14 H 14 H 15 H 15 H 15 H 15 H 15 H 16 H 16 H 17 H 17 H 17 H 17 H 17 H 17 H 17 H 17 H 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX
45 ARMSTRONG Paul 25 H 25 H 26 H 28 H 28 H 28 H 28 H 28 H 28 H 28 H 29 H 29 H 30 H 30 H 30 H 30 H 30 H 30 H 30 H 30 H 33 H 33 H 33 H 33 H 33 H 33 H 33 H 33 H 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX
46 VAN NOORDENNEN Bill 9 H 9 H 9 H 9 H 9 H 9 H 9 H 9 H 9 H 9 H 9 H 9 H 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX
47 MARTIN Christopher 7 H 7 H 7 H 7 H 7 H 7 H 7 H 8 H 8 H 8 H 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX
48 THURLEY David 1211 H 1221 H 1250 H 1272 H 1272 H 1280 H 1280 H 1280 H 1280 H 1282 H 1282 H 1283 H 1285 H 1285 H 1288 H 1289 H 1289 H 1290 H 1290 H 1290 H 1290 H 1304 H 1304 H 1304 H 1305 H 1306 H 1306 H 1306 H 1311 H 1311 H 1312 H 1313 H 1314 H 1314 H 1314 H 1318 H 1333 H 1334 H 1338 H 1348 H 1350 H 1379 H 1394 H 1399 H 1438 H 1465 H 1467 H 1467 H 1617 EL
49 DOYLE Mark 16 H 16 H 16 H 17 H 17 H 17 H 17 H 17 H 17 H 18 H 18 H 18 H 18 H 18 H 19 H 19 H 19 H 19 H 19 H 19 H 19 H 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX
50 HEATHER Esther 5 H 5 H 5 H 5 H 5 H 5 H 5 H 6 H 6 H 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX
51 MOORE John 4 H 4 H 4 H 4 H 4 H 4 H 4 H 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX
52 MACHIN Michael 8 H 8 H 8 H 8 H 8 H 8 H 8 H 8 H 8 H 9 H 10 H 10 H 10 H 10 H 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX
53 HOOD Peter 51 H 51 H 54 H 54 H 54 H 56 H 56 H 57 H 57 H 57 H 57 H 57 H 57 H 57 H 59 H 60 H 60 H 60 H 61 H 61 H 61 H 61 H 61 H 61 H 62 H 62 H 63 H 63 H 64 H 64 H 65 H 66 H 66 H 66 H 67 H 69 H 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX 0 EX

Binary file not shown.

View File

@ -35,7 +35,7 @@ fn ers97_coe_rational() {
.defer_surpluses(true) .defer_surpluses(true)
.build().unwrap(); .build().unwrap();
assert_eq!(stv_opts.describe::<Rational>(), "--round-surplus-fractions 2 --round-values 2 --round-votes 2 --round-quota 2 --sum-surplus-transfers per_ballot --quota-criterion geq --surplus eg --transferable-only --exclusion by_value --defer-surpluses"); assert_eq!(stv_opts.describe::<Rational>(), "--round-surplus-fractions 2 --round-values 2 --round-votes 2 --round-quota 2 --round-subtransfers per_ballot --quota-criterion geq --surplus eg --transferable-only --exclusion by_value --defer-surpluses");
utils::read_validate_election::<Rational>("tests/data/ers97_coe.csv", "tests/data/ers97.blt", stv_opts, None, &["nt"]); utils::read_validate_election::<Rational>("tests/data/ers97_coe.csv", "tests/data/ers97.blt", stv_opts, None, &["nt"]);
} }

View File

@ -1,5 +1,5 @@
/* OpenTally: Open-source election vote counting /* OpenTally: Open-source election vote counting
* Copyright © 2021 Lee Yingtong Li (RunasSudo) * Copyright © 20212022 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
@ -28,6 +28,7 @@ mod equal_ranks;
mod ers; mod ers;
mod meek; mod meek;
mod minneapolis; mod minneapolis;
mod nswlg;
mod prsa; mod prsa;
mod scotland; mod scotland;
mod special_cases; mod special_cases;

41
tests/tests_impl/nswlg.rs Normal file
View File

@ -0,0 +1,41 @@
/* OpenTally: Open-source election vote counting
* Copyright © 20212022 Lee Yingtong Li (RunasSudo)
*
* 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
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
// Compare results under NSW Local Government STV with official results from NSW Electoral Commission
use crate::utils;
use opentally::numbers::Rational;
use opentally::stv;
use opentally::ties::TieStrategy;
#[test]
fn nswlg_albury21_rational() {
let stv_opts = stv::STVOptionsBuilder::default()
.round_votes(Some(0))
.round_quota(Some(0))
.round_subtransfers(stv::RoundSubtransfersMode::ByValueAndSource)
.quota_criterion(stv::QuotaCriterion::GreaterOrEqual)
.ties(vec![TieStrategy::Backwards, TieStrategy::Random(String::from("20220322"))])
.surplus_order(stv::SurplusOrder::ByOrder)
.transferable_only(true)
.build().unwrap();
assert_eq!(stv_opts.describe::<Rational>(), "--round-votes 0 --round-quota 0 --round-subtransfers by_value_and_source --quota-criterion geq --ties backwards random --random-seed 20220322 --surplus-order by_order --transferable-only");
utils::read_validate_election::<Rational>("tests/data/City_of_Albury-finalpreferencedatafile.csv", "tests/data/City_of_Albury-finalpreferencedatafile.blt", stv_opts, None, &[]);
}

View File

@ -40,7 +40,7 @@ fn scotland_linn07_fixed5() {
Fixed::set_dps(5); Fixed::set_dps(5);
assert_eq!(stv_opts.describe::<Fixed>(), "--numbers fixed --decimals 5 --round-surplus-fractions 5 --round-quota 0 --sum-surplus-transfers per_ballot --quota-criterion geq --no-early-bulk-elect --pp-decimals 5"); assert_eq!(stv_opts.describe::<Fixed>(), "--numbers fixed --decimals 5 --round-surplus-fractions 5 --round-quota 0 --round-subtransfers per_ballot --quota-criterion geq --no-early-bulk-elect --pp-decimals 5");
scotland_linn07::<Fixed>(stv_opts); scotland_linn07::<Fixed>(stv_opts);
} }
@ -60,7 +60,7 @@ fn scotland_linn07_gfixed5() {
GuardedFixed::set_dps(5); GuardedFixed::set_dps(5);
assert_eq!(stv_opts.describe::<GuardedFixed>(), "--numbers gfixed --decimals 5 --round-surplus-fractions 5 --round-values 5 --round-votes 5 --round-quota 0 --sum-surplus-transfers per_ballot --quota-criterion geq --no-early-bulk-elect --pp-decimals 5"); assert_eq!(stv_opts.describe::<GuardedFixed>(), "--numbers gfixed --decimals 5 --round-surplus-fractions 5 --round-values 5 --round-votes 5 --round-quota 0 --round-subtransfers per_ballot --quota-criterion geq --no-early-bulk-elect --pp-decimals 5");
scotland_linn07::<GuardedFixed>(stv_opts); scotland_linn07::<GuardedFixed>(stv_opts);
} }