0

I have a file that contains some lines with floating numbers, something like this:

1.66278886795044
1.61858296394348
1.66523003578186
1.62150096893311
1.6725389957428

I am trying to open that file, calculate the average of all lines, and then write the average to the same file. Where 5 stands for the amount of items, the expected output would thus be:

1.66278886795044
1.61858296394348
1.66523003578186
1.62150096893311
1.6725389957428
================
AVERAGE after 5 runs: 1.6481283664703

Considering I can get the amount of runs from a variable higher up in the script $amountofloops, I thought this would do it:

open(my $overviewhandle, '>>', 'overview.txt');
chomp( my @durations = <$overviewhandle> );
my $avgtime = 0;
foreach my $duration (@durations) {
    $avgtime += $duration;
}
$avgtime = $avgtime / $amountofloops;
print $overviewhandle "================\nAVERAGE after $amountofloops runs: $avgtime";
close $overviewhandle;

However, $avgtime keeps returning zero and I don't know why. I think the number isn't parsed as a number.

Bram Vanroy
  • 27,032
  • 24
  • 137
  • 239

3 Answers3

4

You should always add use strict and use warnings to the top of any Perl program that you write. They will help you find bugs.

In this case you would have seen the error:

Filehandle $overviewhandle opened only for output

Which, in my opinion, makes the problem pretty obvious.

Dave Cross
  • 68,119
  • 3
  • 51
  • 97
  • As I hoped was clear from my initial post, this is only a snippet of my whole script. I do use strict and warnings, since it was [previously pointed out to me](http://stackoverflow.com/questions/35552520/why-is-my-xml-file-empty-after-generating-with-xmllibxml#comment58793220_35552520). I did not see the error, though, as I run the script from the terminal, and the script writes a lot to the terminal (for testing purposes). I therefore didn't see that error. – Bram Vanroy Feb 23 '16 at 14:32
  • Can I suggest running your program so that STDOUT is directed to one filehandle and STDERR is directed to another. That way it will be easier to spot the errors and warnings. – Dave Cross Feb 23 '16 at 14:34
3

The open mode of the file is wrong. You need to have it in read/write mode, not append mode

open(my $overviewhandle, '+<','overview.txt');
chomp( my @durations = <$overviewhandle> );
my $avgtime = 0;
foreach my $duration (@durations) {
    $avgtime += $duration;
}
$avgtime = $avgtime / scalar @durations;
print $overviewhandle "================\nAVERAGE after $amountofloops runs: $avgtime";
close $overviewhandle;
Vorsprung
  • 32,923
  • 5
  • 39
  • 63
  • After testing this I found that `$#durations` returns one less than the actually length of the array. Any idea why that's the case? – Bram Vanroy Feb 23 '16 at 12:10
  • Figured it out. Your method only returns the index of the last item. Better methods are described [here](http://stackoverflow.com/questions/7406807/find-size-of-an-array-in-perl). I used `scalar @durations`. – Bram Vanroy Feb 23 '16 at 12:19
  • yeah sorry about the off by one, I was just testing the file mode write and not looking at that. Altered it in answer now – Vorsprung Feb 23 '16 at 12:26
0
open my $in, '<', 'in.txt' or die $!;

my $count = 0;
my $total;
while(<$in>){
    $count++;
    $total += $_;
}

open my $out, '>>', 'in.txt' or die $!;

my $average = $total/$count;
print $out "\n================\n";
print $out "AVERAGE after $count runs: $average\n";
fugu
  • 6,417
  • 5
  • 40
  • 75