On Sep 17, 2012, at 3:23 PM, Chris Stinemetz wrote:

> Sorry forgot you wanted the average.
> Revised program is below:
> 
> #!/usr/bin/perl
> 
> use strict;
> use warnings;
> use Data::Dumper;
> 
> my %hash;
> my $counter;
> 
> while ( my $line = <DATA> ) {
> 
>    my @record = split( /\s+/, $line );
> 
>    ## check to see if we've already added the 3rd column to the hash
>    ## if we have, start counting how many times is shows up
>    ## else add it to the hash with the values of @record[ 0 .. 2 ] and
>    ## counter starting at 1 since first occurence
>    if ( defined $hash{ $record[2]} ) {
>        $counter++;
>        my @trec = @{ $hash{$record[2]} };
> 
>        $hash{$record[2]} = [
>            $trec[0], $trec[1] + $record[1],
>            $trec[2], $counter, avg( $trec[1], $record[1], $counter )
>        ];
> 
> 
>    }
> 
>    else {
>        $hash{ $record[2] } = [ @record[ 0 .. 2 ] ];
>        $counter = 1;
> 
> 
>    }
> }

You are using one variable ($count) to keep track of counts. That only works if 
the data are sorted by keys. It would be better to keep a counter for each key.

You have an anonymous array of five members to save the data for each key. With 
that many elements, you might want to use a hash so you can label each member. 
However, you really only need to keep the running sum of values, the count, and 
the key. Keeping the key in the data structure is redundant, so you only need 
two elements for each key.

Taking your program and applying these suggestions gives the following:

#!/usr/bin/perl
use strict;
use warnings;

my %hash;

# read the data
while ( my $line = <DATA> ) {
    next if $line =~ /^DBS/;
    next if $line =~ /^\s*$/;
    my( undef, $value, $key ) = split( /\s+/, $line );
    $hash{$key}{count}++;
    $hash{$key}{sum} += $value;
}

# print the results
for my $key ( sort keys %hash ) {
    my $count = $hash{$key}{count};
    my $total = $hash{$key}{sum};
    my $avg = $total/$count;
    printf("%18s  %3d  %6.4f\n", $key, $count, $avg);
}

... yielding:

  POPTR_0002s00200   10  0.3899
  POPTR_0002s00210   10  0.1853



--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/


Reply via email to