Category: Misc
Author/Contact Info
Description:

This is makes it simple to watch lots of races. I happened to be interested in the Green Party's races and a particular judge that did an excellent job once. Write your own contents for main(). See http://electionresults.sos.state.mn.us/20041102/media.asp for the list of available data.

Sample output

US REPRESENTATIVE DISTRICT 05 84.1 precincts reporting Party Candidate Percent DFL MARTIN OLAV SABO 69.3 R DANIEL MATHIAS 24.9 GP JAY POND 5.6 WI WRITE-IN** 0.2

use strict;
use warnings;
use YAML 'Dump';
use LWP::Simple 'get';
use Text::Table ();
use Memoize 'memoize';
use Hash::Util 'lock_hash';
use List::Util 'first';
use vars qw( @Fields %Races );
@Fields = ( map { s/^\s+//;
                       s/\s+$//;
                  s/\s+\W*(\w)/uc $1/eg;
                  s/\W+(\w)/uc $1/ge;
                  $_; }
            split /[\r\n]+/, q[ State
        County ID
        Precinct Number
        Office ID
        Office Name
        District
        Candidate ID
        Candidate Name
        Suffix
        Incumbent Code
        Party ID
        Precincts Reporting
        Total Precincts
        Votes for Candidate
        PercentVote
        Total Vote] );
%Races = ( Presidential => 'PresSW',
           StateLegislative => 'StHouseDst',
           USHouse => 'USHouseDst',
           County => 'counties',
           Judicial => 'judicialdst' );
while ( my ( $sub, $file ) = each %Races ) {
  $sub .= "Results";
  {
    no strict 'refs';
    *$sub = sub {
      FetchResults( "http://electionresults.sos.state.mn.us/20041102/m
+edia/$file.txt" );
    };
  }
  memoize $sub;
}

$| = 1;

main();
exit;

sub RacesWithGreenPartyCandidates {
  my @r = @_;
  my %green_races;
  @green_races{ map $_->{'OfficeName'},
                  grep $_->{'PartyID'} =~ /GP|BL/,
                    @r }
    = ();

  return
    grep exists $green_races{$_->{'OfficeName'}},
      @r;
}

sub LaJuneThomasLange {
  my @r = @_;
  my $race = first { $_->{'CandidateName'} eq 'LAJUNE THOMAS LANGE' }
    @r;
  $race = $race->{'OfficeName'};
  
  return
    grep $_->{'OfficeName'} eq $race,
      @r;
}

sub main {
  for ( \ &PresidentialResults,
        \ &USHouseResults,
        \ &StateLegislativeResults ) {
    my @results = $_->();
    Report( \ &RacesWithGreenPartyCandidates,
        \ @results );
  }
  Report( \ &LaJuneThomasLange,
      [ JudicialResults() ] );

  1;
}

sub Report {
  my $filter = shift;
  my @all_results = $filter->( @{ shift() } );
  my %races;
  $races{$_->{'OfficeName'}} = () for @all_results;
  
  for my $race ( sort keys %races ) {
    my @results =
      grep $_->{'OfficeName'} eq $race,
    @all_results;
    
    my $tbl = Text::Table->new( 'Party', 'Candidate', 'Percent' );
    $tbl->load( map { [ $_->{'PartyID'},
            $_->{'CandidateName'},
            sprintf( "%0.1f", $_->{'PercentVote'} ) ] }
        sort { $b->{'PercentVote'} <=> $a->{'PercentVote'} }
        @results );
    
    print( "$race\n"
       . sprintf( "%0.1f", 100 * ( $results[0]{'PrecinctsReporting'} /
+ $results[0]{'TotalPrecincts'} ) )
       . " precincts reporting\n"
       . $tbl
       . "\n" );
  }
}

sub FetchResults {
  my $url = shift;
  
  return
    map { my %h;
      @h{@Fields} = split /;/;
      for ( values %h ) {
        s/^\s+//;
        s/\s+/ /g;
        s/\s+$//;
      }
      lock_hash( %h );
      \ %h }
      split /[\r\n]+/, get( $url );
}