# Income tax calculator [closed]

I've just started coding and have written a program to calculate your tax to be paid. Is there anywhere where I can improve this?

while True:
try:

except ValueError:
print("Sorry, I didn't understand that please enter taxable income as a number")

continue
else:

break
if income <= 18200:
tax = 0

elif income <= 37000:
tax = (income - 18200) * 0.19

elif income <= 90000:
tax = (income-37000) * 0.235 + 3572

elif income <= 180000:
tax = (income - 90000) * 0.37 + 20797

else:
tax = (income - 180000) * 0.45 + 54097

print("you owe", tax, "dollars in tax!" )

• identation isnt proper – Lalit Verma Aug 14 '19 at 7:35
• @LalitVerma At first I thought the try line was just indented too far, but actually all the rest of the code is at the wrong level... – Graipher Aug 14 '19 at 7:54
• To properly indent your code: remove the current code, paste your original code, select your freshly-pasted code and hit Ctrl+K. Or use an editor to give every line of code 4 extra spaces, that does the same thing. Considering indentation is very important in Python, you'll have to fix it to comply with our help center (which requires code to work). – Mast Aug 14 '19 at 8:35
• AFAICT that's not working code, even if indented properly. The code after the try block can't be executed, because it'll either break or continue before reaching it. – l0b0 Aug 14 '19 at 8:48
• That depends on how wrong the indentation is. If the rest of the code is supposed to be outside the while loop it would work. – Graipher Aug 14 '19 at 8:53

Given the bad indentation of the original code, I will assume you meant to post code that looks like this

while True:
try:

except ValueError:
print("Sorry, I didn't understand that please enter taxable income as a number")

continue
else:
break

if income <= 18200:
tax = 0

elif income <= 37000:
tax = (income - 18200) * 0.19

elif income <= 90000:
tax = (income-37000) * 0.235 + 3572

elif income <= 180000:
tax = (income - 90000) * 0.37 + 20797

else:
tax = (income - 180000) * 0.45 + 54097

print("you owe", tax, "dollars in tax!" )


I would suggest you use an IDE or a linter, both of which will point out syntax problems in the code.

The idea behind the code can be summarized as

Get the income from user input
Calculate the tax
Print the amount owed


This is a good structure to have. You have three clear boundaries and have split the work appropriately. You can make this explicit with well named functions. I would lay it out like this

def get_income():
while True:
try:

except ValueError:
print("Sorry, I didn't understand that please enter taxable income as a number")

continue
else:
break

return income

def compute_tax(income):
if income <= 18200:
tax = 0
elif income <= 37000:
tax = (income - 18200) * 0.19
elif income <= 90000:
tax = (income - 37000) * 0.235 + 3572
elif income <= 180000:
tax = (income - 90000) * 0.37 + 20797
else:
tax = (income - 180000) * 0.45 + 54097

return tax

if __name__ == "__main__":
income = get_income()
tax = compute_tax(income)
print("you owe", tax, "dollars in tax!")


The advantage of this is that your code for working out how much tax is owed is easy to use in another python module.

# tax_credits.py
from tax import compute_tax
...


If we look at how the tax is computed, the pattern is very clear. At each tax bracket we subtract an amount, multiply by a percentage, and add back an amount

tax = (income - S) * P + A


We could change the code to first figure out the tax bracket the income falls into, then compute the tax amount. While this doesn't look any better now, it will be beneficial to explore this path.

def compute_tax(income):
if income <= 18200:
S, P, A = 0, 0, 0  # Values picked so the tax amount is always 0.
elif income <= 37000:
S, P, A = 18200, 0.19, 0
elif income <= 90000:
S, P, A = 37000, 0.235, 3572
elif income <= 180000:
S, P, A = 90000, 0.37, 20797
else:
S, P, A = 180000, 0.45, 54097

tax = (income - S) * P + A
return tax


Since this repeated code now looks a bit easier to manager, let's turn it into a loop. I'll leave the details out as there are a few features of python that might be new to you, and are worth looking up yourself.

def compute_tax(income):
# (C,      P,       A)
# S is reused from the previous iteration of the loop
# so no need to store it.
tax_brackets = (
(18200, 0, 0), (37000, 0.19, 0), (90000, 0.235, 3572), (180000, 0.37, 20797)
)
# The final bracket, use if the income is bigger than any cutoff
last_bracket = (None, 0.45, 54097)
previous_cutoff = 0
for cutoff, percent, additive in tax_brackets:
if income <= cutoff:
break
previous_cutoff = cutoff
else:
# If we get here we never found a bracket to stop in

tax = (income - previous_cutoff) * percent + additive
return tax


We should probably include some sanity checks incase somebody incorrectly changes values. As an example, we could check each cutoff is bigger than the last.

Note that this code is a bit denser than the original, and I don't know if I would recommend using a loop. If the original code ever gets more complex this is how I would try and simplify it. But until then I would leave the explicit if/elif/else statements in previous suggestion.

def get_income():
while True:
try:

except ValueError:
print("Sorry, I didn't understand that please enter taxable income as a number")

continue
else:
break

return income


The logic here is pretty solid. I would be hesitant to change to much. The only thing I do not like is int, as it is perfectly reasonable to earn a fractional unit of the currency.

There are a lot of ways you could code this sort of function. Here is one alternative that removes a few unnecessary parts.

def get_income():
while True:
try:
except ValueError:
print("Sorry, I didn't understand that please enter taxable income as a number")

• wow thanks for that, I definitely have alot to learn – AMG_ Aug 14 '19 at 14:45

Hello @AMG_ and welcome to codereview.

One good thing here is checking that the user input is a number. It's a good habit to always assume user input is broken, and give them an indication of what's going wrong. You can also do other validation at this stage. What should happen if, for example, they enter a negative number? By the way, although python does support try...except...else the else is a bit of a niche feature. It's more common, and hence easier for python programmers to see that it's correct, if you put the break at the end of the try section.

One cause for concern is the magic numbers in this code. If, say the government changed the 0.19 threshold from 37k to 38k, you'd need to remember to change the 37000 in both its own band and the 90000 band. Moreover, because I know the idea behind marginal tax rates, I know what 20797 is meant to refer to. Even though I'm aware of it now I'm not checking whether the calculation is accurate. If the government changed the 37000 tax band, all those numbers would need to change and it would be terribly easy to miss one.

This code would be more maintainable if there were a list of thresholds all in one place, and the contribution from lower tax bands were calculated by the code rather than hard coded.

I would split the bit of code which calculates the tax into a function. It's generally considered good practice to split code which does user interaction (display and keyboard parsing) away from code which does calculations. The behaviour would be the same, but it's much easier to follow what's going on.

• Hi, thanks for that. I am just learning so could you talk me through how i could change it to have thresholds? and the splitting also? – AMG_ Aug 14 '19 at 13:45