DEV Community

Simon Green
Simon Green

Posted on

Weekly Challenge: Counting the tax

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.

Challenge, My solutions

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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)
Enter fullscreen mode Exit fullscreen mode

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) ];
    }
Enter fullscreen mode Exit fullscreen mode

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.")
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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 or tax_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)
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Top comments (0)