aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'Votify.pm')
-rw-r--r--Votify.pm49
1 files changed, 35 insertions, 14 deletions
diff --git a/Votify.pm b/Votify.pm
index 87fba2f..35a717f 100644
--- a/Votify.pm
+++ b/Votify.pm
@@ -8,13 +8,13 @@
package Votify;
-use POSIX;
+use Carp::Always;
use Cwd qw(abs_path);
+use Data::Dumper;
use File::Basename;
use File::Spec::Functions;
use List::Util;
-use Data::Dumper;
-use Carp::Always;
+use POSIX;
use strict;
use warnings;
@@ -218,8 +218,8 @@ sub new {
close(F);
# assign confirmation numbers randomly
- for my $v (@voterlist) {
- do { $r = int rand 0xffff } while exists $self->{'voters'}{$r};
+ for my $v (List::Util::shuffle(@voterlist)) {
+ do { $r = int rand 0xffffffff } while exists $self->{'voters'}{$r};
$self->{'voters'}{$r} = $v;
$self->{'confs'}{$v} = $r;
}
@@ -239,7 +239,7 @@ sub confs {
sub voters {
my ($self) = @_;
- sort keys %{$self->{'confs'}};
+ return sort keys %{$self->{'confs'}};
}
sub getvoter {
@@ -252,7 +252,7 @@ sub getconf {
return $self->{'confs'}{$voter};
}
-sub write {
+sub write_confs {
my ($self, $filename) = @_;
$filename ||= $self->{'default_filename'};
@@ -263,8 +263,8 @@ sub write {
}
open(F, ">$filename") or die("can't write to $filename");
- for my $c ($self->confs) {
- printf F "%04x %s\n", $c, $self->getvoter($c);
+ for my $c (sort { $a <=> $b } map { int $_ } $self->confs) {
+ printf F "%08x %s\n", $c, $self->getvoter($c);
}
close F;
}
@@ -287,6 +287,7 @@ sub new {
default_filename => catfile($datadir, "master-$election_name"),
filename => '',
voterlist => $vl,
+ casting_voters => {}, # indexed by voter
ballots => {}, # indexed by conf num
candidates => undef, # indexed by long name
table => undef, # indexed by row+column
@@ -326,6 +327,7 @@ sub collect {
next;
}
$self->{'ballots'}{$c} = $b;
+ $self->{'casting_voters'}{$v} = 1;
}
elsif (-f "$home/.ballot-$self->{election}") {
print STDERR "Warning: $v did not submit their ballot\n";
@@ -333,7 +335,7 @@ sub collect {
}
}
-sub write {
+sub write_master {
my ($self, $filename) = @_;
$filename ||= $self->{'default_filename'};
@@ -344,14 +346,15 @@ sub write {
}
open(F, ">$filename") or die("can't write to $filename");
- for my $c (sort keys %{$self->{'ballots'}}) {
- printf F "--------- confirmation %04x ---------\n", $c;
+ for my $c (sort { $a <=> $b } map { int $_ } keys %{$self->{'ballots'}}) {
+ my $confid = sprintf("%08x",$c);
+ printf F "--------- confirmation %s ---------\n", $confid;
print F $self->{'ballots'}{$c}->to_s
}
close F;
}
-sub read {
+sub read_master {
my ($self, $filename) = @_;
my ($election, $entries) = $self->{'election'};
@@ -362,7 +365,7 @@ sub read {
{ local $/ = undef; $entries = <F>; }
for my $e (split /^--------- confirmation /m, $entries) {
next unless $e; # skip the first zero-length record
- unless ($e =~ /^([[:xdigit:]]{4}) ---------\n(.*)$/s) {
+ unless ($e =~ /^([[:xdigit:]]{4,12}) ---------\n(.*)$/s) {
die "error parsing entry:\n$e";
}
my ($c, $s, $b) = ($1, $2, Ballot->new($election));
@@ -371,6 +374,24 @@ sub read {
}
}
+sub write_casting_voters {
+ my ($self, $filename) = @_;
+
+ $filename ||= $self->{'default_filename'};
+ $self->{'filename'} = $filename;
+
+ if (-f $filename) {
+ die "$filename already exists; please remove it first";
+ }
+
+ open(F, ">$filename") or die("can't write to $filename");
+ for my $v (sort keys %{$self->{'casting_voters'}}) {
+ printf F "%s\n", $v;
+ }
+ close F;
+}
+
+
sub generate_candidates {
my ($self) = @_;
my ($B, @C, $s);