Jeff 'japhy' Pinyan wrote:
On Aug 15, Scott R. Godin said:

quantity    1 - 9        0%
quantity    10 - 19        25%
quantity    20 - 199    40%
quantity    200 - 499    50%
quantity    500+        55%

I'd like to read it in via a __DATA__ handle, and perform the discount
calculation based on the total # of items (out of 6 individual items, each priced differently but contributing to the total quantity towards the discount percentage).

what are some perlish ways one would go about performing this calculation efficiently ?


Well, if the quantities are going to be relatively small numbers, you could use an array:

  my @discount;

  while (<DATA>) {
    if (my ($lower, $upper, $disc) = / (\d+) - (\d+) +(\d+)%/) {
      @discount[$lower..$upper] = ($disc) x ($upper - $lower + 1);
    }
    elsif (my ($lower, $disc) = / (\d+)\+ +(\d+)%/) {
      $discount[$lower] = $disc;
    }
    else {
      warn "unsupported discount line (#$.): $_";
    }
  }

Oh, Jolly Good! though I'm somewhat concerned with how much memory that would take up. Ultimately this would be running as a cgi processing a web-form submission.

Then you would simply poll @discount to find out the rate; this is assuming $quantity is some positive number:

  my $rate = ($discount[$quantity] || $discount[-1]) / 100;

almost. when $discount[1] = 0 that makes it assume the 55% discount instead. see below.

If there is no entry for $discount[$quantity], that means it's greater than 500 (in your sample case), thus it gets the same discount as 500 items. Since $discount[500] is the last element in @discount, it's the same as $discount[-1].


I've modified it slightly, to add strictness and also my pricing/products table.

#!/usr/bin/perl
use warnings;
use strict;

my (@discount, %price);
while ( <DATA> )
{
        chomp;
        if ( /^quantity/)
        {
                my($lower, $upper, $disc);
                if ( ($lower, $upper, $disc) =  /(\d+)\s+-\s+(\d+)\s+(\d+)%$/ )
                {
                  @discount[$lower..$upper] = ($disc) x ($upper - $lower + 1);
                }
                elsif ( ($lower, $disc) = /(\d+)\+\s+(\d+)%$/ )
                {
                  $discount[$lower] = $disc;
                }
                else
                {
                  warn "unsupported discount line (#$.): $_";
                }
                next;
        }
        if ( /^price/ )
        {
                if (my($book, $retail) = /(\w+)\s+\$([\d.]+)$/)
                {
                        $price{$book} = $retail;
                }
                else
                {
                        warn "unsupported price line (#$.): $_";
                }
                next;
        }
        warn "nonmatching line in DATA table: '$_'";# fallthrough
}

for (1 .. 20 )
{
    my $rate = (defined($discount[$_]) ? $discount[$_] : $discount[-1]) / 100;
    print "$_, $rate\n";
}

__DATA__
quantity    1 - 9        0%
quantity    10 - 19     25%
quantity    20 - 199    40%
quantity    200 - 499   50%
quantity    500+        55%
price           rkh             $15.95
price           rkp             $6.95
price           rmh             $15.95
price           rmp             $6.95
price           rbh             $15.95
price           rbp             $6.95

--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
<http://learn.perl.org/> <http://learn.perl.org/first-response>


Reply via email to