Adding comments and asserts.
[retire.git] / retire.py
index 270c608e094d4a19d76a958e3708563839baf4b4..a0b28cd2036fdd0115aa23bc96a6d65da535dc8a 100755 (executable)
--- a/retire.py
+++ b/retire.py
@@ -141,107 +141,107 @@ class simulation(object):
         adjusted_lynn_annual_social_security_dollars = (
             self.params.get_initial_social_security_benefit(constants.LYNN))
 
-#        try:
-        for self.year in xrange(2020, 2080):
-            self.scott_age = self.year - 1974
-            self.lynn_age = self.year - 1964
-            self.alex_age = self.year - 2005
-
-            # Computed money needed this year based on inflated budget.
-            money_needed = adjusted_annual_expenses
-
-            # When Alex is in college, we need $50K more per year.
-            if self.alex_age > 18 and self.alex_age <= 22:
-                money_needed += 50000
-
-            self.dump_annual_header(money_needed)
-
-            # Now, figure out how to find money to pay for this year
-            # and how much of it is taxable.
-            total_income = 0
-
-            # When we reach a certain age we have to take RMDs from
-            # some accounts.  Handle that here.
-            rmds = self.do_rmd_withdrawals(taxes)
-            if rmds > 0:
-                print "## Satisfied %s of RMDs from age-restricted accounts." % utils.format_money(rmds)
-                total_income += rmds
-                money_needed -= rmds
-
-            # When we reach a certain age we are eligible for SS
-            # payments.
-            ss = self.get_social_security(adjusted_scott_annual_social_security_dollars,
-                                          adjusted_lynn_annual_social_security_dollars,
-                                          taxes)
-            if ss > 0:
-                print "## Social security paid %s" % utils.format_money(ss)
-                total_income += ss
-                money_needed -= ss
-
-            # If we still need money, try to go find it.
-            if money_needed > 0:
-                self.go_find_money(money_needed, taxes)
-                total_income += money_needed
-                money_needed = 0
-
-            look_for_conversions = True
-            while True:
-                # Maybe do some opportunistic Roth conversions.
-                taxes_due = taxes.approximate_taxes(
-                    self.params.get_federal_standard_deduction(),
-                    self.params.get_federal_ordinary_income_tax_brackets(),
-                    self.params.get_federal_dividends_and_long_term_gains_income_tax_brackets())
-                total_income = taxes.get_total_income()
-                tax_rate = float(taxes_due) / float(total_income)
-                print "INCOME: %s, TAXES: %s\n" % (utils.format_money(total_income), utils.format_money(taxes_due))
-
-                if (look_for_conversions and
-                    tax_rate <= 0.14 and
-                    taxes_due < 20000 and
-                    self.year <= 2035):
-
-                    look_for_conversions = self.do_opportunistic_roth_conversions(taxes)
-                    # because these conversions affect taxes, spin
-                    # once more in the loop and recompute taxes
-                    # due and tax rate.
+        try:
+            for self.year in xrange(2020, 2080):
+                self.scott_age = self.year - 1974
+                self.lynn_age = self.year - 1964
+                self.alex_age = self.year - 2005
+
+                # Computed money needed this year based on inflated budget.
+                money_needed = adjusted_annual_expenses
+
+                # When Alex is in college, we need $50K more per year.
+                if self.alex_age > 18 and self.alex_age <= 22:
+                    money_needed += 50000
+
+                self.dump_annual_header(money_needed)
+
+                # Now, figure out how to find money to pay for this year
+                # and how much of it is taxable.
+                total_income = 0
+
+                # When we reach a certain age we have to take RMDs from
+                # some accounts.  Handle that here.
+                rmds = self.do_rmd_withdrawals(taxes)
+                if rmds > 0:
+                    print "## Satisfied %s of RMDs from age-restricted accounts." % utils.format_money(rmds)
+                    total_income += rmds
+                    money_needed -= rmds
+
+                # When we reach a certain age we are eligible for SS
+                # payments.
+                ss = self.get_social_security(adjusted_scott_annual_social_security_dollars,
+                                              adjusted_lynn_annual_social_security_dollars,
+                                              taxes)
+                if ss > 0:
+                    print "## Social security paid %s" % utils.format_money(ss)
+                    total_income += ss
+                    money_needed -= ss
+
+                # If we still need money, try to go find it.
+                if money_needed > 0:
+                    self.go_find_money(money_needed, taxes)
+                    total_income += money_needed
+                    money_needed = 0
+
+                look_for_conversions = True
+                while True:
+                    # Maybe do some opportunistic Roth conversions.
+                    taxes_due = taxes.approximate_taxes(
+                        self.params.get_federal_standard_deduction(),
+                        self.params.get_federal_ordinary_income_tax_brackets(),
+                        self.params.get_federal_dividends_and_long_term_gains_income_tax_brackets())
+                    total_income = taxes.get_total_income()
+                    tax_rate = float(taxes_due) / float(total_income)
+                    print "INCOME: %s, TAXES: %s\n" % (utils.format_money(total_income), utils.format_money(taxes_due))
+
+                    if (look_for_conversions and
+                        tax_rate <= 0.14 and
+                        taxes_due < 20000 and
+                        self.year <= 2035):
+
+                        look_for_conversions = self.do_opportunistic_roth_conversions(taxes)
+                        # because these conversions affect taxes, spin
+                        # once more in the loop and recompute taxes
+                        # due and tax rate.
+                    else:
+                        break
+
+                # Pay taxes_due by going to find more money.  This is a
+                # bit hacky since withdrawing more money to cover taxes
+                # will, in turn, cause taxable income.  But I think taxes
+                # are low enough and this simulation is rough enough that
+                # we can ignore this.
+                if taxes_due > 0:
+                    print "## Estimated federal tax due: %s (this year's tax rate=%s)" % (
+                        utils.format_money(taxes_due),
+                        utils.format_rate(tax_rate))
+                    self.go_find_money(taxes_due, taxes)
                 else:
-                    break
-
-            # Pay taxes_due by going to find more money.  This is a
-            # bit hacky since withdrawing more money to cover taxes
-            # will, in turn, cause taxable income.  But I think taxes
-            # are low enough and this simulation is rough enough that
-            # we can ignore this.
-            if taxes_due > 0:
-                print "## Estimated federal tax due: %s (this year's tax rate=%s)" % (
-                    utils.format_money(taxes_due),
-                    utils.format_rate(tax_rate))
-                self.go_find_money(taxes_due, taxes)
-            else:
-                print "## No federal taxes due this year!"
-            taxes.record_taxes_paid_and_reset_for_next_year(taxes_due)
-
-            # Inflation and appreciation:
-            #   * Cost of living increases
-            #   * Social security benefits increase
-            #   * Tax brackets are adjusted for inflation
-            inflation_multiplier = self.params.get_average_inflation_multiplier()
-            adjusted_annual_expenses *= inflation_multiplier
-            for x in self.accounts:
-                x.appreciate(self.params.get_average_investment_return_multiplier())
-            if self.scott_age >= self.params.get_initial_social_security_age(constants.SCOTT):
-                adjusted_scott_annual_social_security_dollars *= self.params.get_average_social_security_multiplier()
-            if self.lynn_age >= self.params.get_initial_social_security_age(constants.LYNN):
-                adjusted_lynn_annual_social_security_dollars *= self.params.get_average_social_security_multiplier()
-
-            self.params.get_federal_ordinary_income_tax_brackets().adjust_with_multiplier(inflation_multiplier)
-            self.params.get_federal_dividends_and_long_term_gains_income_tax_brackets().adjust_with_multiplier(inflation_multiplier)
-#        except:
-#            print "Ran out of money!!!"
-#            pass
-
-#        finally:
-        self.dump_final_report(taxes)
+                    print "## No federal taxes due this year!"
+                taxes.record_taxes_paid_and_reset_for_next_year(taxes_due)
+
+                # Inflation and appreciation:
+                #   * Cost of living increases
+                #   * Social security benefits increase
+                #   * Tax brackets are adjusted for inflation
+                inflation_multiplier = self.params.get_average_inflation_multiplier()
+                adjusted_annual_expenses *= inflation_multiplier
+                for x in self.accounts:
+                    x.appreciate(self.params.get_average_investment_return_multiplier())
+                if self.scott_age >= self.params.get_initial_social_security_age(constants.SCOTT):
+                    adjusted_scott_annual_social_security_dollars *= self.params.get_average_social_security_multiplier()
+                if self.lynn_age >= self.params.get_initial_social_security_age(constants.LYNN):
+                    adjusted_lynn_annual_social_security_dollars *= self.params.get_average_social_security_multiplier()
+
+                self.params.get_federal_ordinary_income_tax_brackets().adjust_with_multiplier(inflation_multiplier)
+                self.params.get_federal_dividends_and_long_term_gains_income_tax_brackets().adjust_with_multiplier(inflation_multiplier)
+        except:
+            print "Ran out of money!!!"
+            pass
+
+        finally:
+            self.dump_final_report(taxes)
 
 # main
 params = parameters().with_default_values()