File Coverage

blib/lib/Vote/Count/Helper/FullCascadeCharge.pm
Criterion Covered Total %
statement 51 52 98.0
branch 9 10 90.0
condition n/a
subroutine 9 9 100.0
pod 0 1 0.0
total 69 72 95.8


line stmt bran cond sub pod time code
1 5     5   836 use strict;
  5         12  
  5         212  
2 5     5   33 use warnings;
  5         10  
  5         145  
3 5     5   108 use 5.024;
  5         20  
4              
5             package Vote::Count::Helper::FullCascadeCharge;
6 5     5   115 no warnings 'experimental';
  5         13  
  5         262  
7 5     5   34 use feature qw /postderef signatures/;
  5         26  
  5         603  
8 5     5   41 use Sort::Hash;
  5         65  
  5         306  
9 5     5   2077 use Vote::Count::TextTableTiny qw/generate_table/;
  5         16  
  5         435  
10              
11             our $VERSION='2.00';
12              
13             # ABSTRACT: Non OO Components for the Vote::Charge implementation of STV.
14              
15             =head1 NAME
16              
17             Vote::Count::Helper::FullCascadeCharge
18              
19             =head1 VERSION 2.00
20              
21             =cut
22              
23             =pod
24              
25             =head1 SYNOPSIS
26              
27             use Vote::Count::Helper::FullCascadeCharge;
28             my $charged = FullCascadeCharge(
29             $Election->GetBallots(), $quota, $cost, $active, $votevalue );
30              
31             =head1 FullCascadeCharge
32              
33             Performs a full Cascading Charge of the Ballots. It takes a list of choices to be elected, with the Vote Value to be charged for each of these. It walks through the Ballots and looks at each choice on the ballot in order. If the choice is elected the vote is charged (up to the remaining vote value) the specified charge and then continues to the next choice on the ballot. If the choice is in the active list (hopeful) it stops processing the choice on the ballot and moves on to the next ballot, otherwise it will continue until the ballot exhausts its choices or vote value.
34              
35             Parameters are Ballots, Quota, Cost (HashRef of elected choices and the charge to each), Active Set (HashRef), and the VoteValue assigned initially to the Ballots.
36              
37             Return Value is a HashRef where the keys are the Elected Choices, the values are a HashRef with the keys: value, count, surplus. The value key is the total Vote Value charged for that choice, the count is the number of Ballots which contributed any amount to that charge, and finally the surplus is the amount of value over or under (negative) the quota.
38              
39             The method is non-OO (thus the need to import it). This permits isolation of values, which may be needed for performing estimations to establish the Costs.
40              
41             The Ballots are passed as a HashRef and the votevalue will be modified, if you do not want the Ballots modified, provide a copy of them (Storable 'dclone' is recommended)
42              
43             =cut
44              
45             use Exporter::Easy (
46 5         43 EXPORT => [ 'FullCascadeCharge' ],
47 5     5   2271 );
  5         6363  
48              
49 34     34 0 8750 sub FullCascadeCharge ( $ballots, $quota, $cost, $active, $votevalue ) {
  34         63  
  34         56  
  34         57  
  34         59  
  34         52  
  34         53  
50 34         2839 for my $b ( keys $ballots->%* ) {
51 23414         35862 $ballots->{$b}{'votevalue'} = $votevalue;
52             }
53             my %chargedval =
54 34         871 map { $_ => { value => 0, count => 0, surplus => 0 } } ( keys $cost->%* );
  89         403  
55             FullChargeBALLOTLOOP1:
56 34         1262 for my $V ( values $ballots->%* ) {
57 23414 50       41390 unless ( $V->{'votevalue'} > 0 ) { next FullChargeBALLOTLOOP1 }
  0         0  
58             FullChargeBALLOTLOOP2:
59 23414         37300 for my $C ( $V->{'votes'}->@* ) {
60 35745 100       67190 if ( $active->{$C} ) { last FullChargeBALLOTLOOP2 }
  17943 100       26606  
61             elsif ( $cost->{$C} ) {
62 17703         22971 my $charge = do {
63 17703 100       30161 if ( $V->{'votevalue'} >= $cost->{$C} ) { $cost->{$C} }
  12335         18721  
64 5368         7970 else { $V->{'votevalue'} }
65             };
66 17703         24776 $V->{'votevalue'} -= $charge;
67 17703         28884 $chargedval{$C}{'value'} += $charge * $V->{'count'};
68 17703         26698 $chargedval{$C}{'count'} += $V->{'count'};
69 17703 100       32674 unless ( $V->{'votevalue'} > 0 ) { last FullChargeBALLOTLOOP2 }
  5370         8721  
70             }
71             }
72             }
73 34         140 for my $E ( keys %chargedval ) {
74 89         189 $chargedval{$E}{'surplus'} = $chargedval{$E}{'value'} - $quota;
75             }
76 34         161 return \%chargedval;
77             }
78              
79             1;
80              
81             #FOOTER
82              
83             =pod
84              
85             BUG TRACKER
86              
87             L<https://github.com/brainbuz/Vote-Count/issues>
88              
89             AUTHOR
90              
91             John Karr (BRAINBUZ) brainbuz@cpan.org
92              
93             CONTRIBUTORS
94              
95             Copyright 2019-2021 by John Karr (BRAINBUZ) brainbuz@cpan.org.
96              
97             LICENSE
98              
99             This module is released under the GNU Public License Version 3. See license file for details. For more information on this license visit L<http://fsf.org>.
100              
101             SUPPORT
102              
103             This software is provided as is, per the terms of the GNU Public License. Professional support and customisation services are available from the author.
104              
105             =cut
106