By the way, I noticed a couple more things:
- Use lexical filehandles: open my $fh, ... instead of open FH, ...
- Check for errors: open my $fh, ... or die "...$!", or use autodie at the beginning of your script
- You had a direct call to average(@array) in the print, and another call with the same data when assigning to the variable $average = average(@array); no need to average the same data twice.
To bring all the excellent suggestions to date into one post, plus these new suggestions, here is an annotated version of the updated code (note I changed to c:\temp\tsukk instead of c:\users\tsukk)
use strict;
use diagnostics;
use warnings;
while (1) {
print "Enter an input file name: ";
chomp (my $choice = <STDIN>);
open (my $fh, '<', "C:/temp/tsukk/$choice") #
+ [pryrt] use lexical filehandles
or die "error opening $choice: $!"; #
+ [pryrt] check for errors; if you don't want this, "use autodie;" ab
+ove
# my @array; while (my $data = <$fh>) { push @array, $data; } #
+ [AnomalousMonk]'s [id://1203631] 'better yet': bring my @array into
+ the while(1)...
my @array = <$fh>; #
+ [AnomalousMonk]'s [id://1203631] 'simply': slurp the whole file by
+giving <> list context
my $use_brostad = 1; #
+ set to 1 to use [brostad]'s, else false to use the anonymous sugges
+tion
my ($largest, $smallest) = (-9e9,9e9); #
+ initialize to the wrong extremes
if($use_brostad) {
($largest, $smallest) = (sort {$b <=> $a } @array)[0,-1]; #
+ [brostad]'s [id://1203655]: reverse sort, return the first and last
+ elements
} else {
for my $v (@array) { #
+ [anonymous monk]'s [id://1203660]: single pass through loop, withou
+t sorting; more efficient than brostad's single sort
$largest = $v if $v > $largest;
$smallest = $v if $v < $smallest;
}
}
print "\nThe largest number is: ";
print $largest, "\n"; #
+ [pryrt]: largest is now scalar, not array
print "The smallest number is: ";
print $smallest; #
+ [pryrt]: smallest is now scalar, not array
print "The average of the numbers is: ";
printf "%.1f\n", my $average = average(@array); #
+ [pryrt]: only call average() once per dataset
print "\n";
foreach (@array) {
chomp;
if ($average > $_) {
print "$_\t is below average.\n";
} elsif ($average < $_) {
print "$_\t is above average.\n";
} elsif ($average == $_) { #
+ [AnomalousMonk]'s [id://1203631]'s fix: comparison, not assigment
print "$_\t is equal to average.\n";
}
}
print "\nDo it again? (Yes or No): ";
chomp (my $yesno=<STDIN>);
if($yesno ne 'Yes') {
print "Goodbye.\n";
exit;
}
}
sub average {
if (@_) { #
+ [pryrt]'s [id://1203627]
my @temp = @_;
my $sum = 0;
foreach (@temp) {
$sum = $sum + $_;
}
return $sum/@temp;
}
}