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