Skip to content

Instantly share code, notes, and snippets.

@saxbophone
Created January 25, 2019 14:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save saxbophone/3302b3ae7a880dc3679a259944cf213a to your computer and use it in GitHub Desktop.
Save saxbophone/3302b3ae7a880dc3679a259944cf213a to your computer and use it in GitHub Desktop.
I'm not quite as good as calculating income tax as I thought I was...
from decimal import Decimal
DEFAULT_PERSONAL_ALLOWANCE = Decimal(11_850)
PERSONAL_ALLOWANCE_ADJUSTMENT_BEGIN = Decimal(100_000)
BASIC_RATE_BEGIN = DEFAULT_PERSONAL_ALLOWANCE
HIGHER_RATE_BEGIN = Decimal(46_350)
ADDITIONAL_RATE_BEGIN = Decimal(150_000)
BASIC_RATE = Decimal(0.20)
HIGHER_RATE = Decimal(0.40)
ADDITIONAL_RATE = Decimal(0.45)
def income_tax(s):
# make sure salary is stored as Decimal type
salary = Decimal(s)
# everyone gets the default personal allowance to start with
personal_allowance = DEFAULT_PERSONAL_ALLOWANCE
# calculate any personal allowance adjustments
if salary > PERSONAL_ALLOWANCE_ADJUSTMENT_BEGIN:
# personal allowance goes down by GBP1 for every GBP2 over 100k
personal_allowance -= (
(salary - PERSONAL_ALLOWANCE_ADJUSTMENT_BEGIN) / 2
)
# this guards against ending up with a negative personal allowance
personal_allowance = max(personal_allowance, Decimal(0))
# take_home tracks take-home pay, taxable tracks tax to pay
take_home = min(personal_allowance, salary)
taxable = Decimal(0)
salary -= take_home
# now that the personal allowance is out of the way, calculate up tax bands
if salary > 0:
# basic rate
basic_rate_taxable = min(HIGHER_RATE_BEGIN - BASIC_RATE_BEGIN, salary)
take_home += basic_rate_taxable * (1 - BASIC_RATE)
taxable += basic_rate_taxable * BASIC_RATE
salary -= basic_rate_taxable
if salary > 0:
# higher rate
higher_rate_taxable = min(ADDITIONAL_RATE_BEGIN - HIGHER_RATE_BEGIN, salary)
take_home += higher_rate_taxable * (1 - HIGHER_RATE)
taxable += higher_rate_taxable * HIGHER_RATE
salary -= higher_rate_taxable
if salary > 0:
# additional rate -this is calculated on any remaining income
additional_rate_taxable = salary
take_home += additional_rate_taxable * (1 - ADDITIONAL_RATE)
taxable += additional_rate_taxable * ADDITIONAL_RATE
salary -= additional_rate_taxable
# these post-conditional assertions perform basic sanity checks
assert salary == 0. # we should have accounted for all income
# take-home + taxable = original salary
# FIXME: below assertion doesn't always work. maybe being too picky
# assert (take_home + taxable) == Decimal(s)
return (take_home, taxable)
for i in range(0, 201_000, 1_000):
take_home, taxable = income_tax(i)
print(i, take_home, taxable)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment