I am trying to create a tiered tax calculator.
The user enters an amount, say 500,000
From that amount, I then have the following tiers that tax is charged as follows:
0 - 125,000 = 0%
125,001 - 250,000 = 2%
250,001 - 925,000 = 5%
925,001 - 1,500,000 = 10%
1,500,001 - or more = 12%
So no tax on the first 125,000
, then 2%
on the next 124,999
and so on.
I can come up with long winded calculations with far too many lines of code. I am sure there is a relatively simple way to do this, so I am bowing to the greater knowledge of folks here to find a more concise method.
Hm, nice challenge though. I'm sorry, I couldn't really come up with a smart way, but if you are in dire need I created this little function;
function calculator($value) {
if(!is_int($value) && !is_double($value))
return;
if($value > 1500000)
$value = $value - ($value*0.12);
elseif($value > 925000)
$value = $value - ($value*0.10);
elseif($value > 250000)
$value = $value - ($value*0.05);
elseif($value > 125000)
$value = $value - ($value*0.02);
return $value;
}
You just feed it with a value (int or double) and it will return the calculated value. Be aware you can't use ,
(comma) though.
Edit: Changed to logic a little.
This won't do any number validation or currency formatting, but it does condense the snippet fairly well. I am also not sure which figure you wanted as a result, so I am returning three values: the rate, the amount of tax, and the price less the tax.
Rather than a block of if/else statements, I've elected to use array functions. (Demo)
Method #1: 2-lines and a return
function tax($value) {
$tiers=['.12'=>1500000,'.1'=>925000,'.05'=>250000,'.02'=>125000,'0'=>0];
$rate=key(array_filter($tiers,function($threshold)use($value){return $value>$threshold;}));
return [$rate,$value*$rate,$value-$value*$rate];
}
Method #2: 4-lines and a return, but more efficient
function tax($value) {
$tiers=['.12'=>1500000,'.1'=>925000,'.05'=>250000,'.02'=>125000,'0'=>0];
foreach($tiers as $rate=>$threshold){
if($value>$threshold){break;} // $rate will be preserved outside of the loop
}
return [$rate,$value*$rate,$value-$value*$rate];
}
Calling the function like this: var_export(tax(126999));
will output:
array (
0 => '.12',
1 => 1523988.0,
2 => 11175912.0,
)
Since you are placing "code brevity" ahead of "code efficiency", I would recommend Method #1. Because this task is so small/light, I don't think anyone will notice any gains via micro-optimization.
p.s. If you are not doing this multiple times in the same script and/or don't want a function call, you can declare $rate
just by using this:
$tiers=['.12'=>1500000,'.1'=>925000,'.05'=>250000,'.02'=>125000,'0'=>0];
$rate=key(array_filter($tiers,function($threshold)use($value){return $value>$threshold;}));
or
$tiers=['.12'=>1500000,'.1'=>925000,'.05'=>250000,'.02'=>125000,'0'=>0];
foreach($tiers as $rate=>$threshold){
if($value>$threshold){break;}
}