116 lines
2.6 KiB
Perl
116 lines
2.6 KiB
Perl
use strict;
|
|
use warnings;
|
|
|
|
use constant RESULT_TEMPLATE => "%-19s = %12.3f / %-6u = %.3f\n";
|
|
|
|
my $parser = Parser->new;
|
|
|
|
# parse lines and print results
|
|
printf RESULT_TEMPLATE, $parser->parse(split)
|
|
while <>;
|
|
|
|
$parser->finish;
|
|
|
|
# print total and summary
|
|
printf "\n".RESULT_TEMPLATE."\n", $parser->result;
|
|
printf "the maximum of %u consecutive bad values was reached %u time(s)\n",
|
|
$parser->bad_max, scalar $parser->bad_ranges;
|
|
|
|
# print bad ranges
|
|
print for map { ' '.join(' - ', @$_)."\n" } $parser->bad_ranges;
|
|
|
|
BEGIN {
|
|
package main::Parser;
|
|
|
|
sub new {
|
|
my $obj = {
|
|
SUM => 0,
|
|
COUNT => 0,
|
|
CURRENT_DATE => undef,
|
|
BAD_DATE => undef,
|
|
BAD_RANGES => [],
|
|
BAD_MAX => 0,
|
|
BAD_COUNT => 0
|
|
};
|
|
|
|
return bless $obj;
|
|
}
|
|
|
|
sub _average {
|
|
my ($sum, $count) = @_;
|
|
return ($sum, $count, $count && $sum / $count);
|
|
}
|
|
|
|
sub _push_bad_range_if_necessary {
|
|
my ($parser) = @_;
|
|
my ($count, $max) = @$parser{qw(BAD_COUNT BAD_MAX)};
|
|
|
|
return if $count < $max;
|
|
|
|
if ($count > $max) {
|
|
$parser->{BAD_RANGES} = [];
|
|
$parser->{BAD_MAX} = $count;
|
|
}
|
|
|
|
push @{$parser->{BAD_RANGES}}, [ @$parser{qw(BAD_DATE CURRENT_DATE)} ];
|
|
}
|
|
|
|
sub _check {
|
|
my ($parser, $flag) = @_;
|
|
if ($flag <= 0) {
|
|
++$parser->{BAD_COUNT};
|
|
$parser->{BAD_DATE} = $parser->{CURRENT_DATE}
|
|
unless defined $parser->{BAD_DATE};
|
|
|
|
return 0;
|
|
}
|
|
else {
|
|
$parser->_push_bad_range_if_necessary;
|
|
$parser->{BAD_COUNT} = 0;
|
|
$parser->{BAD_DATE} = undef;
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
sub bad_max {
|
|
my ($parser) = @_;
|
|
return $parser->{BAD_MAX}
|
|
}
|
|
|
|
sub bad_ranges {
|
|
my ($parser) = @_;
|
|
return @{$parser->{BAD_RANGES}}
|
|
}
|
|
|
|
sub parse {
|
|
my $parser = shift;
|
|
my $date = shift;
|
|
|
|
$parser->{CURRENT_DATE} = $date;
|
|
|
|
my $sum = 0;
|
|
my $count = 0;
|
|
|
|
while (my ($value, $flag) = splice @_, 0, 2) {
|
|
next unless $parser->_check($flag);
|
|
$sum += $value;
|
|
++$count;
|
|
}
|
|
|
|
$parser->{SUM} += $sum;
|
|
$parser->{COUNT} += $count;
|
|
|
|
return ("average($date)", _average($sum, $count));
|
|
}
|
|
|
|
sub result {
|
|
my ($parser) = @_;
|
|
return ('total-average', _average(@$parser{qw(SUM COUNT)}));
|
|
}
|
|
|
|
sub finish {
|
|
my ($parser) = @_;
|
|
$parser->_push_bad_range_if_necessary
|
|
}
|
|
}
|