File Coverage

blib/lib/Vote/Count/TopCount.pm
Criterion Covered Total %
statement 68 68 100.0
branch 10 10 100.0
condition n/a
subroutine 12 12 100.0
pod 2 3 66.6
total 92 93 98.9


line stmt bran cond sub pod time code
1 9     9   4845 use strict;
  9         19  
  9         294  
2 9     9   50 use warnings;
  9         15  
  9         311  
3 9     9   176 use 5.022;
  9         26  
4              
5 9     9   42 use feature qw /postderef signatures/;
  9         14  
  9         900  
6              
7             package Vote::Count::TopCount;
8 9     9   51 use Moose::Role;
  9         73  
  9         70  
9              
10 9     9   44749 no warnings 'experimental';
  9         18  
  9         412  
11 9     9   54 use List::Util qw( min max );
  9         14  
  9         727  
12 9     9   3974 use Vote::Count::RankCount;
  9         23  
  9         320  
13 9     9   75 use TextTableTiny 'generate_markdown_table';
  9         16  
  9         4680  
14             # use boolean;
15             # use Data::Printer;
16              
17             our $VERSION='0.007';
18              
19             =head1 NAME
20              
21             Vote::Count::TopCount
22              
23             =head1 VERSION 0.007
24              
25             =cut
26              
27 72     72 0 114 sub TopCount ( $self, $active=undef ) {
  72         115  
  72         112  
  72         89  
28 72         1777 my %ballotset = $self->BallotSet()->%*;
29 72         349 my %ballots = ( $ballotset{'ballots'}->%* );
30 72 100       187 $active = $ballotset{'choices'} unless defined $active ;
31 72         187 my %topcount = ( map { $_ => 0 } keys( $active->%* ));
  378         658  
32             TOPCOUNTBALLOTS:
33 72         220 for my $b ( keys %ballots ) {
34 595         1129 my @votes = $ballots{$b}->{'votes'}->@* ;
35 595         693 for my $v ( @votes ) {
36 793 100       1176 if ( defined $topcount{$v} ) {
37 569         874 $topcount{$v} += $ballots{$b}{'count'};
38 569         1008 next TOPCOUNTBALLOTS;
39             }
40             }
41             }
42 72         397 return Vote::Count::RankCount->Rank( \%topcount );
43             }
44              
45             =head2 TopCountMajority
46              
47             $self->TopCountMajority( $round_topcount )
48             or
49             $self->TopCountMajority( undef, $active_choices )
50              
51             Will find the majority winner from the results of a topcount, or alternately may be given undef and a hashref of active choices and will topcount the ballotset for just those choices and then find the majority winner.
52              
53             Returns a hashref of results. It will always include the votes in the round and the thresshold for majority. If there is a winner it will also include the winner and winvotes.
54              
55             =cut
56              
57 49     49 1 75 sub TopCountMajority ( $self, $topcount = undef, $active = undef ) {
  49         56  
  49         62  
  49         59  
  49         51  
58 49 100       98 unless ( defined $topcount ) { $topcount = $self->TopCount($active) }
  1         4  
59 49         138 my $topc = $topcount->RawCount();
60 49         177 my $numvotes = $topcount->CountVotes();
61 49         128 my @choices = keys $topc->%*;
62 49         131 my $thresshold = 1 + int( $numvotes / 2 );
63 49         91 for my $t (@choices) {
64 235 100       374 if ( $topc->{$t} >= $thresshold ) {
65             return (
66             {
67             votes => $numvotes,
68             thresshold => $thresshold,
69             winner => $t,
70 10         60 winvotes => $topc->{$t}
71             }
72             );
73             }
74             }
75             # No winner
76             return (
77             {
78 39         161 votes => $numvotes,
79             thresshold => $thresshold
80             }
81             );
82             }
83              
84             =head2 EvaluateTopCountMajority
85              
86             This method wraps TopCountMajority adding logging, the logging of which would be a lot of boiler plate in round oriented methods. It takes the same parameters and returns the same hashref.
87              
88             =cut
89              
90 47     47 1 74 sub EvaluateTopCountMajority ( $self, $topcount = undef, $active = undef) {
  47         66  
  47         58  
  47         71  
  47         50  
91 47         126 my $majority = $self->TopCountMajority( $topcount, $active );
92 47 100       116 if ( $majority->{'winner'} ) {
93 9         22 my $winner = $majority->{'winner'};
94             my $rows = [
95             [ 'Winner', $winner ],
96             [ 'Votes in Final Round', $majority->{'votes'} ],
97             [ 'Votes Needed for Majority', $majority->{'thresshold'} ],
98 9         46 [ 'Winning Votes', $majority->{'winvotes'} ],
99             ];
100 9         36 $self->logt(
101             '---',
102             generate_markdown_table(
103             rows => $rows,
104             header_row => 0
105             )
106             );
107             }
108 47         99 return $majority;
109             }
110              
111             1;