X-Git-Url: http://git.shiar.net/barcat.git/blobdiff_plain/f8ff6134094dfbef301efd2e234c696775d0ed56..HEAD:/barcat diff --git a/barcat b/barcat index 655f386..2b1a714 100755 --- a/barcat +++ b/barcat @@ -6,7 +6,7 @@ use List::Util qw( min max sum ); use open qw( :std :utf8 ); use re '/msx'; -our $VERSION = '1.09'; +our $VERSION = '1.10'; my %opt; if (@ARGV) { @@ -145,16 +145,16 @@ $opt{units} = [split //, ' kMGTPEZYRQqryzafpn'.($opt{ascii} ? 'u' : 'μ').'m'] $opt{'value-length'} = 4 if $opt{units}; $opt{'value-length'} = 1 if $opt{unmodified}; $opt{'signal-stat'} //= exists $SIG{INFO} ? 'INFO' : 'QUIT'; -$opt{markers} //= '=avg >31.73v <68.27v +50v |0'; +$opt{markers} //= '=avg <31.73v >68.27v +50v |0'; $opt{report} //= join('', '${partsum+; $_ .= " of "}', '${sum+; color(1); $_ .= " total in "}', '${count#} values', '${lines#; $_ = $_ != @order && " over $_ lines"}', sprintf('${count: (%s)}', join ', ', - '${min; color(31)} min', + '${0v; color(31)} min', '${avg; $opt{reformat} or $_ = sprintf "%0.2f", $_; color(36)} avg', - '${max; color(32)} max', + '${100v; color(32)} max', ), ); $opt{palette} //= $opt{color} && [31, 90, 32]; @@ -204,7 +204,7 @@ if (defined $opt{interval}) { eval { require Tie::Array::Sorted; - tie @order, 'Tie::Array::Sorted', sub { $_[1] <=> $_[0] }; + tie @order, 'Tie::Array::Sorted', sub { $_[0] <=> $_[1] }; } or warn $@, "Expect slowdown with large datasets!\n" unless $opt{count}; } @@ -268,12 +268,12 @@ if ($opt{count}) { @order = @values; } -@order = sort { $b <=> $a } @order unless tied @order; +@order = sort { $a <=> $b } @order unless tied @order; my $maxval = $opt{maxval} // ( $opt{hidemax} ? max grep { length } @values[$nr .. $limit] : - $order[0] + $order[-1] ) // 0; -my $minval = $opt{minval} // min $order[-1] // (), 0; +my $minval = $opt{minval} // min $order[0] // (), 0; my $range = $maxval - $minval; $range &&= log $range if $opt{log}; my $lenval = $opt{'value-length'} // max map { length } @order; @@ -342,13 +342,13 @@ while ($nr <= $limit) { $rel = min(1, $rel / $range) if $range; # 0..1 } my $color = !length $val || !$opt{palette} ? undef : - $val == $order[0] ? $opt{palette}->[-1] : # max - $val == $order[-1] ? $opt{palette}->[0] : # min + $val == $order[-1] ? $opt{palette}->[-1] : # max + $val == $order[0] ? $opt{palette}->[0] : # min $opt{palette}->[ $rel * ($#{$opt{palette}} - 1) + 1 ]; my $indicator = $opt{indicators} && $opt{indicators}->[ !length($val) || !$#{$opt{indicators}} ? 0 : # blank $#{$opt{indicators}} < 2 ? 1 : - $val >= $order[0] ? -1 : + $val >= $order[-1] ? -1 : $rel * ($#{$opt{indicators}} - 1e-14) + 1 ]; @@ -399,12 +399,6 @@ sub show_stat { if (@order) { $vars{partsum} = sum(0, grep {length} @values[$linemin .. $linemax]) if $linemin <= $linemax and ($opt{hidemin} or $opt{hidemax}); - %vars = (%vars, - sum => sum(@order), - min => $order[-1], - max => $order[0], - ); - $vars{avg} = $vars{sum} / @order; } say varfmt($opt{report}, \%vars); return 1; @@ -413,10 +407,16 @@ sub show_stat { sub calc { my ($func) = @_; if ($func eq 'avg') { - return sum(@order) / @order; + return calc('sum') / @order; } elsif ($func eq 'sum') { - return sum(@order); + state $cache; # avoid recount + state $cachednr = 0; # if unchanged + unless (@order == $cachednr) { + $cache = sum(@order); + $cachednr = @order; + } + return $cache; } elsif ($func =~ /\A([0-9.]+)v\z/) { $1 <= 100 or die( @@ -448,7 +448,7 @@ sub varfmt { defined && do { $_ = $opt{'value-format'}->($_) if $format; if ($cmd and $op eq ':') { - $_ = varfmt($cmd, $vars); + $_ = !!$_ && varfmt($cmd, $vars); } elsif ($cmd) { eval $cmd; @@ -650,8 +650,8 @@ in its frequency distribution (inclusive). The default shows C<+> at C<50v> for the mean or median: the middle value or interpolation between two values. -One standard deviation below the median is at about C<68v>. -The default includes C<< >31.73v <68.27v >> +One standard deviation above the median is at about C<68v>. +The default includes C<< <31.73v >68.27v >> to encompass all I results, or 68% of all entries, by I<< <--> >>. =item B