RE: Loop Problems?!?
by Charles K. Clarkson other posts by this author
Jul 29 2004 4:43AM messages near this date
Loop Problems?!?
|
Re: Loop Problems?!?
Kenny Evans <> wrote:
: Hey All:
:
: I have this script here to calculate the average and
: standard deviation of a bunch of numbers in a text
: file. For some reason, it doesn't seem to go through
: the second while loop at all.
How do you know that?
: Am I doing something wrong? Please help!!!
Well, let's see:
: #!/usr/bin/perl
: use strict;
: use warnings;
Yeah!
: my $year4 = 1997;
: my $year2 = '97';
Why is 97 in quotes?
: chdir "/home/kfevans/grbs/$year4/bkgd" or die "Can't open
: $year4/bkgd: $!\n";
: open(FILE, "> /home/kfevans/grbs/$year4/bkgd/avg_stdev_$year2.txt")
: or die "Can't open FILE: $!\n";
Using "\n" after $! hides useful error information.
my $year4 = 1997;
my $year2 = 97;
my $home_dir = "/home/kfevans/grbs/$year4/bkgd";
chdir $home_dir or die qq(Cannot change directory to "$home_dir": $!);
my $file = "$home_dir/avg_stdev_$year2.txt";
open FILE, "> $file" or die qq(Cannot open "$file": $!);
: foreach my $file (<*.bkgd.txt> ) {
: $file =~ /^(\d+)\.bkgd\.txt/;
: my $num = $1;
How do we know it matched?
It would be safer to write:
next unless $file =~ /^(\d+)\.bkgd\.txt/;
my $num = $1;
: my $value1 = 0;
: my $value2 = 0;
You don't need that up here. Declare it just before
you use it.
: my $count = 0;
:
: open(F, $file);
How do you know this opened? Use the same check as
above.
open F, $file or die qq(Cannot open "$file": $!);
: while (<F> ) {
: $value1 += $_;
: $count++;
: }
: close F;
:
: my $avg = $value1 / ($count -1);
Are you sure it's not $value1 / $count?
:
: open(T, $file);
Same as for F.
: while (<T> ) {
: my $dev = ($_ - $avg)**2;
: my $value2 += $dev;
That 'my' is screwing you up. The loop runs, but
$value2 is local to this (if) code block. The other
$value2 is always 0.
my $value2 = 0;
$value2 += ( $_ - $avg ) ** 2 while <T> ;
: }
: close T;
:
: my $stdev = sqrt ($value2 / ($count - 2));
You should probably check that $count is greater
than 2 before running this.
: print FILE "$num $avg $stdev\n";
: print STDOUT "$num $avg $stdev\n";
: }
You could cut file opening in half by using
an array and a module.
use strict;
use warnings;
use Statistics::Descriptive;
my $year_4 = 1997;
my $year_2 = 97;
my $home_dir = "/home/kfevans/grbs/$year_4/bkgd";
chdir $home_dir or die qq(Cannot open "$home_dir": $!);
my $file = "$home_dir/avg_stdev_$year_2.txt";
open FILE, $file or die qq(Cannot open "$file": $!);
foreach my $file (<*.bkgd.txt> ) {
next unless $file =~ /^(\d+)\.bkgd\.txt/;
my $file_number = $1;
# keep only values that have a digit in them
open FH, $file or die qq(Cannot open "$file": $!);
chomp( my @values = grep /\d+/, <FH> );
close FH;
my $stat = Statistics::Descriptive::Sparse-> new();
$stat-> add_data( @values );
foreach my $handle ( *STDOUT, *FILE ) {
printf $handle
"%s %s %s\n",
$file_number,
$stat-> sum() / @values,
$stat-> standard_deviation();
}
}
__END__
HTH,
Charles K. Clarkson
--
Mobile Homes Specialist
254 968-8328
_______________________________________________
ActivePerl mailing list
ActivePerl@[...].com
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs
Thread:
Kenny Evans
Charles K. Clarkson
$Bill Luebkert
|