Anti-Harassment Tools/SecurePoll Improvements/Test Results/20 6 5000 1048374110

Comments
Case: All but one seat filled, rest of candidates hopeful. All surplus votes transferred to candidate 17.

OpenSTV and SecurePoll agree on results.

Election setup

 * Candidates: 20
 * Seats: 6
 * Votes: 5000

Actual
Output from SecurePoll : array(3) { ["elected"]=> array(6) { [0]=>   int(2) [1]=>   int(4) [2]=>   int(6) [3]=>   int(8) [4]=>   int(19) [5]=>   int(17) } ["eliminated"]=> array(4) { [0]=>   int(12) [1]=>   int(10) [2]=>   int(15) [3]=>   int(5) } ["rounds"]=> array(4) { [0]=>   array(8) { ["round"]=> int(1) ["surplus"]=> int(0) ["rankings"]=> array(20) { [1]=>       array(3) { ["votes"]=> int(0) ["earned"]=> int(67) ["total"]=> int(67) }       [2]=>        array(3) { ["votes"]=> int(0) ["earned"]=> int(800) ["total"]=> int(800) }       [3]=>        array(3) { ["votes"]=> int(0) ["earned"]=> int(67) ["total"]=> int(67) }       [4]=>        array(3) { ["votes"]=> int(0) ["earned"]=> int(800) ["total"]=> int(800) }       [5]=>        array(3) { ["votes"]=> int(0) ["earned"]=> int(66) ["total"]=> int(66) }       [6]=>        array(3) { ["votes"]=> int(0) ["earned"]=> int(800) ["total"]=> int(800) }       [7]=>        array(3) { ["votes"]=> int(0) ["earned"]=> int(67) ["total"]=> int(67) }       [8]=>        array(3) { ["votes"]=> int(0) ["earned"]=> int(800) ["total"]=> int(800) }       [9]=>        array(3) { ["votes"]=> int(0) ["earned"]=> int(67) ["total"]=> int(67) }       [10]=>        array(3) { ["votes"]=> int(0) ["earned"]=> int(66) ["total"]=> int(66) }       [11]=>        array(3) { ["votes"]=> int(0) ["earned"]=> int(67) ["total"]=> int(67) }       [12]=>        array(3) { ["votes"]=> int(0) ["earned"]=> int(66) ["total"]=> int(66) }       [13]=>        array(3) { ["votes"]=> int(0) ["earned"]=> int(67) ["total"]=> int(67) }       [14]=>        array(3) { ["votes"]=> int(0) ["earned"]=> int(67) ["total"]=> int(67) }       [15]=>        array(3) { ["votes"]=> int(0) ["earned"]=> int(66) ["total"]=> int(66) }       [16]=>        array(3) { ["votes"]=> int(0) ["earned"]=> int(67) ["total"]=> int(67) }       [17]=>        array(3) { ["votes"]=> int(0) ["earned"]=> int(66) ["total"]=> int(66) }       [18]=>        array(3) { ["votes"]=> int(0) ["earned"]=> int(67) ["total"]=> int(67) }       [19]=>        array(3) { ["votes"]=> int(0) ["earned"]=> int(800) ["total"]=> int(800) }       [20]=>        array(3) { ["votes"]=> int(0) ["earned"]=> int(67) ["total"]=> int(67) }     }      ["totalVotes"]=> int(5000) ["keepFactors"]=> array(20) { [1]=>       int(1) [2]=>       int(1) [3]=>       int(1) [4]=>       int(1) [5]=>       int(1) [6]=>       int(1) [7]=>       int(1) [8]=>       int(1) [9]=>       int(1) [10]=>       int(1) [11]=>       int(1) [12]=>       int(1) [13]=>       int(1) [14]=>       int(1) [15]=>       int(1) [16]=>       int(1) [17]=>       int(1) [18]=>       int(1) [19]=>       int(1) [20]=>       int(1) }     ["quota"]=> int(715) ["elected"]=> array(0) { }     ["eliminated"]=> array(0) { }   }    [1]=>    array(8) { ["round"]=> int(2) ["elected"]=> array(5) { [0]=>       int(2) [1]=>       int(4) [2]=>       int(6) [3]=>       int(8) [4]=>       int(19) }     ["eliminated"]=> array(0) { }     ["surplus"]=> int(425) ["keepFactors"]=> array(20) { [1]=>       int(1) [2]=>       int(1) [3]=>       int(1) [4]=>       int(1) [5]=>       int(1) [6]=>       int(1) [7]=>       int(1) [8]=>       int(1) [9]=>       int(1) [10]=>       int(1) [11]=>       int(1) [12]=>       int(1) [13]=>       int(1) [14]=>       int(1) [15]=>       int(1) [16]=>       int(1) [17]=>       int(1) [18]=>       int(1) [19]=>       int(1) [20]=>       int(1) }     ["quota"]=> int(715) ["rankings"]=> array(20) { [1]=>       array(3) { ["votes"]=> int(67) ["earned"]=> int(0) ["total"]=> int(67) }       [2]=>        array(3) { ["votes"]=> int(800) ["earned"]=> int(0) ["total"]=> int(800) }       [3]=>        array(3) { ["votes"]=> int(67) ["earned"]=> int(0) ["total"]=> int(67) }       [4]=>        array(3) { ["votes"]=> int(800) ["earned"]=> int(0) ["total"]=> int(800) }       [5]=>        array(3) { ["votes"]=> int(66) ["earned"]=> int(0) ["total"]=> int(66) }       [6]=>        array(3) { ["votes"]=> int(800) ["earned"]=> int(0) ["total"]=> int(800) }       [7]=>        array(3) { ["votes"]=> int(67) ["earned"]=> int(0) ["total"]=> int(67) }       [8]=>        array(3) { ["votes"]=> int(800) ["earned"]=> int(0) ["total"]=> int(800) }       [9]=>        array(3) { ["votes"]=> int(67) ["earned"]=> int(0) ["total"]=> int(67) }       [10]=>        array(3) { ["votes"]=> int(66) ["earned"]=> int(0) ["total"]=> int(66) }       [11]=>        array(3) { ["votes"]=> int(67) ["earned"]=> int(0) ["total"]=> int(67) }       [12]=>        array(3) { ["votes"]=> int(66) ["earned"]=> int(0) ["total"]=> int(66) }       [13]=>        array(3) { ["votes"]=> int(67) ["earned"]=> int(0) ["total"]=> int(67) }       [14]=>        array(3) { ["votes"]=> int(67) ["earned"]=> int(0) ["total"]=> int(67) }       [15]=>        array(3) { ["votes"]=> int(66) ["earned"]=> int(0) ["total"]=> int(66) }       [16]=>        array(3) { ["votes"]=> int(67) ["earned"]=> int(0) ["total"]=> int(67) }       [17]=>        array(3) { ["votes"]=> int(66) ["earned"]=> int(0) ["total"]=> int(66) }       [18]=>        array(3) { ["votes"]=> int(67) ["earned"]=> int(0) ["total"]=> int(67) }       [19]=>        array(3) { ["votes"]=> int(800) ["earned"]=> int(0) ["total"]=> int(800) }       [20]=>        array(3) { ["votes"]=> int(67) ["earned"]=> int(0) ["total"]=> int(67) }     }      ["totalVotes"]=> int(5000) }   [2]=>    array(8) { ["round"]=> int(3) ["elected"]=> array(0) { }     ["eliminated"]=> array(4) { [0]=>       int(12) [1]=>       int(10) [2]=>       int(15) [3]=>       int(5) }     ["surplus"]=> float(0) ["keepFactors"]=> array(20) { [1]=>       int(1) [2]=>       float(0.89375) [3]=>       int(1) [4]=>       float(0.89375) [5]=>       int(1) [6]=>       float(0.89375) [7]=>       int(1) [8]=>       float(0.89375) [9]=>       int(1) [10]=>       int(1) [11]=>       int(1) [12]=>       int(1) [13]=>       int(1) [14]=>       int(1) [15]=>       int(1) [16]=>       int(1) [17]=>       int(1) [18]=>       int(1) [19]=>       float(0.89375) [20]=>       int(1) }     ["quota"]=> int(715) ["rankings"]=> array(20) { [1]=>       array(3) { ["votes"]=> int(67) ["earned"]=> int(0) ["total"]=> int(67) }       [2]=>        array(3) { ["votes"]=> int(800) ["earned"]=> float(-85) ["total"]=> float(715) }       [3]=>        array(3) { ["votes"]=> int(67) ["earned"]=> int(0) ["total"]=> int(67) }       [4]=>        array(3) { ["votes"]=> int(800) ["earned"]=> float(-85) ["total"]=> float(715) }       [5]=>        array(3) { ["votes"]=> int(66) ["earned"]=> int(0) ["total"]=> int(66) }       [6]=>        array(3) { ["votes"]=> int(800) ["earned"]=> float(-85) ["total"]=> float(715) }       [7]=>        array(3) { ["votes"]=> int(67) ["earned"]=> int(0) ["total"]=> int(67) }       [8]=>        array(3) { ["votes"]=> int(800) ["earned"]=> float(-85) ["total"]=> float(715) }       [9]=>        array(3) { ["votes"]=> int(67) ["earned"]=> int(0) ["total"]=> int(67) }       [10]=>        array(3) { ["votes"]=> int(66) ["earned"]=> int(0) ["total"]=> int(66) }       [11]=>        array(3) { ["votes"]=> int(67) ["earned"]=> int(0) ["total"]=> int(67) }       [12]=>        array(3) { ["votes"]=> int(66) ["earned"]=> int(0) ["total"]=> int(66) }       [13]=>        array(3) { ["votes"]=> int(67) ["earned"]=> int(0) ["total"]=> int(67) }       [14]=>        array(3) { ["votes"]=> int(67) ["earned"]=> int(0) ["total"]=> int(67) }       [15]=>        array(3) { ["votes"]=> int(66) ["earned"]=> int(0) ["total"]=> int(66) }       [16]=>        array(3) { ["votes"]=> int(67) ["earned"]=> int(0) ["total"]=> int(67) }       [17]=>        array(3) { ["votes"]=> int(66) ["earned"]=> float(425) ["total"]=> float(491) }       [18]=>        array(3) { ["votes"]=> int(67) ["earned"]=> int(0) ["total"]=> int(67) }       [19]=>        array(3) { ["votes"]=> int(800) ["earned"]=> float(-85) ["total"]=> float(715) }       [20]=>        array(3) { ["votes"]=> int(67) ["earned"]=> int(0) ["total"]=> int(67) }     }      ["totalVotes"]=> float(5000) }   [3]=>    array(8) { ["round"]=> int(4) ["elected"]=> array(1) { [4]=>       int(17) }     ["eliminated"]=> array(0) { }     ["surplus"]=> float(40) ["keepFactors"]=> array(20) { [1]=>       int(1) [2]=>       float(0.89375) [3]=>       int(1) [4]=>       float(0.89375) [5]=>       int(0) [6]=>       float(0.89375) [7]=>       int(1) [8]=>       float(0.89375) [9]=>       int(1) [10]=>       int(0) [11]=>       int(1) [12]=>       int(0) [13]=>       int(1) [14]=>       int(1) [15]=>       int(0) [16]=>       int(1) [17]=>       int(1) [18]=>       int(1) [19]=>       float(0.89375) [20]=>       int(1) }     ["quota"]=> int(715) ["rankings"]=> array(20) { [1]=>       array(3) { ["votes"]=> int(67) ["earned"]=> int(0) ["total"]=> int(67) }       [2]=>        array(3) { ["votes"]=> float(715) ["earned"]=> float(0) ["total"]=> float(715) }       [3]=>        array(3) { ["votes"]=> int(67) ["earned"]=> int(0) ["total"]=> int(67) }       [4]=>        array(3) { ["votes"]=> float(715) ["earned"]=> float(0) ["total"]=> float(715) }       [5]=>        array(3) { ["votes"]=> int(66) ["earned"]=> int(-66) ["total"]=> int(0) }       [6]=>        array(3) { ["votes"]=> float(715) ["earned"]=> float(0) ["total"]=> float(715) }       [7]=>        array(3) { ["votes"]=> int(67) ["earned"]=> int(0) ["total"]=> int(67) }       [8]=>        array(3) { ["votes"]=> float(715) ["earned"]=> float(0) ["total"]=> float(715) }       [9]=>        array(3) { ["votes"]=> int(67) ["earned"]=> int(0) ["total"]=> int(67) }       [10]=>        array(3) { ["votes"]=> int(66) ["earned"]=> int(-66) ["total"]=> int(0) }       [11]=>        array(3) { ["votes"]=> int(67) ["earned"]=> int(0) ["total"]=> int(67) }       [12]=>        array(3) { ["votes"]=> int(66) ["earned"]=> int(-66) ["total"]=> int(0) }       [13]=>        array(3) { ["votes"]=> int(67) ["earned"]=> int(0) ["total"]=> int(67) }       [14]=>        array(3) { ["votes"]=> int(67) ["earned"]=> int(0) ["total"]=> int(67) }       [15]=>        array(3) { ["votes"]=> int(66) ["earned"]=> int(-66) ["total"]=> int(0) }       [16]=>        array(3) { ["votes"]=> int(67) ["earned"]=> int(0) ["total"]=> int(67) }       [17]=>        array(3) { ["votes"]=> float(491) ["earned"]=> float(264) ["total"]=> float(755) }       [18]=>        array(3) { ["votes"]=> int(67) ["earned"]=> int(0) ["total"]=> int(67) }       [19]=>        array(3) { ["votes"]=> float(715) ["earned"]=> float(0) ["total"]=> float(715) }       [20]=>        array(3) { ["votes"]=> int(67) ["earned"]=> int(0) ["total"]=> int(67) }     }      ["totalVotes"]=> float(5000) } } }

Expected
Output from OpenSTV: Loading ballots from file 20_6_5000_1048374110.blt. Ballot file contains 20 candidates and 5000 ballots. No candidates have withdrawn. Ballot file contains 5000 non-empty ballots.

Counting votes for ElectionTitle using Meek STV. 20 candidates running for 6 seats.

R|1         |2          |3          |4          |5          |6 |---+---+---+---+---+--- |7          |8          |9          |10         |11         |12           |---+---+---+---+---+---  |13         |14         |15         |16         |17         |18           |---+---+---+---+---+---  |19         |20         |Exhausted  |Surplus    |Threshold

=
============================================================= 1| 67.000000| 800.000000|  67.000000| 800.000000|  66.000000| 800.000000  |  67.000000| 800.000000|  67.000000|  66.000000|  67.000000|  66.000000  |  67.000000|  67.000000|  66.000000|  67.000000|  66.000000|  67.000000  | 800.000000|  67.000000|   0.000000| 428.571425| 714.285715  |---  | Count of first choices. Candidates 2, 4, 6, 8, and 19 have reached the | threshold and are elected.

=
============================================================= 2| 67.000000| 714.286400|  67.000000| 714.286400|  66.000000| 714.286400  |  67.000000| 714.286400|  67.000000|  66.000000|  67.000000|  66.000000  |  67.000000|  67.000000|  66.000000|  67.000000| 494.568000|  67.000000  | 714.286400|  67.000000|   0.000000|   0.003425| 714.285715  |---  | Count after transferring surplus votes. Keep factors of candidates who | have exceeded the threshold: 2, 0.892858; 4, 0.892858; 6, 0.892858; 8, | 0.892858; and 19, 0.892858.

=
============================================================= 3| 67.000000| 714.286400|  67.000000| 714.286400|  66.000000| 714.286400  |  67.000000| 714.286400|  67.000000|  66.000000|  67.000000|  66.000000  |  67.000000|  67.000000|  66.000000|  67.000000| 494.568000|  67.000000  | 714.286400|  67.000000|   0.000000|   0.003425| 714.285715  |---  | Count after transferring surplus votes. Keep factors of candidates who | have exceeded the threshold: 2, 0.892858; 4, 0.892858; 6, 0.892858; 8, | 0.892858; and 19, 0.892858.

=
============================================================= 4| 67.000000| 714.286400|  67.000000| 714.286400|           | 714.286400  |  67.000000| 714.286400|  67.000000|  66.000000|  67.000000|  66.000000  |  67.000000|  67.000000|  66.000000|  67.000000| 560.568000|  67.000000  | 714.286400|  67.000000|   0.000000|   0.003425| 714.285715  |---  | Count after eliminating 5 and transferring votes. Candidates tied | within precision of computations. Candidates 5, 10, 12, and 15 were | tied when choosing candidates to eliminate. Candidate 5 was chosen by | breaking the tie randomly.

=
============================================================= 5| 67.000000| 714.286400|  67.000000| 714.286400|           | 714.286400  |  67.000000| 714.286400|  67.000000|  66.000000|  67.000000|  66.000000  |  67.000000|  67.000000|  66.000000|  67.000000| 560.568000|  67.000000  | 714.286400|  67.000000|   0.000000|   0.003425| 714.285715  |---  | Count after transferring surplus votes. Keep factors of candidates who | have exceeded the threshold: 2, 0.892858; 4, 0.892858; 6, 0.892858; 8, | 0.892858; and 19, 0.892858.

=
============================================================= 6| 67.000000| 714.286400|  67.000000| 714.286400|           | 714.286400  |  67.000000| 714.286400|  67.000000|           |  67.000000|  66.000000  |  67.000000|  67.000000|  66.000000|  67.000000| 626.568000|  67.000000  | 714.286400|  67.000000|   0.000000|   0.003425| 714.285715  |---  | Count after eliminating 10 and transferring votes. Candidates tied | within precision of computations. Candidates 10, 12, and 15 were tied | when choosing candidates to eliminate. Candidate 10 was chosen by | breaking the tie randomly.

=
============================================================= 7| 67.000000| 714.286400|  67.000000| 714.286400|           | 714.286400  |  67.000000| 714.286400|  67.000000|           |  67.000000|  66.000000  |  67.000000|  67.000000|  66.000000|  67.000000| 626.568000|  67.000000  | 714.286400|  67.000000|   0.000000|   0.003425| 714.285715  |---  | Count after transferring surplus votes. Keep factors of candidates who | have exceeded the threshold: 2, 0.892858; 4, 0.892858; 6, 0.892858; 8, | 0.892858; and 19, 0.892858.

=
============================================================= 8| 67.000000| 714.286400|  67.000000| 714.286400|           | 714.286400  |  67.000000| 714.286400|  67.000000|           |  67.000000|             |  67.000000|  67.000000|  66.000000|  67.000000| 692.568000|  67.000000  | 714.286400|  67.000000|   0.000000|   0.003425| 714.285715  |---  | Count after eliminating 12 and transferring votes. Candidates tied | within precision of computations. Candidates 12 and 15 were tied when | choosing candidates to eliminate. Candidate 12 was chosen by breaking | the tie randomly.

=
============================================================= 9| 67.000000| 714.286400|  67.000000| 714.286400|           | 714.286400  |  67.000000| 714.286400|  67.000000|           |  67.000000|             |  67.000000|  67.000000|           |  67.000000| 758.568000|  67.000000  | 714.286400|  67.000000|   0.000000|  44.285710| 714.285715  |---  | Count after eliminating 15 and transferring votes. All losing | candidates are eliminated. Candidate 17 has reached the threshold and | is elected.

Winners are 2, 4, 6, 8, 17, and 19.

Files
array ( 7 =>   array ( 'count' => 67, 'rank' => array (     1 => 7,    ), ), '6_17' =>   array ( 'count' => 800, 'rank' => array (     1 => 6,      2 => 17,    ), ), '5_17' =>   array ( 'count' => 66, 'rank' => array (     1 => 5,      2 => 17,    ), ), '12_17' =>   array ( 'count' => 66, 'rank' => array (     1 => 12,      2 => 17,    ), ), 14 =>   array ( 'count' => 67, 'rank' => array (     1 => 14,    ), ), '8_17' =>   array ( 'count' => 800, 'rank' => array (     1 => 8,      2 => 17,    ), ), '2_17' =>   array ( 'count' => 800, 'rank' => array (     1 => 2,      2 => 17,    ), ), 16 =>   array ( 'count' => 67, 'rank' => array (     1 => 16,    ), ), 18 =>   array ( 'count' => 67, 'rank' => array (     1 => 18,    ), ), 17 =>   array ( 'count' => 66, 'rank' => array (     1 => 17,    ), ), 1 =>   array ( 'count' => 67, 'rank' => array (     1 => 1,    ), ), '15_17' =>   array ( 'count' => 66, 'rank' => array (     1 => 15,      2 => 17,    ), ), 11 =>   array ( 'count' => 67, 'rank' => array (     1 => 11,    ), ), 20 =>   array ( 'count' => 67, 'rank' => array (     1 => 20,    ), ), '4_17' =>   array ( 'count' => 800, 'rank' => array (     1 => 4,      2 => 17,    ), ), 13 =>   array ( 'count' => 67, 'rank' => array (     1 => 13,    ), ), 9 =>   array ( 'count' => 67, 'rank' => array (     1 => 9,    ), ), '10_17' =>   array ( 'count' => 66, 'rank' => array (     1 => 10,      2 => 17,    ), ), 3 =>   array ( 'count' => 67, 'rank' => array (     1 => 3,    ), ), '19_17' =>   array ( 'count' => 800, 'rank' => array (     1 => 19,      2 => 17,    ), ), )
 * blt: https://github.com/dominic998/SecurePoll-Test-Data/blob/main/test_data/20_6_5000_1048374110.blt
 * php:

Environment

 * Where you tested: local docker using phpunit
 * Version of SecurePoll: commit 271145d5f3cae3b0a1b76d0f5dfeb609615d60b7 (patch 16 from https://gerrit.wikimedia.org/r/c/mediawiki/extensions/SecurePoll/+/704454/)