Beyond using Text::CSV as others have suggested, just for fun I have rewritten the code as I might have written it. It includes many of the suggestions made here and a few of my personal style choices. If you have any questions about it please ask. Also if you can post some sample data, I can check to see that it works.
#!/usr/bin/env perl
use strict;
use warnings;
my $lowestBirthRates = 100000000;
my $highestBirthRates = 0;
my $filename = 'census2008.txt';
open (my $fh, '<', $filename) or die "Cannot open $filename: $!";
my %data;
while (<$fh>) {
chomp;
my ($sumlev, $stname,$ctyname,$popestimate2008,$births2008,$deaths2008) = split(",");
push (@{$data{SumLev}}, $sumlev);
push (@{$data{StName}}, $stname);
push (@{$data{CtyName}}, $ctyname);
push (@{$data{PopEstimate}}, $popestimate2008);
push (@{$data{Births}}, $births2008);
push (@{$data{Deaths}}, $deaths2008);
}
my $i = 0;
my $size = @{$data{Births}};
while ($i < $size) {
if ( $data{SumLev}[$i] eq " 040" ){
#if ( $data{SumLev}[$i] == 40 ){
my $temp = $data{Births}[$i] / $data{PopEstimate}[$i] / 541;
if( $lowestBirthRates > $temp && $temp > 0 ){
$lowestBirthRates = $temp;
}
if ( $highestBirthRates < $temp ){
$highestBirthRates = $temp;
}
}
$i++;
}
print <<REPORT;
Lowest birth rate in LOW-STATE: $lowestBirthRates per 541
Highest birth rate in HIGH-STATE: $highestBirthRates per 541
In Washington:
Lowest birth rate in LOW-COUNTY County, WA: x.xxx per 541
Highest birth rate in HIGH-COUNTY County, WA: x.xxx per 541
REPORT
if you have the luxury of having Perl version 5.14 or greater installed, you can use an even clearer syntax, where push
can take references directly, and where each
can give the index in question as well as the value.
#!/usr/bin/env perl
use strict;
use warnings;
use 5.14.0;
my $lowestBirthRates = 100000000;
my $highestBirthRates = 0;
my $filename = 'census2008.txt';
open (my $fh, '<', $filename) or die "Cannot open $filename: $!";
my %data = (
SumLev => [],
StName => [],
CtyName => [],
PopEstimate => [],
Births => [],
Deaths => [],
);
while (<$fh>) {
chomp;
my ($sumlev, $stname,$ctyname,$popestimate2008,$births2008,$deaths2008) = split(",");
push ($data{SumLev}, $sumlev);
push ($data{StName}, $stname);
push ($data{CtyName}, $ctyname);
push ($data{PopEstimate}, $popestimate2008);
push ($data{Births}, $births2008);
push ($data{Deaths}, $deaths2008);
}
while (my ($i, $births) = each $data{Births}) {
if ( $data{SumLev}[$i] eq " 040" ){
#if ( $data{SumLev}[$i] == 40 ){
my $temp = $births / $data{PopEstimate}[$i] / 541;
if( $lowestBirthRates > $temp && $temp > 0 ){
$lowestBirthRates = $temp;
}
if ( $highestBirthRates < $temp ){
$highestBirthRates = $temp;
}
}
}
print <<REPORT;
Lowest birth rate in LOW-STATE: $lowestBirthRates per 541
Highest birth rate in HIGH-STATE: $highestBirthRates per 541
In Washington:
Lowest birth rate in LOW-COUNTY County, WA: x.xxx per 541
Highest birth rate in HIGH-COUNTY County, WA: x.xxx per 541
REPORT
Finally here is an implementation using Tie::Array::CSV
which I wrote to be able to use a CSV file just like a 2D array in Perl (i.e. Array of ArrayRefs). It uses Text::CSV
to do the parsing and Tie::File
to do line access. This means that you don't need to store all the data in memory like in the previous examples.
#!/usr/bin/env perl
use strict;
use warnings;
use Tie::Array::CSV;
my $lowestBirthRates = 100000000;
my $highestBirthRates = 0;
my $filename = 'census2008.txt';
tie my @data, 'Tie::Array::CSV', $filename
or die "Cannot tie $filename: $!";
foreach my $row (@data) {
my ($sumlev, $stname, $ctyname, $popest, $births, $deaths) = @$row;
if ( $sumlev eq " 040" ){
#if ( $sumlev == 40 ){
my $temp = $births / $popest / 541;
if( $lowestBirthRates > $temp && $temp > 0 ){
$lowestBirthRates = $temp;
}
if ( $highestBirthRates < $temp ){
$highestBirthRates = $temp;
}
}
}
print <<REPORT;
Lowest birth rate in LOW-STATE: $lowestBirthRates per 541
Highest birth rate in HIGH-STATE: $highestBirthRates per 541
In Washington:
Lowest birth rate in LOW-COUNTY County, WA: x.xxx per 541
Highest birth rate in HIGH-COUNTY County, WA: x.xxx per 541
REPORT