Testing new git server.
[retire.git] / tax_brackets.py
1 import copy
2 import utils
3 from money import money
4
5 class tax_brackets:
6     """A class to represent tax brackets and some operations on them."""
7
8     def __init__(self, brackets):
9         self.brackets = copy.deepcopy(brackets)
10
11     def compute_taxes_for_income(self, income):
12         """Compute the tax bill for income given our brackets."""
13         taxes_due = money(0)
14         while income > 1:
15             (threshold, rate) = self.get_bracket_for_income(income)
16             taxes_due += (income - threshold) * rate
17             income = threshold
18         assert taxes_due >= 0, "Somehow computed negative tax bill?!"
19         return taxes_due
20
21     def get_bracket_for_income(self, income):
22         """Return the bracket that the last dollar of income was in."""
23         assert income > 0, "Income should be >0 to be taxed"
24         rate = 0.0
25         threshold = 0
26         for bracket in self.brackets:
27             # Bracket is a tuple of (monetary_threshold,
28             # tax_rate).  So bracket[0] is a dollar amount and
29             # bracket[1] is a tax rate.  e.g. ( 250000, 0.20 )
30             # indicates that every dollar you earn over 250K is
31             # taxed at 20%.
32             if (income > bracket[0] and rate < bracket[1]):
33                 threshold = bracket[0]
34                 rate = bracket[1]
35         return (threshold, rate)
36
37     def get_bracket_above_income(self, income):
38         """Return the next bracket above the one activated by income."""
39         assert income > 0, "Income should be >0 to be taxed"
40         rate = 1.0
41         threshold = None
42
43         # Walk the income tax brackets and look for the one just above
44         # the one this year's income is activating.
45         for bracket in self.brackets:
46             if (bracket[0] > income and bracket[1] < rate):
47                 threshold = bracket[0]
48                 rate = bracket[1]
49
50         # Note: this can return (None, 1.0) iff the income is already
51         # in the top tax bracket.
52         return (threshold, rate)
53
54     def get_bracket_below_income(self, income):
55         """Return the next bracket below the one activated by income."""
56         assert income > 0, "Income should be >0 to be taxed"
57         bracket = self.get_bracket_for_income(income)
58         income = bracket[0]
59         return self.get_bracket_for_income(income)
60
61     def get_effective_tax_rate_for_income(self, income):
62         """Compute and return the effective tax rate for an income."""
63         if income <= 0: return 0
64         tax_bill = self.compute_taxes_for_income(income)
65         return float(tax_bill) / income
66
67     def adjust_with_multiplier(self, multiplier):
68         """Every year the IRS adjusts the income tax brackets for inflation."""
69         for bracket in self.brackets:
70             if bracket[0] != 1:
71                 bracket[0] *= multiplier
72
73     def dump(self):
74         """Print out the tax brackets we're using in here."""
75         for x in self.brackets:
76             print "{:<20} -> {:<3}".format(x[0], utils.format_rate(x[1]))