Skip to content

Commit

Permalink
Merge pull request #842 from martinholmer/add-hc-vs-bs-test
Browse files Browse the repository at this point in the history
Fix typo in BenefitSurtax function and add test_ID_HC_vs_BS
  • Loading branch information
martinholmer authored Jul 29, 2016
2 parents 05fa9ea + 1f5ea9d commit 41290b8
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 26 deletions.
2 changes: 1 addition & 1 deletion taxcalc/comparison/reform_results.txt
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ Increase Itemized Deduction phaseout rate by 1 pts
Tax-Calculator,3.6,3.8,4.0,4.1
""
limit the tax value of ID to 6% of AGI
Tax-Calculator,19.4,20.8,22.0,23.5
Tax-Calculator,19.6,21.0,22.2,23.7
Budget Options,11,9,8,7
""
CAPITAL GAIN
Expand Down
51 changes: 26 additions & 25 deletions taxcalc/functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -1159,31 +1159,32 @@ def BenefitSurtax(calc):
BenefitSurtax function: ...
"""
if calc.policy.ID_BenefitSurtax_crt != 1.:
nobenefits_calc = copy.deepcopy(calc)
# hard code the reform
nobenefits_calc.policy.ID_Medical_HC = \
int(nobenefits_calc.policy.ID_BenefitSurtax_Switch[0])
nobenefits_calc.policy.ID_StateLocalTax_HC = \
int(nobenefits_calc.policy.ID_BenefitSurtax_Switch[1])
nobenefits_calc.policy.ID_RealEstate_HC = \
int(nobenefits_calc.policy.ID_BenefitSurtax_Switch[2])
nobenefits_calc.policy.ID_casualty_HC = \
int(nobenefits_calc.policy.ID_BenefitSurtax_Switch[3])
nobenefits_calc.policy.ID_Miscellaneous_HC = \
int(nobenefits_calc.policy.ID_BenefitSurtax_Switch[4])
nobenefits_calc.policy.ID_InterestPaid_HC = \
int(nobenefits_calc.policy.ID_BenefitSurtax_Switch[5])
nobenefits_calc.policy.ID_Charity_HC = \
int(nobenefits_calc.policy.ID_BenefitSurtax_Switch[6])
nobenefits_calc.calc_one_year()
# compute income tax liability with no itemized deductions allowed for
# the types of itemized deductions covered under the BenefitSurtax
no_ID_calc = copy.deepcopy(calc)
if calc.policy.ID_BenefitSurtax_Switch[0]:
no_ID_calc.policy.ID_Medical_HC = 1.
if calc.policy.ID_BenefitSurtax_Switch[1]:
no_ID_calc.policy.ID_StateLocalTax_HC = 1.
if calc.policy.ID_BenefitSurtax_Switch[2]:
no_ID_calc.policy.ID_RealEstate_HC = 1.
if calc.policy.ID_BenefitSurtax_Switch[3]:
no_ID_calc.policy.ID_Casualty_HC = 1.
if calc.policy.ID_BenefitSurtax_Switch[4]:
no_ID_calc.policy.ID_Miscellaneous_HC = 1.
if calc.policy.ID_BenefitSurtax_Switch[5]:
no_ID_calc.policy.ID_InterestPaid_HC = 1.
if calc.policy.ID_BenefitSurtax_Switch[6]:
no_ID_calc.policy.ID_Charity_HC = 1.
no_ID_calc.calc_one_year()
# pylint: disable=protected-access
tax_diff = np.where(
nobenefits_calc.records._iitax - calc.records._iitax > 0.,
nobenefits_calc.records._iitax - calc.records._iitax,
0.)
surtax_cap = nobenefits_calc.policy.ID_BenefitSurtax_crt *\
nobenefits_calc.records.c00100
benefit_amount = np.where(
no_ID_calc.records._iitax - calc.records._iitax > 0.,
no_ID_calc.records._iitax - calc.records._iitax, 0.)
benefit_deduction = (calc.policy.ID_BenefitSurtax_crt *
calc.records.c00100)
calc.records._surtax[:] = calc.policy.ID_BenefitSurtax_trt * np.where(
tax_diff > surtax_cap, tax_diff - surtax_cap, 0.)
benefit_amount > benefit_deduction,
benefit_amount - benefit_deduction, 0.)
calc.records._iitax += calc.records._surtax
calc.records._combined = calc.records._iitax + calc.records._fica
calc.records._combined += calc.records._surtax
39 changes: 39 additions & 0 deletions taxcalc/tests/test_calculate.py
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,45 @@ def test_make_Calculator_increment_years_first():
assert_allclose(calc.policy._II_em, exp_II_em, atol=0.5, rtol=0.0)


def test_ID_HC_vs_BS():
"""
Test that complete haircut of itemized deductions produces same
results as a 100% benefit surtax with no benefit deduction.
"""
# specify complete-haircut reform policy and Calculator object
hc_reform = {2013: {
'_ID_Medical_HC': [1.0],
'_ID_StateLocalTax_HC': [1.0],
'_ID_RealEstate_HC': [1.0],
'_ID_Casualty_HC': [1.0],
'_ID_Miscellaneous_HC': [1.0],
'_ID_InterestPaid_HC': [1.0],
'_ID_Charity_HC': [1.0]}
}
hc_policy = Policy()
hc_policy.implement_reform(hc_reform)
hc_records = Records(data=TAXDATA, weights=WEIGHTS, start_year=2009)
hc_calc = Calculator(policy=hc_policy, records=hc_records)
# specify benefit-surtax reform policy and Calculator object
bs_reform = {2013: {
'_ID_BenefitSurtax_crt': [0.0],
'_ID_BenefitSurtax_trt': [1.0]}
}
bs_policy = Policy()
bs_policy.implement_reform(bs_reform)
bs_records = Records(data=TAXDATA, weights=WEIGHTS, start_year=2009)
bs_calc = Calculator(policy=bs_policy, records=bs_records)
# compare calculated tax results generated by the two reforms
hc_calc.calc_all()
bs_calc.calc_all()
assert_allclose(hc_calc.records._fica,
bs_calc.records._fica,
atol=0.01, rtol=0.0)
assert_allclose(hc_calc.records._iitax,
bs_calc.records._iitax,
atol=0.01, rtol=0.0)


def test_Calculator_using_nonstd_input(rawinputfile):
# check Calculator handling of raw, non-standard input data with no aging
policy = Policy()
Expand Down

0 comments on commit 41290b8

Please sign in to comment.