App-pl
view release on metacpan or search on metacpan
pod/examples.pod view on Meta::CPAN
$b = F "\e[%dm%3d "x16, map +(($_)x2, ($_+60)x2), 30..37' \
'f "%2d: %4d; \e[%2:dm$b\e[m", @$_'
=item Terminal Rulers
If you need a ruler to better count the width of some other output, you can
print out one of the following. These are either decimal, by groups of 5 or
hex by groups of 4 and 8. The latter two do the same. But instead of one
static ruler of length 100 or 256, they repeat and adapt. Depending on your
terminal emulator and Shell, the variable C<$COLUMNS> may track the current
width. If so, pass it in a single argument to "loop" over with B<-o>, else
provide the desired width yourself:
pl 'say map "$_...:.....", 0..9'
pl 'say map "$_..:...|...:....", 0..9, "A".."F"'
pl -o 'say substr join( "", map "$_...:.....", 0..9 ) x ($_ / 100 + 1), 0, $_' $COLUMNS
pl -o 'say substr join( "", map "$_..:...|...:....", 0..9, "A".."F" ) x ($_ / 256 + 1), 0, $_' $COLUMNS
> 0...:.....1...:.....2...:.....3...:.....4...:.....5...:.....6...:.....7...:.....8...:.....9...:.....
> 0..:...|...:....1..:...|...:....2..:...|...:....3..:...|...:....4..:...|...:....5..:...|...:....6..:...|...:....7..:...|...:....8..:...|...:....9..:...|...:....A..:...|...:....B..:...|...:....C..:...|...:....D..:...|...:....E..:...|...:....F....
> 0...:.....1...:.....2...:.....3...:.....4...:.....5...:.....6...:.....7...:.....
> 0..:...|...:....1..:...|...:....2..:...|...:....3..:...|...:....4..:...|...:....
=back
=head2 Math
=over
=item Minimum and Maximum
The C<List::Util> functions C<min> and C<max> are imported for you:
pl 'echo max 1..5'
pl 'e max 1..5'
> 5
If you have just several numbers on each line and want their minimums, you can
autosplit (B<-a>) to C<@F(IELD)>:
pl -a 'echo min @FIELD' file*
pl -a 'e min @FIELD' file*
If on the same you just want the overall minimum, you can use the print-at-end
variable C<$R(ESULT)>, which you initialise to infinity in a B<-B> begin
program:
pl -aB '$RESULT = "inf"' '$RESULT = min $RESULT, @FIELD' file*
pl -aB '$R = "inf"' '$R = min $R, @FIELD' file*
Likewise for overall maximum, you start with negative infinity:
pl -aB '$RESULT = "-inf"' '$RESULT = max $RESULT, @FIELD' file*
pl -aB '$R = "-inf"' '$R = max $R, @FIELD' file*
=item Median, Quartiles, Percentiles
The median is the number where half the list is less and half is greater.
Similarly the 1st quartile is where 25% are less and the 3rd where 25% are
greater. Use a list slice to extract these 3 and a 97th percentile, by
multiplying the fractional percentage with the list length:
pl -A 0..200 'echo @ARGV[map $_*@ARGV, .25, .5, .75, .97]'
pl -A 0..200 'e @A[map $_*@A, .25, .5, .75, .97]'
> 50 100 150 194
If you'd rather have names associated, assign them to hash slice in
sort-numerically-at-end C<%N(UMBER)>, whose key order must match the
percentages:
pl -A 0..200 '@NUMBER{qw(lower median upper 97.)} = @ARGV[map $_*@ARGV, .25, .5, .75, .97]'
pl -A 0..200 '@N{qw(lower median upper 97.)} = @A[map $_*@A, .25, .5, .75, .97]'
> 50: lower
> 100: median
> 150: upper
> 194: 97.
=item Triangular Number, Factorial and Averages
I<80% of people consider themselves to be above average. :-)>
The triangular number is defined as the sum of all numbers from 1 to I<n>, e.g. 1
to 5. Factorial is the equivalent for products:
pl 'echo sum 1..5;
echo product 1..5'
pl 'e sum 1..5;
e product 1..5'
> 15
> 120
The sum of all list elements divided by the length of the list gives the
linear average. Alternately the root mean square can be a fairer average,
because it accounts for the weights:
pl -A 11..200 'echo sum( @ARGV ) / @ARGV;
echo sqrt sum( map $_ ** 2, @ARGV ) / @ARGV'
pl -A 11..200 'e sum( @A ) / @A;
e sqrt sum( map $_ ** 2, @A ) / @A'
> 105.5
> 118.905424602917
=item Add Pairs or Tuples of Numbers
If you have a list of number pairs and want to add each 1st and each 2nd
number, C<reduce> is your friend. Inside it map over the pair elements
C<0..1>:
pl 'echo reduce {
[map $a->[$_] + $b->[$_], 0..1]
} [1, 11], [2, 12], [3, 13]'
pl 'e reduce {
[map $a->[$_] + $b->[$_], 0..1]
} [1, 11], [2, 12], [3, 13]'
> [
> 6,
> 36
> ]
If your list is a variable and is empty the result is C<undef>. You can
insert a fallback zero element if you'd rather receive that for an empty list:
pl 'echo reduce {
[map $a->[$_] + $b->[$_], 0..1]
} [0, 0], @list'
( run in 2.298 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )