def test_consumption_response(cps_subsample): consump = Consumption() mpc = 0.5 consumption_response = {'MPC_e20400': {2013: mpc}} consump.update_consumption(consumption_response) # test incorrect call to response method with pytest.raises(ValueError): consump.response(list(), 1) # test correct call to response method rec = Records.cps_constructor(data=cps_subsample) pre = copy.deepcopy(rec.e20400) consump.response(rec, 1.0) post = rec.e20400 actual_diff = post - pre expected_diff = np.ones(rec.array_length) * mpc assert np.allclose(actual_diff, expected_diff) # compute earnings mtr with no consumption response rec = Records.cps_constructor(data=cps_subsample) ided0 = copy.deepcopy(rec.e20400) calc0 = Calculator(policy=Policy(), records=rec, consumption=None) (mtr0_ptax, mtr0_itax, _) = calc0.mtr(variable_str='e00200p', wrt_full_compensation=False) assert np.allclose(calc0.array('e20400'), ided0) # compute earnings mtr with consumption response calc1 = Calculator(policy=Policy(), records=rec, consumption=consump) mtr1_ptax, mtr1_itax, _ = calc1.mtr(variable_str='e00200p', wrt_full_compensation=False) assert np.allclose(calc1.array('e20400'), ided0) # confirm that payroll mtr values are no different assert np.allclose(mtr1_ptax, mtr0_ptax) # confirm that all mtr with cons-resp are no greater than without cons-resp assert np.all(np.less_equal(np.around(mtr1_itax, decimals=5), np.around(mtr0_itax, decimals=5))) # confirm that some mtr with cons-resp are less than without cons-resp assert np.any(np.less(mtr1_itax, mtr0_itax))
def test_calc_and_used_vars(tests_path): """ Runs two kinds of tests on variables used in the calcfunctions.py file: (1) Checks that each var in Records.CALCULATED_VARS is actually calculated If test (1) fails, a variable in Records.CALCULATED_VARS was not calculated in any function in the calcfunctions.py file. With the exception of a few variables listed in this test, all Records.CALCULATED_VARS must be calculated in the calcfunctions.py file. (2) Check that each variable that is calculated in a function and returned by that function is an argument of that function. """ # pylint: disable=too-many-locals funcpath = os.path.join(tests_path, '..', 'calcfunctions.py') gfd = GetFuncDefs() fnames, fargs, cvars, rvars = gfd.visit(ast.parse(open(funcpath).read())) # Test (1): # .. create set of vars that are actually calculated in calcfunctions.py all_cvars = set() for fname in fnames: if fname == 'BenefitSurtax': continue # because BenefitSurtax is not really a function all_cvars.update(set(cvars[fname])) # .. add to all_cvars set variables calculated in Records class all_cvars.update(set(['num', 'sep', 'exact'])) # .. add to all_cvars set variables calculated elsewhere all_cvars.update(set(['mtr_paytax', 'mtr_inctax'])) all_cvars.update(set(['benefit_cost_total', 'benefit_value_total'])) # .. check that each var in Records.CALCULATED_VARS is in the all_cvars set Records.read_var_info() found_error1 = False if not Records.CALCULATED_VARS <= all_cvars: msg1 = ('all Records.CALCULATED_VARS not calculated ' 'in calcfunctions.py\n') for var in Records.CALCULATED_VARS - all_cvars: found_error1 = True msg1 += 'VAR NOT CALCULATED: {}\n'.format(var) # Test (2): faux_functions = ['EITCamount', 'ComputeBenefit', 'BenefitPrograms', 'BenefitSurtax', 'BenefitLimitation'] found_error2 = False msg2 = 'calculated & returned variables are not function arguments\n' for fname in fnames: if fname in faux_functions: continue # because fname is not a genuine function crvars_set = set(cvars[fname]) & set(rvars[fname]) if not crvars_set <= set(fargs[fname]): found_error2 = True for var in crvars_set - set(fargs[fname]): msg2 += 'FUNCTION,VARIABLE: {} {}\n'.format(fname, var) # Report errors for the two tests: if found_error1 and found_error2: raise ValueError('{}\n{}'.format(msg1, msg2)) if found_error1: raise ValueError(msg1) if found_error2: raise ValueError(msg2)
def test_validity_of_name_lists(): assert len(DIST_TABLE_COLUMNS) == len(DIST_TABLE_LABELS) Records.read_var_info() assert set(DIST_VARIABLES).issubset(Records.CALCULATED_VARS | {'s006'}) extra_vars_set = set(['num_returns_StandardDed', 'num_returns_ItemDed', 'num_returns_AMT']) assert (set(DIST_TABLE_COLUMNS) - set(DIST_VARIABLES)) == extra_vars_set
def test_correct_Records_instantiation(): rec1 = Records(data=TAXDATA, blowup_factors=None, weights=WEIGHTS) assert rec1 assert np.all(rec1.MARS != 0) assert rec1.current_year == Records.PUF_YEAR sum_e00200_in_puf_year = rec1.e00200.sum() rec1.set_current_year(Records.PUF_YEAR + 1) sum_e00200_in_puf_year_plus_one = rec1.e00200.sum() assert sum_e00200_in_puf_year_plus_one == sum_e00200_in_puf_year bf_df = pd.read_csv(Records.BLOWUP_FACTORS_PATH) rec2 = Records(data=TAXDATA, blowup_factors=bf_df, weights=None) assert rec2 assert np.all(rec2.MARS != 0) assert rec2.current_year == Records.PUF_YEAR
def test_correct_Records_instantiation_sample(puf_1991, weights_1991): sample = puf_1991.sample(frac=0.10) rec1 = Records(data=sample, blowup_factors=None, weights=weights_1991) assert rec1 assert np.all(rec1.MARS != 0) assert rec1.current_year == Records.PUF_YEAR sum_e00200_in_puf_year = rec1.e00200.sum() rec1.set_current_year(Records.PUF_YEAR + 1) sum_e00200_in_puf_year_plus_one = rec1.e00200.sum() assert sum_e00200_in_puf_year_plus_one == sum_e00200_in_puf_year bf_df = pd.read_csv(Records.BLOWUP_FACTORS_PATH) rec2 = Records(data=sample, blowup_factors=bf_df, weights=None) assert rec2 assert np.all(rec2.MARS != 0) assert rec2.current_year == Records.PUF_YEAR
def test_itax_compare(tests_path, using_puf, puf_fullsample, cps_fullsample): """ Conduct income tax comparisons using ITAX data. """ using_puf_adjust_ratios = True # generate 2015 estimates by AGI category using Tax-Calculator if using_puf: if using_puf_adjust_ratios: recs = Records(data=puf_fullsample) else: recs = Records(data=puf_fullsample, adjust_ratios=None) else: recs = Records.cps_constructor(data=cps_fullsample) calc = Calculator(policy=Policy(), records=recs, verbose=False) calc.advance_to_year(2015) calc.calc_all() # open actual output file if using_puf: afilename = os.path.join(tests_path, 'cmpi_puf_actual.txt') else: afilename = os.path.join(tests_path, 'cmpi_cps_actual.txt') afile = open(afilename, 'w') # write compare results to afile for cname in sorted(ITAX.keys()): comparison(cname, calc, ITAX, afile) # close actual output file afile.close() # check for differences between actual and expect output files efilename = afilename.replace('actual', 'expect') differences(afilename, efilename)
def test_distribution_tables(cps_subsample): """ Test distribution_tables method. """ pol = Policy() recs = Records.cps_constructor(data=cps_subsample) calc1 = Calculator(policy=pol, records=recs) assert calc1.current_year == 2014 calc1.calc_all() dt1, dt2 = calc1.distribution_tables(None, 'weighted_deciles') assert isinstance(dt1, pd.DataFrame) assert dt2 is None dt1, dt2 = calc1.distribution_tables(calc1, 'weighted_deciles') assert isinstance(dt1, pd.DataFrame) assert isinstance(dt2, pd.DataFrame) reform = {2014: {'_UBI_u18': [1000], '_UBI_1820': [1000], '_UBI_21': [1000]}} pol.implement_reform(reform) assert not pol.parameter_errors calc2 = Calculator(policy=pol, records=recs) calc2.calc_all() dt1, dt2 = calc1.distribution_tables(calc2, 'weighted_deciles') assert isinstance(dt1, pd.DataFrame) assert isinstance(dt2, pd.DataFrame)
def test_make_calculator_with_multiyear_reform(cps_subsample): """ Test Calculator class ctor with multi-year policy reform. """ rec = Records.cps_constructor(data=cps_subsample) year = rec.current_year # create a Policy object and apply a policy reform pol = Policy() reform = {2015: {}, 2016: {}} reform[2015]['_II_em'] = [5000, 6000] # reform values for 2015 and 2016 reform[2015]['_II_em_cpi'] = False reform[2016]['_STD_Aged'] = [[1600, 1300, 1600, 1300, 1600]] pol.implement_reform(reform) # create a Calculator object using this policy-reform calc = Calculator(policy=pol, records=rec) # check that Policy object embedded in Calculator object is correct assert pol.num_years == Policy.DEFAULT_NUM_YEARS assert calc.current_year == year assert calc.policy_param('II_em') == 3950 exp_II_em = [3900, 3950, 5000] + [6000] * (Policy.DEFAULT_NUM_YEARS - 3) assert np.allclose(calc.policy_param('_II_em'), np.array(exp_II_em)) calc.increment_year() calc.increment_year() assert calc.current_year == 2016 assert np.allclose(calc.policy_param('STD_Aged'), np.array([1600, 1300, 1600, 1300, 1600]))
def test_n65(cps_subsample): """ Test n65 method. """ recs = Records.cps_constructor(data=cps_subsample) calc = Calculator(policy=Policy(), records=recs) assert calc.n65().sum() > 1500
def test_make_calculator_raises_on_no_policy(cps_subsample): """ Test Calculator ctor error with no policy argument. """ rec = Records.cps_constructor(data=cps_subsample) with pytest.raises(ValueError): Calculator(records=rec)
def test_make_calculator_increment_years_first(cps_subsample): """ Test Calculator inflation indexing of policy parameters. """ # pylint: disable=too-many-locals # create Policy object with policy reform pol = Policy() reform = {2015: {}, 2016: {}} std5 = 2000 reform[2015]['_STD_Aged'] = [[std5, std5, std5, std5, std5]] reform[2015]['_II_em'] = [5000] reform[2016]['_II_em'] = [6000] reform[2016]['_II_em_cpi'] = False pol.implement_reform(reform) # create Calculator object with Policy object as modified by reform rec = Records.cps_constructor(data=cps_subsample) calc = Calculator(policy=pol, records=rec) # compare expected policy parameter values with those embedded in calc irates = pol.inflation_rates() syr = Policy.JSON_START_YEAR irate2015 = irates[2015 - syr] irate2016 = irates[2016 - syr] std6 = std5 * (1.0 + irate2015) std7 = std6 * (1.0 + irate2016) exp_STD_Aged = np.array([[1500, 1200, 1200, 1500, 1500], [1550, 1200, 1200, 1550, 1550], [std5, std5, std5, std5, std5], [std6, std6, std6, std6, std6], [std7, std7, std7, std7, std7]]) act_STD_Aged = calc.policy_param('_STD_Aged') assert np.allclose(act_STD_Aged[:5], exp_STD_Aged) exp_II_em = np.array([3900, 3950, 5000, 6000, 6000]) act_II_em = calc.policy_param('_II_em') assert np.allclose(act_II_em[:5], exp_II_em)
def test_mtr_graph_data(cps_subsample): recs = Records.cps_constructor(data=cps_subsample) calc = Calculator(policy=Policy(), records=recs) year = calc.current_year with pytest.raises(ValueError): mtr_graph_data(None, year, mars='bad', income_measure='agi', dollar_weighting=True) with pytest.raises(ValueError): mtr_graph_data(None, year, mars=0, income_measure='expanded_income', dollar_weighting=True) with pytest.raises(ValueError): mtr_graph_data(None, year, mars=list()) with pytest.raises(ValueError): mtr_graph_data(None, year, mars='ALL', mtr_variable='e00200s') with pytest.raises(ValueError): mtr_graph_data(None, year, mtr_measure='badtax') with pytest.raises(ValueError): mtr_graph_data(None, year, income_measure='badincome') mtr = 0.20 * np.ones_like(cps_subsample['e00200']) vdf = calc.dataframe(['s006', 'MARS', 'e00200']) vdf['mtr1'] = mtr vdf['mtr2'] = mtr vdf = vdf[vdf['MARS'] == 1] gdata = mtr_graph_data(vdf, year, mars=1, mtr_wrt_full_compen=True, income_measure='wages', dollar_weighting=True) assert isinstance(gdata, dict)
def test_ID_HC_vs_BS(cps_subsample): """ Test that complete haircut of itemized deductions produces same results as a 100% benefit surtax with no benefit deduction. """ recs = Records.cps_constructor(data=cps_subsample) # 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_calc = Calculator(policy=hc_policy, records=recs) hc_calc.calc_all() hc_taxes = hc_calc.dataframe(['iitax', 'payrolltax']) del hc_calc # 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_calc = Calculator(policy=bs_policy, records=recs) bs_calc.calc_all() bs_taxes = bs_calc.dataframe(['iitax', 'payrolltax']) del bs_calc # compare calculated taxes generated by the two reforms assert np.allclose(hc_taxes['payrolltax'], bs_taxes['payrolltax']) assert np.allclose(hc_taxes['iitax'], bs_taxes['iitax'])
def test_make_calculator_with_policy_reform(cps_subsample): """ Test Calculator class ctor with policy reform. """ rec = Records.cps_constructor(data=cps_subsample) year = rec.current_year # create a Policy object and apply a policy reform pol = Policy() reform = {2013: {'_II_em': [4000], '_II_em_cpi': False, '_STD_Aged': [[1600, 1300, 1300, 1600, 1600]], '_STD_Aged_cpi': False}} pol.implement_reform(reform) # create a Calculator object using this policy reform calc = Calculator(policy=pol, records=rec) # check that Policy object embedded in Calculator object is correct assert calc.current_year == year assert calc.policy_param('II_em') == 4000 assert np.allclose(calc.policy_param('_II_em'), np.array([4000] * Policy.DEFAULT_NUM_YEARS)) exp_STD_Aged = [[1600, 1300, 1300, 1600, 1600]] * Policy.DEFAULT_NUM_YEARS assert np.allclose(calc.policy_param('_STD_Aged'), np.array(exp_STD_Aged)) assert np.allclose(calc.policy_param('STD_Aged'), np.array([1600, 1300, 1300, 1600, 1600]))
def test_dec_graph_plots(cps_subsample): pol = Policy() rec = Records.cps_constructor(data=cps_subsample) calc1 = Calculator(policy=pol, records=rec) year = 2020 calc1.advance_to_year(year) reform = { 'SS_Earnings_c': {year: 9e99}, # OASDI FICA tax on all earnings 'FICA_ss_trt': {year: 0.107484} # lower rate to keep revenue unchanged } pol.implement_reform(reform) calc2 = Calculator(policy=pol, records=rec) calc2.advance_to_year(year) assert calc1.current_year == calc2.current_year calc1.calc_all() calc2.calc_all() fig = calc1.decile_graph(calc2) assert fig dt1, dt2 = calc1.distribution_tables(calc2, 'weighted_deciles') dta = dec_graph_data(dt1, dt2, year, include_zero_incomes=True, include_negative_incomes=False) assert isinstance(dta, dict) dta = dec_graph_data(dt1, dt2, year, include_zero_incomes=False, include_negative_incomes=True) assert isinstance(dta, dict) dta = dec_graph_data(dt1, dt2, year, include_zero_incomes=False, include_negative_incomes=False) assert isinstance(dta, dict)
def test_write_graph_file(cps_subsample): recs = Records.cps_constructor(data=cps_subsample) calc = Calculator(policy=Policy(), records=recs) mtr = 0.20 * np.ones_like(cps_subsample['e00200']) vdf = calc.dataframe(['s006', 'e00200', 'c00100']) vdf['mtr1'] = mtr vdf['mtr2'] = mtr gdata = mtr_graph_data(vdf, calc.current_year, mtr_measure='ptax', alt_e00200p_text='Taxpayer Earnings', income_measure='agi', dollar_weighting=False) gplot = xtr_graph_plot(gdata) assert gplot htmlfname = temporary_filename(suffix='.html') try: write_graph_file(gplot, htmlfname, 'title') except Exception: # pylint: disable=broad-except if os.path.isfile(htmlfname): try: os.remove(htmlfname) except OSError: pass # sometimes we can't remove a generated temporary file assert 'write_graph_file()_ok' == 'no' # if try was successful, try to remove the file if os.path.isfile(htmlfname): try: os.remove(htmlfname) except OSError: pass # sometimes we can't remove a generated temporary file
def test_blowup(): pol1 = Policy() assert pol1.current_year == Policy.JSON_START_YEAR rec1 = Records(data=TAXDATA, weights=WEIGHTS) assert rec1.current_year == Records.PUF_YEAR calc1 = Calculator(policy=pol1, records=rec1, sync_years=True) assert calc1.records.current_year == Policy.JSON_START_YEAR pol2 = Policy() assert pol2.current_year == Policy.JSON_START_YEAR rec2 = Records(data=TAXDATA, weights=WEIGHTS) assert rec2.current_year == Records.PUF_YEAR rec2.set_current_year(Policy.JSON_START_YEAR) assert rec2.current_year == Policy.JSON_START_YEAR calc2 = Calculator(policy=pol2, records=rec2, sync_years=False) assert calc2.policy.current_year == Policy.JSON_START_YEAR assert calc2.records.current_year == Policy.JSON_START_YEAR
def test_diagnostic_table(cps_subsample): """ Test diagnostic_table method. """ recs = Records.cps_constructor(data=cps_subsample) calc = Calculator(policy=Policy(), records=recs) adt = calc.diagnostic_table(3) assert isinstance(adt, pd.DataFrame)
def test_make_calculator_deepcopy(cps_subsample): """ Test deepcopy of Calculator object. """ pol = Policy() rec = Records.cps_constructor(data=cps_subsample) calc1 = Calculator(policy=pol, records=rec) calc2 = copy.deepcopy(calc1) assert isinstance(calc2, Calculator)
def test_dist_table_sum_row(cps_subsample): rec = Records.cps_constructor(data=cps_subsample) calc = Calculator(policy=Policy(), records=rec) calc.calc_all() tb1 = create_distribution_table(calc.distribution_table_dataframe(), 'standard_income_bins', 'expanded_income') tb2 = create_distribution_table(calc.distribution_table_dataframe(), 'soi_agi_bins', 'expanded_income') assert np.allclose(tb1[-1:], tb2[-1:])
def test_atr_graph(cps_subsample): """ Test atr_graph method. """ recs = Records.cps_constructor(data=cps_subsample) calc = Calculator(policy=Policy(), records=recs) fig = calc.atr_graph(calc, mars=2, atr_measure='itax') assert fig fig = calc.atr_graph(calc, atr_measure='ptax') assert fig
def test_ce_aftertax_income(cps_subsample): """ Test ce_aftertax_income method. """ rec = Records.cps_constructor(data=cps_subsample) pol = Policy() calc1 = Calculator(policy=pol, records=rec) pol.implement_reform({2013: {'_SS_Earnings_c': [9e99]}}) calc2 = Calculator(policy=pol, records=rec) res = calc1.ce_aftertax_income(calc2) assert isinstance(res, dict)
def test_calculator_advance_to_year(cps_subsample): """ Test Calculator advance_to_year method. """ rec = Records.cps_constructor(data=cps_subsample) pol = Policy() calc = Calculator(policy=pol, records=rec) calc.advance_to_year(2016) assert calc.current_year == 2016 with pytest.raises(ValueError): calc.advance_to_year(2015)
def test_mtr_graph(cps_subsample): """ Test mtr_graph method. """ recs = Records.cps_constructor(data=cps_subsample) calc = Calculator(policy=Policy(), records=recs) fig = calc.mtr_graph(calc, mars=2, income_measure='wages', mtr_measure='ptax') assert fig fig = calc.mtr_graph(calc, income_measure='agi', mtr_measure='itax') assert fig
def test_privacy_of_embedded_objects(cps_subsample): """ Test privacy of objects embedded in Calculator object. """ recs = Records.cps_constructor(data=cps_subsample) calc = Calculator(policy=Policy(), records=recs) var1 = var2 = var3 = 0 # pylint: disable=protected-access with pytest.raises(AttributeError): var1 = calc.__policy.current_year with pytest.raises(AttributeError): var2 = calc.__records.s006 with pytest.raises(AttributeError): var3 = calc.__consumption.current_year assert var1 == var2 == var3
def fixture_tc_objs(request, reform_xx, puf_subsample, cps_subsample): """ Fixture for creating Tax-Calculator objects that use the PUF and use the CPS (called only twice: once for PUF and once for CPS) """ puftest = request.param p_xx = Policy() p_xx.implement_reform(reform_xx, raise_errors=False) if puftest: rec_xx = Records(data=puf_subsample) else: rec_xx = Records.cps_constructor(data=cps_subsample) c_xx = Calculator(policy=p_xx, records=rec_xx) c_xx.advance_to_year(TEST_YEAR) c_xx.calc_all() return rec_xx, c_xx, puftest
def test_difference_table(cps_subsample): """ Test difference_table method. """ cyr = 2014 pol = Policy() recs = Records.cps_constructor(data=cps_subsample) calc1 = Calculator(policy=pol, records=recs) assert calc1.current_year == cyr reform = {cyr: {'_SS_Earnings_c': [9e99]}} pol.implement_reform(reform) calc2 = Calculator(policy=pol, records=recs) assert calc2.current_year == cyr calc1.calc_all() calc2.calc_all() diff = calc1.difference_table(calc2, 'weighted_deciles', 'iitax') assert isinstance(diff, pd.DataFrame)
def test_calculator_mtr(cps_subsample): """ Test Calculator mtr method. """ rec = Records.cps_constructor(data=cps_subsample) calcx = Calculator(policy=Policy(), records=rec) calcx.calc_all() combinedx = calcx.array('combined') c00100x = calcx.array('c00100') calc = Calculator(policy=Policy(), records=rec) recs_pre_e00200p = copy.deepcopy(calc.array('e00200p')) (mtr_ptx, mtr_itx, mtr_cmb) = calc.mtr(variable_str='e00200p', zero_out_calculated_vars=True) recs_post_e00200p = calc.array('e00200p') assert np.allclose(recs_post_e00200p, recs_pre_e00200p) assert np.allclose(calc.array('combined'), combinedx) assert np.allclose(calc.array('c00100'), c00100x) assert np.array_equal(mtr_cmb, mtr_ptx) is False assert np.array_equal(mtr_ptx, mtr_itx) is False with pytest.raises(ValueError): calc.mtr(variable_str='bad_income_type') (_, _, mtr_combined) = calc.mtr(variable_str='e00200s', calc_all_already_called=True) assert isinstance(mtr_combined, np.ndarray) (_, _, mtr_combined) = calc.mtr(variable_str='e00650', negative_finite_diff=True, calc_all_already_called=True) assert isinstance(mtr_combined, np.ndarray) (_, _, mtr_combined) = calc.mtr(variable_str='e00900p', calc_all_already_called=True) assert isinstance(mtr_combined, np.ndarray) (_, _, mtr_combined) = calc.mtr(variable_str='e01700', calc_all_already_called=True) assert isinstance(mtr_combined, np.ndarray) (_, _, mtr_combined) = calc.mtr(variable_str='e26270', calc_all_already_called=True) assert isinstance(mtr_combined, np.ndarray) (_, _, mtr_combined) = calc.mtr(variable_str='e00200p', calc_all_already_called=True) assert np.allclose(mtr_combined, mtr_cmb) assert np.allclose(calc.array('combined'), combinedx) assert np.allclose(calc.array('c00100'), c00100x)
def test_xtr_graph_plot(cps_subsample): recs = Records.cps_constructor(data=cps_subsample) calc = Calculator(policy=Policy(), records=recs) mtr = 0.20 * np.ones_like(cps_subsample['e00200']) vdf = calc.dataframe(['s006', 'MARS', 'c00100']) vdf['mtr1'] = mtr vdf['mtr2'] = mtr gdata = mtr_graph_data(vdf, calc.current_year, mtr_measure='ptax', income_measure='agi', dollar_weighting=False) gplot = xtr_graph_plot(gdata) assert gplot vdf = calc.dataframe(['s006', 'expanded_income']) vdf['mtr1'] = mtr vdf['mtr2'] = mtr gdata = mtr_graph_data(vdf, calc.current_year, mtr_measure='itax', alt_e00200p_text='Taxpayer Earnings', income_measure='expanded_income', dollar_weighting=False) assert isinstance(gdata, dict)
def test_myr_diag_table_w_behv(cps_subsample): pol = Policy() rec = Records.cps_constructor(data=cps_subsample) year = rec.current_year beh = Behavior() calc = Calculator(policy=pol, records=rec, behavior=beh) assert calc.current_year == year reform = {year: {'_II_rt7': [0.33], '_PT_rt7': [0.33]}} pol.implement_reform(reform) reform_behav = {year: {'_BE_sub': [0.4], '_BE_cg': [-3.67]}} beh.update_behavior(reform_behav) calc_clp = calc.current_law_version() calc_beh = Behavior.response(calc_clp, calc) calc_beh.calc_all() liabilities_x = (calc_beh.records.combined * calc_beh.records.s006).sum() adt = multiyear_diagnostic_table(calc_beh, 1) # extract combined liabilities as a float and # adopt units of the raw calculator data in liabilities_x liabilities_y = adt.iloc[19].tolist()[0] * 1e9 assert np.allclose(liabilities_x, liabilities_y, atol=0.01, rtol=0.0)
def test_Calculator_results_consistency(pit_fullsample, cit_crosssample): # generate calculated-variable dataframe for full sample in second year recs = Records(data=pit_fullsample) crecs = CorpRecords(data=cit_crosssample) calc = Calculator(policy=Policy(), records=recs, corprecords=crecs) assert isinstance(calc, Calculator) assert calc.current_year == Policy.JSON_START_YEAR calc.advance_to_year(Policy.JSON_START_YEAR + 1) assert calc.current_year == Policy.JSON_START_YEAR + 1 calc.calc_all() varlist = list(Records.CALCULATED_VARS) vdf = calc.dataframe(varlist) assert isinstance(vdf, pd.DataFrame) # check consistency of calculated results individual by individual assert np.allclose(vdf['TTI'], vdf['GTI'] - vdf['deductions']) assert np.allclose(vdf['Aggregate_Income'], np.maximum(0., vdf['TTI'] - vdf['TI_special_rates'])) assert np.all(vdf['Tax_ST_CG_RATE1'] >= 0.) assert np.all(vdf['Tax_ST_CG_RATE2'] >= 0.) assert np.all(vdf['Tax_ST_CG_APPRATE'] == 0.) assert np.allclose(vdf['Total_Tax_STCG'], (vdf['Tax_ST_CG_RATE1'] + vdf['Tax_ST_CG_RATE2'] + vdf['Tax_ST_CG_APPRATE'])) assert np.all(vdf['Tax_LT_CG_RATE1'] >= 0.) assert np.all(vdf['Tax_LT_CG_RATE2'] >= 0.) assert np.allclose(vdf['Total_Tax_LTCG'], vdf['Tax_LT_CG_RATE1'] + vdf['Tax_LT_CG_RATE2']) assert np.allclose(vdf['Total_Tax_Cap_Gains'], vdf['Total_Tax_STCG'] + vdf['Total_Tax_LTCG']) assert np.all(vdf['tax_Aggregate_Income'] >= 0.) assert np.all(vdf['tax_TI_special_rates'] >= 0.) assert np.all(vdf['rebate_agri'] >= 0.) exp = vdf['tax_Aggregate_Income'] + vdf['tax_TI_special_rates'] exp -= vdf['rebate_agri'] assert np.allclose(vdf['tax_TTI'], exp) assert np.all(vdf['rebate'] >= 0.) assert np.all(vdf['surcharge'] >= 0.) assert np.all(vdf['cess'] >= 0.) assert np.all(vdf['pitax'] >= 0.) exp = vdf['tax_TTI'] - vdf['rebate'] + vdf['surcharge'] + vdf['cess'] assert np.allclose(vdf['pitax'], exp)
def test_make_calculator_increment_years_first(cps_subsample): """ Test Calculator inflation indexing of policy parameters. """ # pylint: disable=too-many-locals # create Policy object with policy reform pol = Policy() std5 = 2000 reform = { 'STD_Aged': { 2015: [std5, std5, std5, std5, std5] }, 'II_em': { 2015: 5000, 2016: 6000 }, 'II_em-indexed': { 2016: False } } pol.implement_reform(reform) # create Calculator object with Policy object as modified by reform rec = Records.cps_constructor(data=cps_subsample) calc = Calculator(policy=pol, records=rec) # compare expected policy parameter values with those embedded in calc irates = pol.inflation_rates() syr = Policy.JSON_START_YEAR irate2015 = irates[2015 - syr] irate2016 = irates[2016 - syr] std6 = std5 * (1.0 + irate2015) std7 = std6 * (1.0 + irate2016) exp_STD_Aged = np.array([[1500, 1200, 1200, 1500, 1500], [1550, 1200, 1200, 1550, 1550], [std5, std5, std5, std5, std5], [std6, std6, std6, std6, std6], [std7, std7, std7, std7, std7]]) act_STD_Aged = calc.policy_param('_STD_Aged') assert np.allclose(act_STD_Aged[:5], exp_STD_Aged) exp_II_em = np.array([3900, 3950, 5000, 6000, 6000]) act_II_em = calc.policy_param('_II_em') assert np.allclose(act_II_em[:5], exp_II_em)
def test_ce_aftertax_income(cps_subsample): # test certainty_equivalent() function with con>cmin con = 5000 cmin = 1000 assert con == round(certainty_equivalent(con, 0, cmin), 6) assert con > round(certainty_equivalent((math.log(con) - 0.1), 1, cmin), 6) # test certainty_equivalent() function with con<cmin con = 500 cmin = 1000 assert con == round(certainty_equivalent(con, 0, cmin), 6) # test with require_no_agg_tax_change equal to False rec = Records.cps_constructor(data=cps_subsample) cyr = 2020 # specify calc1 and calc_all() for cyr pol = Policy() calc1 = Calculator(policy=pol, records=rec) calc1.advance_to_year(cyr) calc1.calc_all() # specify calc2 and calc_all() for cyr reform = {2019: {'_II_em': [1000]}} pol.implement_reform(reform) calc2 = Calculator(policy=pol, records=rec) calc2.advance_to_year(cyr) calc2.calc_all() df1 = calc1.dataframe(['s006', 'combined', 'expanded_income']) df2 = calc2.dataframe(['s006', 'combined', 'expanded_income']) cedict = ce_aftertax_expanded_income(df1, df2, require_no_agg_tax_change=False) assert isinstance(cedict, dict) np.allclose(cedict['ceeu1'], [55641, 27167, 5726, 2229, 1565], atol=0.5, rtol=0.0) np.allclose(cedict['ceeu2'], [54629, 26698, 5710, 2229, 1565], atol=0.5, rtol=0.0) # test with require_no_agg_tax_change equal to True with pytest.raises(ValueError): ce_aftertax_expanded_income(df1, df2, require_no_agg_tax_change=True) # test with require_no_agg_tax_change equal to False and custom_params params = {'crra_list': [0, 2], 'cmin_value': 2000} with pytest.raises(ValueError): ce_aftertax_expanded_income(df1, df2, require_no_agg_tax_change=True, custom_params=params)
def test_puf_var_stats(tests_path, puf_fullsample): """ Main logic of test. """ # create a baseline Policy object containing 2017_law.json parameters pre_tcja_jrf = os.path.join(tests_path, '..', 'reforms', '2017_law.json') pre_tcja = Calculator.read_json_param_objects(pre_tcja_jrf, None) baseline_policy = Policy() baseline_policy.implement_reform(pre_tcja['policy']) # create a Calculator object using baseline_policy and full puf.csv sample rec = Records(data=puf_fullsample) calc = Calculator(policy=baseline_policy, records=rec, verbose=False) # create base tables table_mean = create_base_table(tests_path) table_corr = copy.deepcopy(table_mean) del table_corr['description'] # add statistics to tables year_headers = ['description'] for year in range(Policy.JSON_START_YEAR, Policy.LAST_BUDGET_YEAR + 1): assert year == calc.policy_current_year() year_headers.append(str(year)) calc.calc_all() calculate_mean_stats(calc, table_mean, year) if year == 2016: calculate_corr_stats(calc, table_corr) if year < Policy.LAST_BUDGET_YEAR: calc.increment_year() # write tables to new CSV files mean_path = os.path.join(tests_path, MEAN_FILENAME + '-new') table_mean.sort_index(inplace=True) table_mean.to_csv(mean_path, header=year_headers, float_format='%8.0f') corr_path = os.path.join(tests_path, CORR_FILENAME + '-new') table_corr.sort_index(inplace=True) table_corr.to_csv(corr_path, float_format='%8.2f', columns=table_corr.index) # compare new and old CSV files for nonsmall differences mean_msg = differences(mean_path, mean_path[:-4], 'MEAN') corr_msg = differences(corr_path, corr_path[:-4], 'CORR') if mean_msg or corr_msg: raise ValueError(mean_msg + corr_msg)
def test_agg(): """ Test Tax-Calculator aggregate taxes with no policy reform using puf.csv """ # create a Policy object (clp) containing current-law policy parameters clp = Policy() # create a Records object (puf) containing puf.csv input records puf = Records(data=PUFCSV_PATH) # create a Calculator object using clp policy and puf records calc = Calculator(policy=clp, records=puf) # create aggregate diagnostic table (adt) as a Pandas DataFrame object adt = calc.diagnostic_table(num_years=10) # convert adt results to a string with a trailing EOL character adtstr = adt.to_string() + '\n' # generate differences between actual and expected results actual = adtstr.splitlines(True) with open(AGGRES_PATH, 'r') as expected_file: txt = expected_file.read() expected_results = txt.rstrip('\n\t ') + '\n' # cleanup end of file txt expected = expected_results.splitlines(True) diff = difflib.unified_diff(expected, actual, fromfile='expected', tofile='actual', n=0) # convert diff generator into a list of lines: diff_lines = list() for line in diff: diff_lines.append(line) # test failure if there are any diff_lines if len(diff_lines) > 0: new_filename = '{}{}'.format(AGGRES_PATH[:-10], 'actual.txt') with open(new_filename, 'w') as new_file: new_file.write(adtstr) sys.stdout.write('*************************************************\n') sys.stdout.write('*** NEW RESULTS IN pufcsv_agg_actual.txt FILE ***\n') sys.stdout.write('*** if new OK, copy pufcsv_agg_actual.txt to ***\n') sys.stdout.write('*** pufcsv_agg_expect.txt ***\n') sys.stdout.write('*** and rerun test. ***\n') sys.stdout.write('*************************************************\n') assert False
def test_ce_aftertax_income(cps_subsample): # test certainty_equivalent() function with con>cmin con = 5000 cmin = 1000 assert con == round(certainty_equivalent(con, 0, cmin), 6) assert con > round(certainty_equivalent((math.log(con) - 0.1), 1, cmin), 6) # test certainty_equivalent() function with con<cmin con = 500 cmin = 1000 assert con == round(certainty_equivalent(con, 0, cmin), 6) # test with require_no_agg_tax_change equal to False rec = Records.cps_constructor(data=cps_subsample) cyr = 2020 # specify calc1 and calc_all() for cyr pol = Policy() calc1 = Calculator(policy=pol, records=rec) calc1.advance_to_year(cyr) calc1.calc_all() # specify calc2 and calc_all() for cyr reform = {'II_em': {2019: 1000}} pol.implement_reform(reform) calc2 = Calculator(policy=pol, records=rec) calc2.advance_to_year(cyr) calc2.calc_all() df1 = calc1.dataframe(['s006', 'combined', 'expanded_income']) df2 = calc2.dataframe(['s006', 'combined', 'expanded_income']) cedict = ce_aftertax_expanded_income(df1, df2, require_no_agg_tax_change=False) assert isinstance(cedict, dict) np.allclose(cedict['ceeu1'], [55641, 27167, 5726, 2229, 1565], atol=0.5, rtol=0.0) np.allclose(cedict['ceeu2'], [54629, 26698, 5710, 2229, 1565], atol=0.5, rtol=0.0) # test with require_no_agg_tax_change equal to True with pytest.raises(ValueError): ce_aftertax_expanded_income(df1, df2, require_no_agg_tax_change=True) # test with require_no_agg_tax_change equal to False and custom_params params = {'crra_list': [0, 2], 'cmin_value': 2000} with pytest.raises(ValueError): ce_aftertax_expanded_income(df1, df2, require_no_agg_tax_change=True, custom_params=params)
def test_make_calculator(cps_subsample): pol = Policy(start_year=2014, num_years=9) assert pol.current_year == 2014 rec = Records.cps_constructor(data=cps_subsample) consump = Consumption() consump.update_consumption({2014: {'_MPC_e20400': [0.05]}}) assert consump.current_year == 2013 calc = Calculator(policy=pol, records=rec, consumption=consump, behavior=Behavior()) assert calc.current_year == 2014 # test incorrect Calculator instantiation: with pytest.raises(ValueError): Calculator(policy=None, records=rec) with pytest.raises(ValueError): Calculator(policy=pol, records=None) with pytest.raises(ValueError): Calculator(policy=pol, records=rec, behavior=list()) with pytest.raises(ValueError): Calculator(policy=pol, records=rec, consumption=list())
def test_xtr_graph_plot(cps_subsample): calc = Calculator(policy=Policy(), records=Records.cps_constructor(data=cps_subsample), behavior=Behavior()) mtr = 0.20 * np.ones_like(cps_subsample['e00200']) vdf = calc.dataframe(['s006', 'MARS', 'c00100']) vdf['mtr1'] = mtr vdf['mtr2'] = mtr gdata = mtr_graph_data(vdf, calc.current_year, mtr_measure='ptax', income_measure='agi', dollar_weighting=False) gplot = xtr_graph_plot(gdata) assert gplot vdf = calc.dataframe(['s006', 'expanded_income']) vdf['mtr1'] = mtr vdf['mtr2'] = mtr gdata = mtr_graph_data(vdf, calc.current_year, mtr_measure='itax', alt_e00200p_text='Taxpayer Earnings', income_measure='expanded_income', dollar_weighting=False) assert isinstance(gdata, dict)
def test_make_calculator(cps_subsample): start_year = Policy.JSON_START_YEAR sim_year = 2018 pol = Policy() assert pol.current_year == start_year rec = Records.cps_constructor(data=cps_subsample) consump = Consumption() consump.update_consumption({sim_year: {'_MPC_e20400': [0.05]}}) assert consump.current_year == start_year calc = Calculator(policy=pol, records=rec, consumption=consump, behavior=Behavior()) assert calc.current_year == Records.CPSCSV_YEAR # test incorrect Calculator instantiation: with pytest.raises(ValueError): Calculator(policy=None, records=rec) with pytest.raises(ValueError): Calculator(policy=pol, records=None) with pytest.raises(ValueError): Calculator(policy=pol, records=rec, behavior=list()) with pytest.raises(ValueError): Calculator(policy=pol, records=rec, consumption=list())
def test_dec_graph_plot(cps_subsample): pol = Policy() rec = Records.cps_constructor(data=cps_subsample) calc1 = Calculator(policy=pol, records=rec) year = 2020 calc1.advance_to_year(year) reform = { year: { '_SS_Earnings_c': [9e99], # OASDI FICA tax on all earnings '_FICA_ss_trt': [0.107484] # lower rate to keep revenue unchanged } } pol.implement_reform(reform) calc2 = Calculator(policy=pol, records=rec) calc2.advance_to_year(year) assert calc1.current_year == calc2.current_year calc1.calc_all() calc2.calc_all() fig = calc1.decile_graph(calc2) assert fig
def test_make_calculator(cps_subsample): syr = 2014 pol = Policy(start_year=syr, num_years=9) assert pol.current_year == syr rec = Records.cps_constructor(data=cps_subsample, no_benefits=True) consump = Consumption() consump.update_consumption({syr: {'_MPC_e20400': [0.05]}}) assert consump.current_year == Consumption.JSON_START_YEAR calc = Calculator(policy=pol, records=rec, consumption=consump, behavior=Behavior()) assert calc.current_year == syr assert calc.records_current_year() == syr # test incorrect Calculator instantiation: with pytest.raises(ValueError): Calculator(policy=None, records=rec) with pytest.raises(ValueError): Calculator(policy=pol, records=None) with pytest.raises(ValueError): Calculator(policy=pol, records=rec, behavior=list()) with pytest.raises(ValueError): Calculator(policy=pol, records=rec, consumption=list())
def taxcalc_clp_results(): """ Use taxcalc package on this computer to compute aggregate income tax and payroll tax revenues for years beginning with MIN_START_YEAR and ending with MAX_START_YEAR+NUMBER_OF_YEARS-1 for current-law policy. Return two aggregate revenue dictionaries indexed by calendar year. """ calc = Calculator(policy=Policy(), records=Records(data=PUF_PATH), verbose=False) nyears = MAX_START_YEAR + NUMBER_OF_YEARS - MIN_START_YEAR - 1 adts = list() for iyr in range(-1, nyears - 1): calc.calc_all() adts.append(create_diagnostic_table(calc)) if iyr < nyears: calc.increment_year() adt = pd.concat(adts, axis=1) # note that adt is Pandas DataFrame object return (adt.xs('Ind Income Tax ($b)').to_dict(), adt.xs('Payroll Taxes ($b)').to_dict())
def test_incorrect_Records_instantiation(cps_subsample): with pytest.raises(ValueError): recs = Records(data=list()) with pytest.raises(ValueError): recs = Records(data=cps_subsample, gfactors=list()) with pytest.raises(ValueError): recs = Records(data=cps_subsample, gfactors=None, weights=list()) with pytest.raises(ValueError): recs = Records(data=cps_subsample, gfactors=None, weights=None, start_year=list()) with pytest.raises(ValueError): recs = Records(data=cps_subsample, gfactors=None, weights=None, adjust_ratios=list()) with pytest.raises(ValueError): recs = Records(data=cps_subsample, gfactors=None, weights=None, adjust_ratios=None, benefits=list())
def test_ID_HC_vs_BS(cps_subsample): """ Test that complete haircut of itemized deductions produces same results as a 100% benefit surtax with no benefit deduction. """ recs = Records.cps_constructor(data=cps_subsample) # 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_calc = Calculator(policy=hc_policy, records=recs) hc_calc.calc_all() hc_taxes = hc_calc.dataframe(['iitax', 'payrolltax']) del hc_calc # 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_calc = Calculator(policy=bs_policy, records=recs) bs_calc.calc_all() bs_taxes = bs_calc.dataframe(['iitax', 'payrolltax']) del bs_calc # compare calculated taxes generated by the two reforms assert np.allclose(hc_taxes['payrolltax'], bs_taxes['payrolltax']) assert np.allclose(hc_taxes['iitax'], bs_taxes['iitax'])
def xtest_diff_table_sum_row(pit_subsample): rec = Records(data=pit_subsample) # create a current-law Policy object and Calculator calc1 pol = Policy() calc1 = Calculator(policy=pol, records=rec) calc1.calc_all() # create a policy-reform Policy object and Calculator calc2 reform = {2017: {'_rate2': [0.06]}} pol.implement_reform(reform) calc2 = Calculator(policy=pol, records=rec) calc2.calc_all() # create two difference tables and compare their content tdiff1 = create_difference_table(calc1.dataframe(DIFF_VARIABLES), calc2.dataframe(DIFF_VARIABLES), 'standard_income_bins', 'iitax') tdiff2 = create_difference_table(calc1.dataframe(DIFF_VARIABLES), calc2.dataframe(DIFF_VARIABLES), 'soi_agi_bins', 'iitax') non_digit_cols = ['perc_inc', 'perc_cut'] digit_cols = [c for c in list(tdiff1) if c not in non_digit_cols] assert np.allclose(tdiff1[digit_cols][-1:], tdiff2[digit_cols][-1:]) np.allclose(tdiff1[non_digit_cols][-1:], tdiff2[non_digit_cols][-1:])
def test_qbid_calculation(): """ Test Calculator's QBID calculations using the six example filing units specified in Table 1 of this TPC publication: "Navigating the New Pass-Through Provisions: A Technical Explanation" by William G. Gale and Aaron Krupkin (January 31, 2018), which is available at this URL: https://www.taxpolicycenter.org/publications/ navigating-new-pass-through-provisions-technical-explanation/full """ # In constructing the TPC example filing units, assume that the taxpayer # has business income in the form of e26270/e02000 income and no earnings, # and that the spouse has no business income and only earnings. TPC_YEAR = 2018 TPC_VARS = ( 'RECID,MARS,e00200s,e00200,e26270,e02000,PT_SSTB_income,' 'PT_binc_w2_wages,PT_ubia_property,pre_qbid_taxinc,qbid\n' ) TPC_FUNITS = ( '1,2, 99000, 99000,75000,75000,1,20000,90000,150000,15000.00\n' '2,2,349000,349000,75000,75000,1,20000,90000,400000, 1612.50\n' '3,2,524000,524000,75000,75000,1,20000,90000,575000, 0.00\n' '4,2, 99000, 99000,75000,75000,0,20000,90000,150000,15000.00\n' '5,2,349000,349000,75000,75000,0,20000,90000,400000,10750.00\n' '6,2,524000,524000,75000,75000,0,20000,90000,575000,10000.00\n' ) # generate actual Calculator pre-qbid taxinc and qbid amounts tpc_df = pd.read_csv(StringIO(TPC_VARS + TPC_FUNITS)) recs = Records(data=tpc_df, start_year=TPC_YEAR, gfactors=None, weights=None) calc = Calculator(policy=Policy(), records=recs) assert calc.current_year == TPC_YEAR calc.calc_all() varlist = ['RECID', 'c00100', 'standard', 'c04470', 'qbided'] tc_df = calc.dataframe(varlist) # compare actual amounts with expected amounts from TPC publication act_taxinc = tc_df.c00100 - np.maximum(tc_df.standard, tc_df.c04470) exp_taxinc = tpc_df.pre_qbid_taxinc assert np.allclose(act_taxinc, exp_taxinc) assert np.allclose(tc_df.qbided, tpc_df.qbid)
def test_ID_RealEstate_HC_vs_CRT(cps_subsample): """ Test that a cap on all state, local, and foreign real estate tax deductions at 0 percent of AGI is equivalent to a complete haircut on the same real estate tax deductions. """ rec = Records.cps_constructor(data=cps_subsample) # specify real estate complete haircut reform policy and Calculator object hc_reform = {2013: {'_ID_RealEstate_hc': [1.0]}} hc_policy = Policy() hc_policy.implement_reform(hc_reform) hc_calc = Calculator(policy=hc_policy, records=rec) hc_calc.calc_all() # specify AGI cap reform policy and Calculator object crt_reform = {2013: {'_ID_RealEstate_crt': [0.0]}} crt_policy = Policy() crt_policy.implement_reform(crt_reform) crt_calc = Calculator(policy=crt_policy, records=rec) crt_calc.calc_all() # compare calculated tax results generated by the two reforms assert np.allclose(hc_calc.records.payrolltax, crt_calc.records.payrolltax) assert np.allclose(hc_calc.records.iitax, crt_calc.records.iitax)
def test_distribution_tables(cps_subsample): pol = Policy() recs = Records.cps_constructor(data=cps_subsample) calc1 = Calculator(policy=pol, records=recs) assert calc1.current_year == 2014 calc1.calc_all() dt1, dt2 = calc1.distribution_tables(None) assert isinstance(dt1, pd.DataFrame) assert dt2 is None dt1, dt2 = calc1.distribution_tables(calc1) assert isinstance(dt1, pd.DataFrame) assert isinstance(dt2, pd.DataFrame) reform = {2014: {'_UBI_u18': [1000], '_UBI_1820': [1000], '_UBI_21': [1000]}} pol.implement_reform(reform) assert not pol.reform_errors calc2 = Calculator(policy=pol, records=recs) calc2.calc_all() dt1, dt2 = calc1.distribution_tables(calc2) assert isinstance(dt1, pd.DataFrame) assert isinstance(dt2, pd.DataFrame)
def test_make_calculator_with_policy_reform(cps_subsample): rec = Records.cps_constructor(data=cps_subsample) year = rec.current_year # create a Policy object and apply a policy reform pol = Policy() reform = {2013: {'_II_em': [4000], '_II_em_cpi': False, '_STD_Aged': [[1600, 1300, 1300, 1600, 1600]], '_STD_Aged_cpi': False}} pol.implement_reform(reform) # create a Calculator object using this policy reform calc = Calculator(policy=pol, records=rec) # check that Policy object embedded in Calculator object is correct assert calc.current_year == year assert calc.param('II_em') == 4000 assert np.allclose(calc.param('_II_em'), np.array([4000] * Policy.DEFAULT_NUM_YEARS)) exp_STD_Aged = [[1600, 1300, 1300, 1600, 1600]] * Policy.DEFAULT_NUM_YEARS assert np.allclose(calc.param('_STD_Aged'), np.array(exp_STD_Aged)) assert np.allclose(calc.param('STD_Aged'), np.array([1600, 1300, 1300, 1600, 1600]))
def test_calculator_mtr(cps_subsample): rec = Records.cps_constructor(data=cps_subsample) calcx = Calculator(policy=Policy(), records=rec) calcx.calc_all() combinedx = calcx.array('combined') c00100x = calcx.array('c00100') calc = Calculator(policy=Policy(), records=rec) recs_pre_e00200p = copy.deepcopy(calc.array('e00200p')) (mtr_ptx, mtr_itx, mtr_cmb) = calc.mtr(variable_str='e00200p', zero_out_calculated_vars=True) recs_post_e00200p = calc.array('e00200p') assert np.allclose(recs_post_e00200p, recs_pre_e00200p) assert np.allclose(calc.array('combined'), combinedx) assert np.allclose(calc.array('c00100'), c00100x) assert np.array_equal(mtr_cmb, mtr_ptx) is False assert np.array_equal(mtr_ptx, mtr_itx) is False with pytest.raises(ValueError): calc.mtr(variable_str='bad_income_type') (_, _, mtr_combined) = calc.mtr(variable_str='e00200s', calc_all_already_called=True) assert isinstance(mtr_combined, np.ndarray) (_, _, mtr_combined) = calc.mtr(variable_str='e00650', negative_finite_diff=True, calc_all_already_called=True) assert isinstance(mtr_combined, np.ndarray) (_, _, mtr_combined) = calc.mtr(variable_str='e00900p', calc_all_already_called=True) assert isinstance(mtr_combined, np.ndarray) (_, _, mtr_combined) = calc.mtr(variable_str='e01700', calc_all_already_called=True) assert isinstance(mtr_combined, np.ndarray) (_, _, mtr_combined) = calc.mtr(variable_str='e26270', calc_all_already_called=True) assert isinstance(mtr_combined, np.ndarray) (_, _, mtr_combined) = calc.mtr(variable_str='e00200p', calc_all_already_called=True) assert np.allclose(mtr_combined, mtr_cmb) assert np.allclose(calc.array('combined'), combinedx) assert np.allclose(calc.array('c00100'), c00100x)
def test_dec_graph_plots(cps_subsample): pol = Policy() rec = Records.cps_constructor(data=cps_subsample, no_benefits=True) calc1 = Calculator(policy=pol, records=rec) year = 2020 calc1.advance_to_year(year) reform = { year: { '_SS_Earnings_c': [9e99], # OASDI FICA tax on all earnings '_FICA_ss_trt': [0.107484] # lower rate to keep revenue unchanged } } pol.implement_reform(reform) calc2 = Calculator(policy=pol, records=rec) calc2.advance_to_year(year) assert calc1.current_year == calc2.current_year calc1.calc_all() calc2.calc_all() fig = calc1.decile_graph(calc2) assert fig dt1, dt2 = calc1.distribution_tables(calc2, 'weighted_deciles') dta = dec_graph_data(dt1, dt2, year, include_zero_incomes=True, include_negative_incomes=False) assert isinstance(dta, dict) dta = dec_graph_data(dt1, dt2, year, include_zero_incomes=False, include_negative_incomes=True) assert isinstance(dta, dict) dta = dec_graph_data(dt1, dt2, year, include_zero_incomes=False, include_negative_incomes=False) assert isinstance(dta, dict)
def test_make_Calculator_with_multiyear_reform(): # create a Policy object and apply a policy reform policy3 = Policy() reform3 = {2015: {}} reform3[2015]['_STD_Aged'] = [[1600, 1300, 1600, 1300, 1600, 1300]] reform3[2015]['_II_em'] = [5000, 6000] # reform values for 2015 and 2016 reform3[2015]['_II_em_cpi'] = False policy3.implement_reform(reform3) # create a Calculator object using this policy-reform puf = Records(data=TAXDATA, weights=WEIGHTS, start_year=2009) calc3 = Calculator(policy=policy3, records=puf) # check that Policy object embedded in Calculator object is correct assert calc3.current_year == 2013 assert calc3.policy.II_em == 3900 assert calc3.policy.num_years == Policy.DEFAULT_NUM_YEARS exp_II_em = [3900, 3950, 5000] + [6000] * (Policy.DEFAULT_NUM_YEARS - 3) assert_array_equal(calc3.policy._II_em, np.array(exp_II_em)) calc3.increment_year() calc3.increment_year() assert calc3.current_year == 2015 assert_array_equal(calc3.policy.STD_Aged, np.array([1600, 1300, 1600, 1300, 1600, 1300]))
def main(): parser = argparse.ArgumentParser( prog="python stats_summary.py", description=('Generates a files for either statistics summary' 'on a 10-year span or correlation matrix of current' 'tax year. Adding either sum-stats or correlation' 'as an argument after python Stats_Summary.py --output')) parser.add_argument('--output', default='sum-stats') args = parser.parse_args() # create a calculator tax_dta1 = pd.read_csv(PUF_PATH) records1 = Records(tax_dta1) policy1 = Policy(start_year=2013) calc1 = Calculator(records=records1, policy=policy1) table = creat_table_base() if args.output == 'sum-stats': gen_sum_stats(table, calc=calc1) elif args.output == 'correlation': gen_correlation(table, calc=calc1) else: print("no such output available") return 0
def test_atr_graph_data(cps_subsample): pol = Policy() rec = Records.cps_constructor(data=cps_subsample, no_benefits=True) calc = Calculator(policy=pol, records=rec) year = calc.current_year with pytest.raises(ValueError): atr_graph_data(None, year, mars='bad') with pytest.raises(ValueError): atr_graph_data(None, year, mars=0) with pytest.raises(ValueError): atr_graph_data(None, year, mars=list()) with pytest.raises(ValueError): atr_graph_data(None, year, atr_measure='badtax') calc.calc_all() vdf = calc.dataframe(['s006', 'MARS', 'expanded_income']) tax = 0.20 * np.ones_like(vdf['expanded_income']) vdf['tax1'] = tax vdf['tax2'] = tax gdata = atr_graph_data(vdf, year, mars=1, atr_measure='combined') gdata = atr_graph_data(vdf, year, atr_measure='itax') gdata = atr_graph_data(vdf, year, atr_measure='ptax') assert isinstance(gdata, dict)
def test_ID_StateLocal_HC_vs_CRT(cps_subsample): """ Test that a cap on state/local income and sales tax deductions at 0 percent of AGI is equivalent to a complete haircut on the same state/local tax deductions. """ rec = Records.cps_constructor(data=cps_subsample) # specify state/local complete haircut reform policy and Calculator object hc_policy = Policy() hc_reform = {'ID_StateLocalTax_hc': {2013: 1.0}} hc_policy.implement_reform(hc_reform) hc_calc = Calculator(policy=hc_policy, records=rec) hc_calc.calc_all() # specify AGI cap reform policy and Calculator object crt_policy = Policy() crt_reform = {'ID_StateLocalTax_crt': {2013: 0.0}} crt_policy.implement_reform(crt_reform) crt_calc = Calculator(policy=crt_policy, records=rec) crt_calc.calc_all() # compare calculated tax results generated by the two reforms assert np.allclose(hc_calc.array('payrolltax'), crt_calc.array('payrolltax')) assert np.allclose(hc_calc.array('iitax'), crt_calc.array('iitax'))
def test_dec_graph_plot(cps_subsample): pol = Policy() rec = Records.cps_constructor(data=cps_subsample) calc1 = Calculator(policy=pol, records=rec) year = 2020 reform = { year: { '_SS_Earnings_c': [9e99], # OASDI FICA tax on all earnings '_FICA_ss_trt': [0.107484] # lower rate to keep revenue unchanged } } pol.implement_reform(reform) calc2 = Calculator(policy=pol, records=rec) calc1.advance_to_year(year) with pytest.raises(ValueError): dec_graph_data(calc1, calc2) calc2.advance_to_year(year) gdata = dec_graph_data(calc1, calc2) assert isinstance(gdata, dict) deciles = gdata['bars'].keys() assert len(deciles) == 14 gplot = dec_graph_plot(gdata, xlabel='', ylabel='') assert gplot
def test_Calculator_create_distribution_table(): policy = Policy() puf = Records(data=TAXDATA, weights=WEIGHTS, start_year=2009) calc = Calculator(policy=policy, records=puf) calc.calc_all() dist_labels = [ 'Returns', 'AGI', 'Standard Deduction Filers', 'Standard Deduction', 'Itemizers', 'Itemized Deduction', 'Personal Exemption', 'Taxable Income', 'Regular Tax', 'AMTI', 'AMT Filers', 'AMT', 'Tax before Credits', 'Non-refundable Credits', 'Tax before Refundable Credits', 'Refundable Credits', 'Individual Income Tax Liabilities', 'Payroll Tax Liablities', 'Combined Payroll and Individual Income Tax Liabilities' ] dt1 = create_distribution_table(calc, groupby="weighted_deciles", result_type="weighted_sum") dt1.columns = dist_labels dt2 = create_distribution_table(calc, groupby="small_income_bins", result_type="weighted_avg") assert isinstance(dt1, pd.DataFrame) assert isinstance(dt2, pd.DataFrame)
def test_make_calculator_with_multiyear_reform(cps_subsample): rec = Records.cps_constructor(data=cps_subsample) year = rec.current_year # create a Policy object and apply a policy reform pol = Policy() reform = {2015: {}, 2016: {}} reform[2015]['_II_em'] = [5000, 6000] # reform values for 2015 and 2016 reform[2015]['_II_em_cpi'] = False reform[2016]['_STD_Aged'] = [[1600, 1300, 1600, 1300, 1600]] pol.implement_reform(reform) # create a Calculator object using this policy-reform calc = Calculator(policy=pol, records=rec) # check that Policy object embedded in Calculator object is correct assert calc.current_year == year assert calc.policy.II_em == 3950 assert calc.policy.num_years == Policy.DEFAULT_NUM_YEARS exp_II_em = [3900, 3950, 5000] + [6000] * (Policy.DEFAULT_NUM_YEARS - 3) assert np.allclose(calc.policy._II_em, np.array(exp_II_em)) calc.increment_year() calc.increment_year() assert calc.current_year == 2016 assert np.allclose(calc.policy.STD_Aged, np.array([1600, 1300, 1600, 1300, 1600]))
def test_make_calculator(cps_subsample): """ Test Calculator class ctor. """ start_year = Policy.JSON_START_YEAR sim_year = 2018 pol = Policy() assert pol.current_year == start_year rec = Records.cps_constructor(data=cps_subsample) consump = Consumption() consump.update_consumption({'MPC_e20400': {sim_year: 0.05}}) assert consump.current_year == start_year calc = Calculator(policy=pol, records=rec, consumption=consump, verbose=True) assert calc.data_year == Records.CPSCSV_YEAR assert calc.current_year == Records.CPSCSV_YEAR # test incorrect Calculator instantiation: with pytest.raises(ValueError): Calculator(policy=None, records=rec) with pytest.raises(ValueError): Calculator(policy=pol, records=None) with pytest.raises(ValueError): Calculator(policy=pol, records=rec, consumption=list())
def test_puf_var_stats(tests_path, puf_fullsample): """ Main logic of test. """ # create a Calculator object rec = Records(data=puf_fullsample) calc = Calculator(policy=Policy(), records=rec, verbose=False) # create base tables table_mean = create_base_table(tests_path) table_corr = copy.deepcopy(table_mean) del table_corr['description'] # add statistics to tables year_headers = ['description'] for year in range(Policy.JSON_START_YEAR, Policy.LAST_BUDGET_YEAR + 1): assert year == calc.policy.current_year year_headers.append(str(year)) calc.calc_all() calculate_mean_stats(calc, table_mean, year) if year == 2016: calculate_corr_stats(calc, table_corr) if year < Policy.LAST_BUDGET_YEAR: calc.increment_year() # write tables to new CSV files mean_path = os.path.join(tests_path, MEAN_FILENAME + '-new') table_mean.sort_index(inplace=True) table_mean.to_csv(mean_path, header=year_headers, float_format='%8.0f') corr_path = os.path.join(tests_path, CORR_FILENAME + '-new') table_corr.sort_index(inplace=True) table_corr.to_csv(corr_path, float_format='%8.2f', columns=table_corr.index) # compare new and old CSV files for differences no larger than small value mean_msg = differences(mean_path, mean_path[:-4], 'MEAN', small=1.000001) corr_msg = differences(corr_path, corr_path[:-4], 'CORR', small=0.010001) if mean_msg or corr_msg: raise ValueError(mean_msg + corr_msg)