in reply to Calculating the average of a column in a flat-file database

Greetings suggus,

Try this...

open(HANDLE,"script_integration_records"); while (<HANDLE>) { @temp1 = split(/:/); $domain = unpack ("A4", $temp1[40]); if (($domain eq "ATM") && ($temp1[36] eq "In Production")) { $sum += $temp1[38]; $count++; } } close(HANDLE); $average = $sum / $count; print $average, "\n";

-gryphon
code('Perl') || die;

UPDATE:

Well, here's a smaller version of the above. I'm sure I could use map to get this in a line or two less, but I'm still having difficulties really getting my mind around complicated multi-calls of map. (Anyone out there know a tutorial on map?)

open(HANDLE, 'script_integration_records'); foreach (grep /^(?:[^:]*:){36}In Production:/, <HANDLE>) { my @line = split(/:/); push @numbers, $line[38] if (unpack("A4", $line[40]) eq "ATM"); } close(HANDLE); print eval(join('+',@numbers))/($#numbers+1), "\n";

Theoretically, you could run multiple greps against eachother to get just a single array. Then just average the array. Also, I have a general "ungood" feeling about using eval anywhere for any reason. Perhaps it's just a personal problem, but I have this fear of stuff being executed without my pre-knowledge of its contents.

-gryphon
code('Perl') || die;

Replies are listed 'Best First'.
Re: Re: Calculating the average of a column in a flat-file database
by Hofmator (Curate) on Oct 26, 2001 at 13:34 UTC

    Let me add a few comments and suggestions:

    • I would declare all variables with my, otherwise you might run into problems later - apart from the fact that it won't run under use strict.
    • You were looking for a map solution, here you go:
      #!/usr/bin/perl use strict; use warnings; # always check if open fails open(DB, '<test.data') or die "Couldn't open file: $!"; my @numbers = map { my ($prod, $num, $dom) = (split /:/)[36,38,40]; (unpack("A4",$dom) eq 'ATM' && $prod eq 'In Production')?$num:() } <DB>; close DB; my $sum; $sum += $_ foreach (@numbers); printf "The average is %.2f.", @numbers ? ($sum/@numbers) : 0;
      I'm not saying that this is a better solution, I'd go - for the sake of readability/maintainability - for something straight forward like your first version.
    • Instead of the eval you can use a loop like I did or have a look at List::Utils.

    -- Hofmator

Re: Re: Calculating the average of a column in a flat-file database
by suggus (Sexton) on Oct 26, 2001 at 02:58 UTC
    THANKS gryphon! It works! You rock!