Weekly Challenge 323
Each week Mohammad S. Anwar sends out The Weekly Challenge, a chance for all of us to come up with solutions to two weekly tasks. My solutions are written in Python first, and then converted to Perl. It's a great way for us all to practice some coding.
Task 1: Increment Decrement
Task
You are given a list of operations.
Write a script to return the final value after performing the given operations in order. The initial value is always 0.
My solution
This one is relatively straight forward, so doesn't need much explanation. I start with counter
set to zero. I loop through each operator, adding or subtracting 1 as needed. I will raise an ValueError
(die
in Perl) if an operator is not expected.
def increment_decrement(operations: list) -> int:
counter = 0
for operation in operations:
if operation == "x++" or operation == "++x":
counter += 1
elif operation == "x--" or operation == "--x":
counter -= 1
else:
raise ValueError(f"Unknown operation: {operation}")
return counter
The Perl code follows the same logic, with slightly different syntax.
Examples
$ ./ch-1.py --x x++ x++
1
$ ./ch-1.py x++ ++x x++
3
$ ./ch-1.py x++ ++x --x x--
0
Task 2: Tax Amount
Task
You are given an income amount and tax brackets.
Write a script to calculate the total tax amount.
My solution
For input from the command line, I take an odd number of numbers. The first number is income
variable, the remaining items are the tax brackets.
def main():
# Convert input into floating point numbers
array = [float(n) for n in sys.argv[1:]]
if len(array) < 3 or len(array) % 2 == 0:
raise ValueError("Input must contain at least one income and at least one tax bracket.")
income = array[0]
tax_brackets = [array[i:i + 2] for i in range(1, len(array), 2)]
result = tax_amount(income, tax_brackets)
print(result)
The Perl solution is similar, but uses the shift
function to get the values.
sub main (@numbers) {
# Check we have an odd number of arguments
die "Please provide an odd number of arguments" if @numbers % 2 == 0;
my $income = shift(@numbers);
my @tax_brackets = ();
while ( scalar(@numbers) ) {
push @tax_brackets, [ shift(@numbers), shift(@numbers) ];
}
The examples don't mention what happens when the income
is higher than the last tax bucket. As such I raise an error if this occurs.
def tax_amount(income, tax_brackets: list) -> float:
if income > tax_brackets[-1][0]:
raise ValueError("Income exceeds the last tax bracket limit.")
The next thing I do is prepend a list (array in Perl) of [0, 0]
to the tax_brackets
list. I also set the total_tax
value to 0
.
tax_brackets.insert(0, [0, 0])
total_tax = 0
In then loop from 1 to the length of tax_brackets
list with the variable idx
. I set the variable tax_threshold
and tax_rate
from the tax_brackets
list.
The tax for this bracket is defined as
- the minimum of
income
ortax_threshold
- minus the threshold of the previous rate
- multiplied by the tax rate (which is divided by 100)
If the income
is less than or equal to the tax_threshold
, we don't need to calculate any more and can exit the loop.
for idx in range(1, len(tax_brackets)):
tax_threshold, tax_rate = tax_brackets[idx]
total_tax += (min(income, tax_threshold) - tax_brackets[idx - 1][0]) * (tax_rate / 100)
if income <= tax_threshold:
break
return round(total_tax, 2)
The Perl code follows the same logic as the Python solution.
Examples
$ ./ch-2.py 10 3 50 7 10 12 25
2.65
$ ./ch-2.py 2 1 0 4 25 5 50
0.25
$ ./ch-2.py 0 2 50
0.0
Top comments (0)