From 850e6582f48afb204e4f1d1710002a3bb6dac0a4 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Thu, 10 Sep 2009 01:52:40 +0100 Subject: [PATCH] Allow %age adjustments to capacity --- yarrg/web/check_capacitystring | 68 +++++++++++++++++++++------------- yarrg/web/docs | 17 ++++++--- 2 files changed, 55 insertions(+), 30 deletions(-) diff --git a/yarrg/web/check_capacitystring b/yarrg/web/check_capacitystring index ae1dec4..f001c79 100644 --- a/yarrg/web/check_capacitystring +++ b/yarrg/web/check_capacitystring @@ -87,6 +87,19 @@ print STDERR "PAN \`$string'\n"; return @mve; }; +my @mv_names= qw(mass volume); +my $canon_numeric= $h->{'canon_numeric'}= sub { + print STDERR "CANNUM @_\n"; + my $sep= ''; + my $out= ''; + foreach my $ix (qw(0 1)) { + next unless defined $_[$ix]; + $out .= $sep; $sep= ' '; + $out .= sprintf "%g%s", $_[$ix], (qw(kg l))[$ix]; + } + return $out; +}; + $h->{'deltas'}= [ ]; print STDERR "NDELTA0 $#{ $h->{'deltas'} }\n"; @@ -96,9 +109,29 @@ while (m/^(.*)(\bminus\b|-|\bplus\b|\+)/) { print STDERR "TERM L=\`$1' M=\`$2' R=\`$''\n"; my ($signum,$signopstr)= $2 =~ m/^p|^\+/ ? (+1,'plus') : (-1,'minus'); - my (@mve)= $parse_numeric->($rhs, 0); - ${ $h->{Emsg} }= $mve[2] if defined $mve[2]; - unshift @{ $h->{'deltas'} }, [ @mve,$signum,$signopstr ]; + my @mveco; + if ($rhs =~ m/^\s*(\d{1,2}(?:\.\d{0,4})?)\%\s*$/) { + my $pct= 100.0 + $signum * $1; + @mveco= ($pct,$pct,undef); + push @mveco, sprintf "%s %g%%", $signopstr, $1; + push @mveco, sub { + return undef unless defined $_[0]; + $_[0] * $_[1] / 100.0 + }; + } else { + @mveco= $parse_numeric->($rhs, 0); + if (!defined $mveco[2]) { + push @mveco, $signopstr.' '.$canon_numeric->(@mveco); + push @mveco, sub { + ${ $h->{Emsg} }= "Cannot add or subtract". + " mass to/from volume" + unless defined $_[0]; + $_[0] + $_[1] * $signum + }; + } + } + ${ $h->{Emsg} }= $mveco[2] if defined $mveco[2]; + unshift @{ $h->{'deltas'} }, [ @mveco ]; print STDERR "NDELTA $#{ $h->{'deltas'} }\n"; $_= $lhs; } @@ -143,30 +176,19 @@ $h <%perl> -return if length ${ $h->{Emsg} }; - -my @mv_names= qw(mass volume); +my $canon_numeric= $h->{'canon_numeric'}; -my $canon_numeric= sub { - print STDERR "CANNUM @_\n"; - my $sep= ''; - my $out= ''; - foreach my $ix (qw(0 1)) { - next unless defined $_[$ix]; - $out .= $sep; $sep= ' '; - $out .= sprintf "%g%s", $_[$ix], (qw(kg l))[$ix]; - } - return $out; -}; +return if length ${ $h->{Emsg} }; my @mv; +my @mv_names= qw(mass volume); if (@{ $h->{Specs} }) { @mv= @{ $h->{Results}[0] }[1,2]; - print STDERR "INITIAL VESSEL @mv\n"; } else { @mv= @{ $h->{'initial'} }; ${ $h->{Canon} }= $canon_numeric->(@mv); } +print STDERR "INITIAL @mv\n"; print STDERR "NDELTAE $#{ $h->{'deltas'} }\n"; foreach my $delta (@{ $h->{'deltas'} }) { @@ -175,14 +197,10 @@ foreach my $delta (@{ $h->{'deltas'} }) { foreach my $ix (qw(0 1)) { next unless defined $delta->[$ix]; print STDERR "DELTA I $ix\n"; - if (!defined $mv[$ix]) { - ${ $h->{Emsg} }= "Cannot add or subtract". - " $mv_names[$ix] to/from $mv_names[!$ix]"; - return; - } - $mv[$ix] += $delta->[$ix] * $delta->[3]; + $mv[$ix] = $delta->[4]->($mv[$ix], $delta->[$ix]); + return if length ${ $h->{Emsg} }; } - ${ $h->{Canon} }.= " $delta->[4] ". $canon_numeric->(@$delta); + ${ $h->{Canon} }.= ' '.$delta->[3]; } if (@{ $h->{Specs} } || @{ $h->{'deltas'} }) { diff --git a/yarrg/web/docs b/yarrg/web/docs index 24d9f16..48a0062 100755 --- a/yarrg/web/docs +++ b/yarrg/web/docs @@ -114,23 +114,30 @@ So you should specify your vessel capacity. You can enter things like:
sloop -
The capacity of a sloop, exactly +
The capacity of a sloop, leaving no allowance for rum and shot +
sloop - 1% +
The capacity of a sloop minus 1%
20t 13kl -
20 tonnes (20,000kg), 13 kilolitres (13,000l) +
13 tonnes (13,000kg), 20 kilolitres (20,000l)
sloop - 100l 100kg
The capacity of a sloop minus 100l, minus 100kg
2t plus 500kg minus 200kg
2300kg, with no limit on volume
+Evaluation is strictly from left to right. + +

Formally, the capacity is a list of terms, all but the first preceded by one of -, minus, +, plus. Each term may specify a mass and/or a volume (separated by a space), as a number followed (without an intervening space) by a unit (t, kg, kl or -l). The first term may be a ship name or abbrevation -instead. If the first term specifies only one of mass or volume, all -the subsequent terms may only adjust that same value. +l). Alternatively each term except the first may specify a +percentage, which is applied as a percentage change to the answer from +all the preceding terms. The first term may be a ship name or +abbrevation instead. If the first term specifies only one of mass or +volume, all the subsequent terms may only adjust that same value.

Expected losses

-- 2.30.2