Hi Jim, Thanks again. Very helpful as usual!
T. On 2013-02-13, at 11:37 PM, Jim Gibson <jimsgib...@gmail.com> wrote: > > On Feb 13, 2013, at 6:47 PM, Tiago Hori wrote: > >> Hey Guys, >> >> I am still at the same place. I am writing these little pieces of code to >> try to learn the language better, so any advice would be useful. I am again >> parsing through tab delimited files and now trying to find fish from on id >> (in these case families AS5 and AS9), retrieve the weights and average >> them. When I started I did it for one family and it worked (instead of the >> @families I had a scalar $family set to AS5). But really it is more useful >> to look at more than one family at time (I should mention that are 2 types >> of fish per family one ends in PS , the other doesn't). So I tried to use a >> foreach loop to go through the file twice, once with a the search value set >> to AS5 and a second time to AS9. It works for AS5, but for some reason, the >> foreach loop sets $test to AS9 the second time, but it doesn't go through >> the while loop. What am I doing wrong? >> >> here is the code: >> >> #! /usr/bin/perl >> use strict; >> use warnings; >> >> my $file = $ARGV[0]; >> my @family = ('AS5','AS9'); >> my $i; >> my $ii; >> my $test; >> >> open (my $fh, "<", $file) or die ("Can't open $file: $!"); >> >> foreach (@family){ >> $test = $_; > > You can combine those two lines like this (for and foreach are equivalent, so > most people use the shorter form): > > for my $test ( @family ) { > >> my @data_weight_2N = (); >> my @data_weight_3N = (); > > The second time through the for loop, the file has been read and is > positioned at its end. You are going to get nothing by reading the file the > second time through. You should rewind the file: > > seek($fh,0,0); > >> while (<$fh>){ >> chomp; >> my $line = $_; > > Once again, you can do the assignment directly and not use the default > variable $_. It is shorter and better: > > while( my $line = <$fh> ) { > chomp($line); > >> my @data = split ("\t", $line); >> if ($data[0] !~ /[0-9]*/){ >> next;} > > Better syntax for those two lines: > > next if $data[0] !~ /[0-9]*/; > >> elsif ($data[1] eq "ABF09-$test"){ > > Then you can make the above line 'if …' > >> $i += 1; >> push (@data_weight_2N, $data[6]); >> }elsif ($data[1] eq "ABF09-".$test."PS"){ >> $ii += 1; >> push (@data_weight_3N,$data[6]); >> } >> } >> my $mean_2N = &average (\@data_weight_2N); >> my $stdev_2N = &stdev (\@data_weight_2N); > > You should not be calling subroutines with the ampersand character. > >> my $stderr_2N = ($stdev_2N/sqrt($i)); >> >> print "These are the the avearge weight, stdev and stderr for $test >> 2N:\t", $mean_2N,"\t",$stdev_2N,"\t",$stderr_2N, "\n"; > > It is more efficient to print one double-quoted string than a series of short > strings, > even if you have to concatenate the string from two shorter strings: > > print "These are the the avearge weight, stdev and stderr for $test" . > " 2N:\t$mean_2N\t$stdev_2N\t$stderr_2N\n"; > >> >> my $mean_3N = &average (\@data_weight_3N); >> my $stdev_3N = &stdev (\@data_weight_3N); >> my $stderr_3N = ($stdev_3N/sqrt($i)); >> >> print "These are the the avearge weight, stdev and stderr for $test >> 3N:\t", $mean_3N,"\t",$stdev_3N,"\t",$stderr_3N, "\n"; >> } >> >> close ($fh); >> >> sub average{ >> my($data) = @_; >> if (not @$data) { >> print ("Empty array\n"); >> return 0; >> } >> my $total = 0; >> foreach (@$data) { >> $total += $_; >> } > > Shorter: > > $total += $_ for @$data; > >> my $average = $total / @$data; >> return $average; >> } >> >> sub stdev{ >> my($data) = @_; >> if(@$data == 1){ >> return 0; >> } >> my $average = &average($data); >> my $sqtotal = 0; >> foreach(@$data) { >> $sqtotal += ($average-$_) ** 2; >> } >> my $std = ($sqtotal / (@$data-1)) ** 0.5; >> return $std; >> } >> >> Thanks, > > > -- > To unsubscribe, e-mail: beginners-unsubscr...@perl.org > For additional commands, e-mail: beginners-h...@perl.org > http://learn.perl.org/ > > -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/