The Perl and Raku Conference 2025: Greenville, South Carolina - June 27-29 Learn more

#!perl
our $DATE = '2018-07-07'; # DATE
our $VERSION = '0.001'; # VERSION
use strict;
use Getopt::Long qw(:config bundling no_ignore_case);
my %Opts = (
calc_count => 1,
calc_mode => 1,
calc_min => 1,
calc_max => 1,
calc_mean => 1,
calc_median => 1,
calc_variance => 1,
calc_stddev => 1,
calc_percentiles => [25, 75],
calc_covariance => 0,
calc_correlation => 0,
);
sub parse_cmdline {
my $res = GetOptions(
'count!' => \$Opts{calc_count},
'mode!' => \$Opts{calc_mode},
'max!' => \$Opts{calc_max},
'min!' => \$Opts{calc_min},
'mean!' => \$Opts{calc_mean},
'median!' => \$Opts{calc_median},
'variance!' => \$Opts{calc_variance},
'stddev!' => \$Opts{calc_stddev},
'no-percentile|P' => sub { $Opts{calc_percentiles} = [] },
'percentile|p=s' => sub {
my $p = int($_[1]);
die "summ: Invalid percentile $p, must be between 0 and 100\n"
if $p < 0 || $p > 100;
push @{ $Opts{calc_percentiles} }, $p
unless grep { $p == $_ } @{ $Opts{calc_percentiles} };
},
'covariance!' => \$Opts{calc_covariance},
'correlation!' => \$Opts{calc_correlation},
'help|h' => sub {
print <<USAGE;
Usage:
summ [OPTIONS]... [INPUT]...
summ --help
For more details, see the manpage/documentation.
USAGE
exit 0;
},
'version|v' => sub {
no warnings 'once';
print "summ version ".($main::VERSION // 'dev'), "\n";
exit 0;
},
);
exit 99 if !$res;
}
sub run {
my (@nums, @nums2);
while (<>) {
chomp;
if ($Opts{calc_covariance} || $Opts{calc_correlation}) {
my ($n, $n2) = split /\s+/, $_, 2;
defined $n2 or die "summ:$.: Please supply two numbers: $_\n";
push @nums, $n+0;
push @nums2, $n2+0;
} else {
push @nums, $_+0;
}
}
die "summ: Please specify at least 1 number\n" unless @nums;
my $sd = Statistics::Discrete->new;
$sd->add_data(@nums);
if ($Opts{calc_count}) {
printf "Count: %s\n", $sd->count;
}
if ($Opts{calc_mode}) {
printf "Mode: %s\n", Statistics::Basic::mode(@nums);
}
if ($Opts{calc_min}) {
printf "Minimum: %s\n", $sd->minimum;
}
if ($Opts{calc_max}) {
printf "Maximum: %s\n", $sd->maximum;
}
if ($Opts{calc_mean}) {
printf "Mean: %s\n", $sd->mean;
}
if ($Opts{calc_median}) {
printf "Median: %s\n", $sd->median;
}
if ($Opts{calc_variance}) {
printf "Variance: %s\n", $sd->variance;
}
if ($Opts{calc_stddev}) {
printf "Std. dev.: %s\n", $sd->standard_deviation;
}
if (@{ $Opts{calc_percentiles} }) {
for my $p (sort { $a <=> $b } @{ $Opts{calc_percentiles} }) {
printf "%s percentile: %s\n",
Lingua::EN::Numbers::Ordinate::ordinate($p),
$sd->percentile($p);
}
}
if ($Opts{calc_covariance}) {
printf "Covariance: %s\n", Statistics::Basic::covariance(
\@nums, \@nums2);
}
if ($Opts{calc_correlation}) {
printf "Correlation: %s\n", Statistics::Basic::correlation(
\@nums, \@nums2) + 0;
}
}
# MAIN
parse_cmdline();
run();
1;
# ABSTRACT: Print summary statistics of a series of numbers
# PODNAME: summ
__END__
=pod
=encoding UTF-8
=head1 NAME
summ - Print summary statistics of a series of numbers
=head1 VERSION
This document describes version 0.001 of summ (from Perl distribution App-summ), released on 2018-07-07.
=head1 SYNOPSIS
summ [OPTION]... [FILE]...
=head1 DESCRIPTION
=head1 EXIT CODES
0 on success.
255 on I/O error.
99 on command-line options error.
=head1 OPTIONS
=over
=item * --no-count
Do not calculate count.
=item * --no-mode
Do not calculate mode.
=item * --no-max
Do not calculate maximum.
=item * --no-min
Do not calculate minimum.
=item * --no-mean
Do not calculate mean.
=item * --no-median
Do not calculate median.
=item * --no-variance
Do not calculate variance.
=item * --no-stddev
Do not calculate standard deviation.
=item * --no-percentile, -P
Do not calculate any percentiles. The default is to calculate 25th and 75th
percentiles.
=item * --percentile=P, -p P
Add a percentile to calculate, for example: C<-p 5 -p 95> to add calculating 5th
and 95th percentiles. The default is to only calculate 25th and 75th
percentiles.
=item * --covariance
Calculate covariance. This requires every line to contain two numbers intead of
one.
=item * --correlation
Calculate correlation. This requires every line to contain two numbers intead of
one.
=back
=head1 FAQ
=head1 HOMEPAGE
Please visit the project's homepage at L<https://metacpan.org/release/App-summ>.
=head1 SOURCE
Source repository is at L<https://github.com/perlancar/perl-App-summ>.
=head1 BUGS
Please report any bugs or feature requests on the bugtracker website L<https://rt.cpan.org/Public/Dist/Display.html?Name=App-summ>
When submitting a bug or request, please include a test-file or a
patch to an existing test-file that illustrates the bug or desired
feature.
=head1 SEE ALSO
L<Statistics::Basic>
L<Statistics::Discrete>
=head1 AUTHOR
perlancar <perlancar@cpan.org>
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2018 by perlancar@cpan.org.
This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.
=cut