def taxcalc_results(start_year, reform_dict, itax_clp, ptax_clp): """ Use taxcalc package on this computer to compute aggregate income tax and payroll tax revenue difference (between reform and current-law policy) for ten years beginning with the specified start_year using the specified reform_dict dictionary and the two specified current-law-policy results dictionaries. Return two aggregate tax revenue difference dictionaries indexed by calendar year. """ pol = Policy() pol.implement_reform(reform_dict) calc = Calculator(policy=pol, records=Records(data=PUF_PATH), verbose=False) calc.advance_to_year(start_year) nyears = NUMBER_OF_YEARS 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 itax_ref = adt.xs('Ind Income Tax ($b)').to_dict() ptax_ref = adt.xs('Payroll Taxes ($b)').to_dict() itax_diff = {} ptax_diff = {} for year in itax_ref: itax_diff[year] = round(itax_ref[year] - itax_clp[year], 1) ptax_diff[year] = round(ptax_ref[year] - ptax_clp[year], 1) return (itax_diff, ptax_diff)
def test_qbid_limit_switch(): """ Test Calculator's switch to implement wage/capital limitations on QBI deduction. """ cy = 2019 ref = {"PT_qbid_limit_switch": {2019: False}} # filing unit has $500,000 in wages and $100,000 in QBI. Since # the household is above the taxable income limitation threshold, # with full wage/capital limitations, it does not receive a QBI # deduction. With sufficent wage/capital to avoid the limitation, # the filing unit receives a deduction of: # $100,000 * 20% = $20,000. VARS = 'RECID,MARS,e00200s,e00200p,e00200,e26270,e02000\n' FUNIT = '1,2,250000,250000,500000,100000,100000' funit_df = pd.read_csv(StringIO(VARS + FUNIT)) recs = Records(data=funit_df, start_year=cy, gfactors=None, weights=None) calc_base = Calculator(policy=Policy(), records=recs) calc_base.calc_all() qbid_base = calc_base.array('qbided') assert np.equal(qbid_base, 0) pol_ref = Policy() pol_ref.implement_reform(ref) calc_ref = Calculator(policy=pol_ref, records=recs) calc_ref.calc_all() qbid_ref = calc_ref.array('qbided') assert np.equal(qbid_ref, 20000)
def run_reform(name, reform, behave): puf = pd.read_csv("../tax-calculator/puf.csv") policy_base = Policy(start_year=2013) records_base = Records(puf) policy_reform = Policy() records_reform = Records(puf) bhv = Behavior() calcbase = Calculator(policy=policy_base, records=records_base) calcreform = Calculator(policy=policy_reform, records=records_reform, behavior=bhv) policy_reform.implement_reform(reform) calcbase.advance_to_year(CURRENT_YEAR) calcreform.advance_to_year(CURRENT_YEAR) calcbase.calc_all() calcreform.calc_all() bhv.update_behavior(behave) calc_behav = Behavior.response(calcbase, calcreform) calc_behav.calc_all() base_list = multiyear_diagnostic_table(calcbase, 10) reform_list = multiyear_diagnostic_table(calc_behav, 10) difflist = (reform_list.iloc[18] - base_list.iloc[18]) return difflist
def run_reform(name, reform, epsilon): puf = pd.read_csv("./puf.csv") policy_base = Policy(start_year=2013) records_base = Records(puf) policy_reform = Policy() records_reform = Records(puf) calcbase = Calculator(policy=policy_base, records=records_base) calcreform = Calculator(policy=policy_reform, records=records_reform) policy_reform.implement_reform(reform) calcbase.advance_to_year(CURRENT_YEAR) calcreform.advance_to_year(CURRENT_YEAR) calcbase.calc_all() calcreform.calc_all() diff_df = get_diff(calcbase, calcreform, name) data_df = print_data(calcbase, calcreform, weights=weighted, tab='c00100', name=name) equiv_tax_cut = reform_equiv(reform, epsilon) total_rev_raise = agg_diff(calcbase, calcreform) delta_num_filers, delta_percent_filers = agg_num_delta( calcbase, calcreform) #diff_df['equiv_rate_cut'] = len(diff_df)*[equiv_tax_cut] return (diff_df, data_df, equiv_tax_cut, total_rev_raise, delta_num_filers, delta_percent_filers)
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 = { 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) 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 diff_in_revenue(reform_on_II, orig_reform): policy_func = Policy() puf = pd.read_csv("./puf.csv") records_func = Records(puf) calc_func = Calculator(policy = policy_func, records = records_func) policy_bench = Policy() records_bench = Records(puf) calc_bench = Calculator(policy = policy_bench, records = records_bench) reform = { CURRENT_YEAR:{ "_II_rt1":[max(policy_bench._II_rt1[0] *(1 - reform_on_II),0.0)], "_II_rt2":[max(policy_bench._II_rt2[0] *(1 - reform_on_II),0.0)], "_II_rt3":[max(policy_bench._II_rt3[0] *(1 - reform_on_II),0.0)], "_II_rt4":[max(policy_bench._II_rt4[0] *(1 - reform_on_II),0.0)], "_II_rt5":[max(policy_bench._II_rt5[0] *(1 - reform_on_II),0.0)], "_II_rt6":[max(policy_bench._II_rt6[0] *(1 - reform_on_II),0.0)], "_II_rt7":[max(policy_bench._II_rt7[0] *(1 - reform_on_II),0.0)]} } policy_func.implement_reform(reform) policy_func.implement_reform(orig_reform) calc_func.advance_to_year(CURRENT_YEAR) calc_bench.advance_to_year(CURRENT_YEAR) calc_func.calc_all() calc_bench.calc_all() ans = ((calc_bench.records._combined*calc_bench.records.s006).sum()-(calc_func.records._combined*calc_func.records.s006).sum()) print("diff in revenue is ", ans) return ans
def test_ID_HC_vs_BS(puf_1991, weights_1991): """ 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=puf_1991, weights=weights_1991, 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=puf_1991, weights=weights_1991, 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 np.allclose(hc_calc.records._payrolltax, bs_calc.records._payrolltax) assert np.allclose(hc_calc.records._iitax, bs_calc.records._iitax)
def test_calc_all_benefits_amounts(cps_subsample): ''' Testing how benefits are handled in the calc_all method ''' # set a reform with a positive UBI amount ubi_ref = {'UBI_21': {2020: 1000}} # create baseline calculator pol = Policy() recs = Records.cps_constructor(data=cps_subsample) calc_base = Calculator(pol, recs) calc_base.advance_to_year(2020) calc_base.calc_all() # create reform calculator pol_ubi = Policy() pol_ubi.implement_reform(ubi_ref) calc_ubi = Calculator(pol_ubi, recs) calc_ubi.advance_to_year(2020) calc_ubi.calc_all() # check that differences in benefits totals are equal to diffs in # UBI ubi_diff = (calc_ubi.weighted_total('ubi') - calc_base.weighted_total('ubi')) / 1e9 benefit_cost_diff = (calc_ubi.weighted_total('benefit_cost_total') - calc_base.weighted_total('benefit_cost_total')) / 1e9 benefit_value_diff = (calc_ubi.weighted_total('benefit_cost_total') - calc_base.weighted_total('benefit_cost_total')) / 1e9 assert np.allclose(ubi_diff, benefit_cost_diff) assert np.allclose(ubi_diff, benefit_value_diff)
def test_diff_table_sum_row(cps_subsample): rec = Records.cps_constructor(data=cps_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 = {2013: {'_II_rt4': [0.56]}} 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.records, calc2.records, groupby='small_income_bins', income_measure='expanded_income', tax_to_diff='iitax') tdiff2 = create_difference_table(calc1.records, calc2.records, groupby='large_income_bins', income_measure='expanded_income', tax_to_diff='iitax') non_digit_cols = [ 'mean', 'perc_inc', 'perc_cut', 'share_of_change', 'perc_aftertax', 'pc_aftertaxinc' ] 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.testing.assert_array_equal(tdiff1[non_digit_cols][-1:], tdiff2[non_digit_cols][-1:])
def test_dist_table_sum_row(cps_subsample): rec = Records.cps_constructor(data=cps_subsample) calc = Calculator(policy=Policy(), records=rec) calc.calc_all() # create three distribution tables and compare the ALL row contents tb1, _ = calc.distribution_tables(None, 'standard_income_bins') tb2, _ = calc.distribution_tables(None, 'soi_agi_bins') tb3, _ = calc.distribution_tables(None, 'weighted_deciles') tb4, _ = calc.distribution_tables(None, 'weighted_deciles', pop_quantiles=True) assert np.allclose(tb1.loc['ALL'], tb2.loc['ALL']) assert np.allclose(tb1.loc['ALL'], tb3.loc['ALL']) # make sure population count is larger than filing-unit count assert tb4.at['ALL', 'count'] > tb1.at['ALL', 'count'] # make sure population table has same ALL row values as filing-unit table for col in ['count', 'count_StandardDed', 'count_ItemDed', 'count_AMT']: tb4.at['ALL', col] = tb1.at['ALL', col] assert np.allclose(tb1.loc['ALL'], tb4.loc['ALL']) # make sure population table has same ALL tax liabilities as diagnostic tbl dgt = calc.diagnostic_table(1) assert np.allclose([tb4.at['ALL', 'iitax'], tb4.at['ALL', 'payrolltax']], [ dgt.at['Ind Income Tax ($b)', calc.current_year], dgt.at['Payroll Taxes ($b)', calc.current_year] ])
def test_diff_table_sum_row(cps_subsample): rec = Records.cps_constructor(data=cps_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 = {'II_rt4': {2013: 0.56}} pol.implement_reform(reform) calc2 = Calculator(policy=pol, records=rec) calc2.calc_all() # create three difference tables and compare their content dv1 = calc1.dataframe(DIFF_VARIABLES) dv2 = calc2.dataframe(DIFF_VARIABLES) dt1 = create_difference_table(dv1, dv2, 'standard_income_bins', 'iitax') dt2 = create_difference_table(dv1, dv2, 'soi_agi_bins', 'iitax') dt3 = create_difference_table(dv1, dv2, 'weighted_deciles', 'iitax', pop_quantiles=False) dt4 = create_difference_table(dv1, dv2, 'weighted_deciles', 'iitax', pop_quantiles=True) assert np.allclose(dt1.loc['ALL'], dt2.loc['ALL']) assert np.allclose(dt1.loc['ALL'], dt3.loc['ALL']) # make sure population count is larger than filing-unit count assert dt4.at['ALL', 'count'] > dt1.at['ALL', 'count']
def test_diff_table_sum_row(puf_1991, weights_1991): # create a current-law Policy object and Calculator calc1 policy1 = Policy() records1 = Records(data=puf_1991, weights=weights_1991, start_year=2009) calc1 = Calculator(policy=policy1, records=records1) calc1.calc_all() # create a policy-reform Policy object and Calculator calc2 reform = {2013: {'_II_rt4': [0.56]}} policy2 = Policy() policy2.implement_reform(reform) records2 = Records(data=puf_1991, weights=weights_1991, start_year=2009) calc2 = Calculator(policy=policy2, records=records2) calc2.calc_all() # create two difference tables and compare their content tdiff1 = create_difference_table(calc1.records, calc2.records, groupby='small_income_bins') tdiff2 = create_difference_table(calc1.records, calc2.records, groupby='large_income_bins') non_digit_cols = ['mean', 'perc_inc', 'perc_cut', 'share_of_change'] digit_cols = [ x for x in tdiff1.columns.tolist() if x not in non_digit_cols ] npt.assert_allclose(tdiff1[digit_cols][-1:], tdiff2[digit_cols][-1:]) assert np.array_equal(tdiff1[non_digit_cols][-1:], tdiff2[non_digit_cols][-1:])
def test_ce_aftertax_income(puf_1991, weights_1991): # test certainty_equivalent() function con = 10000 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 with require_no_agg_tax_change equal to False cyr = 2020 crra = 1 # specify calc1 and calc_all() for cyr pol1 = Policy() rec1 = Records(data=puf_1991, weights=weights_1991, start_year=2009) calc1 = Calculator(policy=pol1, records=rec1) calc1.advance_to_year(cyr) calc1.calc_all() # specify calc2 and calc_all() for cyr pol2 = Policy() reform = {2018: {'_II_em': [0.0]}} pol2.implement_reform(reform) rec2 = Records(data=puf_1991, weights=weights_1991, start_year=2009) calc2 = Calculator(policy=pol2, records=rec2) calc2.advance_to_year(cyr) calc2.calc_all() cedict = ce_aftertax_income(calc1, calc2, require_no_agg_tax_change=False) assert cedict['year'] == cyr # test with require_no_agg_tax_change equal to True with pytest.raises(ValueError): ce_aftertax_income(calc1, calc2, 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_income(calc1, calc2, require_no_agg_tax_change=True, custom_params=params)
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_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_calculator_using_nonstd_input(rawinputfile): # check Calculator handling of raw, non-standard input data with no aging pol = Policy() pol.set_year(RAWINPUTFILE_YEAR) # set policy params to input data year nonstd = Records( data=rawinputfile.name, gfactors=None, # keeps raw data unchanged weights=None, start_year=RAWINPUTFILE_YEAR) # set raw input data year assert nonstd.dim == RAWINPUTFILE_FUNITS calc = Calculator(policy=pol, records=nonstd, sync_years=False) # keeps raw data unchanged assert calc.current_year == RAWINPUTFILE_YEAR calc.calc_all() assert calc.weighted_total('e00200') == 0 assert calc.total_weight() == 0 varlist = ['RECID', 'MARS'] pdf = calc.dataframe(varlist) assert isinstance(pdf, pd.DataFrame) assert pdf.shape == (RAWINPUTFILE_FUNITS, len(varlist)) mars = calc.array('MARS') assert isinstance(mars, np.ndarray) assert mars.shape == (RAWINPUTFILE_FUNITS, ) exp_iitax = np.zeros((nonstd.dim, )) assert np.allclose(calc.records.iitax, exp_iitax) mtr_ptax, _, _ = calc.mtr(wrt_full_compensation=False) exp_mtr_ptax = np.zeros((nonstd.dim, )) exp_mtr_ptax.fill(0.153) assert np.allclose(mtr_ptax, exp_mtr_ptax)
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_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) # 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.to_csv(mean_path, header=year_headers, float_format='%8.3f') corr_path = os.path.join(tests_path, CORR_FILENAME + '-new') table_corr.to_csv(corr_path, float_format='%8.3f') # compare new and old CSV files diffs_in_mean, mean_msg = differences(mean_path, mean_path[:-4], 'MEAN') diffs_in_corr, corr_msg = differences(corr_path, corr_path[:-4], 'CORR') if diffs_in_mean or diffs_in_corr: raise ValueError(mean_msg + corr_msg)
def test_calculator_using_nonstd_input(rawinputfile): """ Test Calculator using non-standard input records. """ # check Calculator handling of raw, non-standard input data with no aging pol = Policy() pol.set_year(RAWINPUTFILE_YEAR) # set policy params to input data year nonstd = Records(data=rawinputfile.name, gfactors=None, # keeps raw data unchanged weights=None, start_year=RAWINPUTFILE_YEAR) # set raw input data year assert nonstd.array_length == RAWINPUTFILE_FUNITS calc = Calculator(policy=pol, records=nonstd, sync_years=False) # keeps raw data unchanged assert calc.current_year == RAWINPUTFILE_YEAR calc.calc_all() assert calc.weighted_total('e00200') == 0 assert calc.total_weight() == 0 varlist = ['RECID', 'MARS'] dframe = calc.dataframe(varlist) assert isinstance(dframe, pd.DataFrame) assert dframe.shape == (RAWINPUTFILE_FUNITS, len(varlist)) mars = calc.array('MARS') assert isinstance(mars, np.ndarray) assert mars.shape == (RAWINPUTFILE_FUNITS,) exp_iitax = np.zeros((nonstd.array_length,)) assert np.allclose(calc.array('iitax'), exp_iitax) mtr_ptax, _, _ = calc.mtr(wrt_full_compensation=False) exp_mtr_ptax = np.zeros((nonstd.array_length,)) exp_mtr_ptax.fill(0.153) assert np.allclose(mtr_ptax, exp_mtr_ptax)
def test_calculator_using_nonstd_input(): """ Test Calculator using non-standard input records. """ # check Calculator handling of raw, non-standard input data with no aging pol = Policy() pol.set_year(RAWINPUT_YEAR) # set policy params to input data year nonstd = Records( data=pd.read_csv(StringIO(RAWINPUT_CONTENTS)), start_year=RAWINPUT_YEAR, # set raw input data year gfactors=None, # keeps raw data unchanged weights=None) assert nonstd.array_length == RAWINPUT_FUNITS calc = Calculator(policy=pol, records=nonstd, sync_years=False) # keeps raw data unchanged assert calc.current_year == RAWINPUT_YEAR calc.calc_all() assert calc.weighted_total('e00200') == 0 assert calc.total_weight() == 0 varlist = ['RECID', 'MARS'] dframe = calc.dataframe(varlist) assert isinstance(dframe, pd.DataFrame) assert dframe.shape == (RAWINPUT_FUNITS, len(varlist)) mars = calc.array('MARS') assert isinstance(mars, np.ndarray) assert mars.shape == (RAWINPUT_FUNITS, ) exp_iitax = np.zeros((nonstd.array_length, )) assert np.allclose(calc.array('iitax'), exp_iitax) mtr_ptax, _, _ = calc.mtr(wrt_full_compensation=False) exp_mtr_ptax = np.zeros((nonstd.array_length, )) exp_mtr_ptax.fill(0.153) assert np.allclose(mtr_ptax, exp_mtr_ptax)
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 = { 'UBI_u18': { 2014: 1000 }, 'UBI_1820': { 2014: 1000 }, 'UBI_21': { 2014: 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_correct_Calculator_instantiation(pit_fullsample, pit_subsample, gst_sample, cit_crosssample): syr = Policy.JSON_START_YEAR pol = Policy() assert pol.current_year == syr # specify expected number of filers and aggregate PIT liability expect_weight = 35.241e6 expect_pitax = 1812.601e9 # expect_corpweight = ??? # expect_citax = ??? # create full-sample Calculator object rec_full = Records(data=pit_fullsample) grec = GSTRecords(data=gst_sample) crec = CorpRecords(data=cit_crosssample) calc_full = Calculator(policy=pol, records=rec_full, gstrecords=grec, corprecords=crec) assert isinstance(calc_full, Calculator) assert calc_full.current_year == syr assert calc_full.records_current_year() == syr calc_full.calc_all() actual_full_weight = calc_full.total_weight() actual_full_pitax = calc_full.weighted_total('pitax') assert np.allclose([actual_full_weight], [expect_weight]) assert np.allclose([actual_full_pitax], [expect_pitax]) # TODO: test for corporate results # create sub-sample Calculator object """
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. """ rec = 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=rec) hc_calc.calc_all() # 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=rec) bs_calc.calc_all() # compare calculated tax results generated by the two reforms assert np.allclose(hc_calc.array('payrolltax'), bs_calc.array('payrolltax')) assert np.allclose(hc_calc.array('iitax'), bs_calc.array('iitax'))
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_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_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_mtr_plot(records_2009): pol = Policy() behv = Behavior() calc = Calculator(policy=pol, records=records_2009, behavior=behv) calc.calc_all() source = get_mtr_data(calc, calc, weighting='wage_weighted', weight_by_income_measure=True) plot = mtr_plot(source)
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_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_dist_table_sum_row(records_2009): # Create a default Policy object policy1 = Policy() # Create a Calculator calc1 = Calculator(policy=policy1, records=records_2009) calc1.calc_all() t1 = create_distribution_table(calc1.records, groupby="small_income_bins", result_type="weighted_sum") t2 = create_distribution_table(calc1.records, groupby="large_income_bins", result_type="weighted_sum") npt.assert_allclose(t1[-1:], t2[-1:]) t3 = create_distribution_table(calc1.records, groupby="small_income_bins", result_type="weighted_avg")
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_policy = Policy() hc_reform = { 'ID_Medical_hc': { 2013: 1.0 }, 'ID_StateLocalTax_hc': { 2013: 1.0 }, 'ID_RealEstate_hc': { 2013: 1.0 }, 'ID_Casualty_hc': { 2013: 1.0 }, 'ID_Miscellaneous_hc': { 2013: 1.0 }, 'ID_InterestPaid_hc': { 2013: 1.0 }, 'ID_Charity_hc': { 2013: 1.0 } } 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_policy = Policy() bs_reform = { 'ID_BenefitSurtax_crt': { 2013: 0.0 }, 'ID_BenefitSurtax_trt': { 2013: 1.0 } } bs_policy.implement_reform(bs_reform) bs_calc = Calculator(policy=bs_policy, records=recs) bs_calc.calc_all() bs_taxes = bs_calc.dataframe([], all_vars=True) 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_mtr_plot_force_no_bokeh(records_2009): import taxcalc taxcalc.utils.BOKEH_AVAILABLE = False pol = Policy() behv = Behavior() calc = Calculator(policy=pol, records=records_2009, behavior=behv) calc.calc_all() source = get_mtr_data(calc, calc, weighting='weighted_mean', weight_by_income_measure=True) with pytest.raises(RuntimeError): plot = mtr_plot(source) taxcalc.utils.BOKEH_AVAILABLE = True
def test_multiyear_diagnostic_table_wo_behv(records_2009): pol = Policy() reform = {2013: {"_II_rt7": [0.33], "_PT_rt7": [0.33]}} pol.implement_reform(reform) calc = Calculator(policy=pol, records=records_2009) calc.calc_all() liabilities_x = (calc.records._combined * calc.records.s006).sum() adt = multiyear_diagnostic_table(calc, 1) # extract combined liabilities as a float and # adopt units of the raw calculator data in liabilities_x liabilities_y = adt.iloc[18].tolist()[0] * 1000000000 npt.assert_almost_equal(liabilities_x, liabilities_y, 2)
def initiate_calculator(self): """ Creates an intial version of the taxcalc.Calculator object for 2014 """ policy1 = Policy() records1 = Records(data=self.records_data) if self.refdict != {}: policy1.implement_reform(self.refdict) calc1 = Calculator(records=records1, policy=policy1, verbose=False) calc1.advance_to_year(2014) calc1.calc_all() return (calc1)
def reform_results(reform_dict, puf_data, reform_2017_law): """ Return actual results of the reform specified in reform_dict. """ # pylint: disable=too-many-locals rec = Records(data=puf_data) # create baseline Calculator object, calc1 pol = Policy() if reform_dict['baseline'] == '2017_law.json': pol.implement_reform(reform_2017_law) elif reform_dict['baseline'] == 'current_law_policy.json': pass else: msg = 'illegal baseline value {}' raise ValueError(msg.format(reform_dict['baseline'])) calc1 = Calculator(policy=pol, records=rec, verbose=False, behavior=None) # create reform Calculator object, calc2, with possible behavioral response start_year = reform_dict['start_year'] beh = Behavior() if '_BE_cg' in reform_dict['value']: elasticity = reform_dict['value']['_BE_cg'] del reform_dict['value']['_BE_cg'] # in order to have a valid reform beh_assump = {start_year: {'_BE_cg': elasticity}} beh.update_behavior(beh_assump) reform = {start_year: reform_dict['value']} pol.implement_reform(reform) calc2 = Calculator(policy=pol, records=rec, verbose=False, behavior=beh) # increment both Calculator objects to reform's start_year calc1.advance_to_year(start_year) calc2.advance_to_year(start_year) # calculate prereform and postreform output for several years output_type = reform_dict['output_type'] num_years = 4 results = list() for _ in range(0, num_years): calc1.calc_all() prereform = calc1.array(output_type) if calc2.behavior_has_response(): calc2_br = Behavior.response(calc1, calc2) postreform = calc2_br.array(output_type) else: calc2.calc_all() postreform = calc2.array(output_type) diff = postreform - prereform weighted_sum_diff = (diff * calc1.array('s006')).sum() * 1.0e-9 results.append(weighted_sum_diff) calc1.increment_year() calc2.increment_year() # write actual results to actual_str actual_str = 'Tax-Calculator' for iyr in range(0, num_years): actual_str += ',{:.1f}'.format(results[iyr]) return actual_str
def test_dist_table_sum_row(pit_subsample, cit_crosssample): rec = Records(data=pit_subsample) crec = CorpRecords(data=cit_crosssample) calc = Calculator(policy=Policy(), records=rec, corprecords=crec) calc.calc_all() tb1 = create_distribution_table(calc.distribution_table_dataframe(), 'standard_income_bins', 'GTI') tb2 = create_distribution_table(calc.distribution_table_dataframe(), 'weighted_deciles', 'GTI') allrow1 = tb1[-1:] allrow2 = tb2[-4:-3] assert np.allclose(allrow1, allrow2)
def test_difference_table(cps_subsample): pol = Policy() recs = Records.cps_constructor(data=cps_subsample) calc1 = Calculator(policy=pol, records=recs) assert calc1.current_year == 2014 reform = {2014: {'_SS_Earnings_c': [9e99]}} pol.implement_reform(reform) assert not pol.reform_errors calc2 = Calculator(policy=pol, records=recs) calc2.calc_all() diff = calc1.difference_table(calc2) assert isinstance(diff, pd.DataFrame)
def test_calc_all(reform_file, rawinputfile): cyr = 2016 pol = Policy() param_dict = Calculator.read_json_param_objects(reform_file.name, None) pol.implement_reform(param_dict['policy']) pol.set_year(cyr) nonstd = Records(data=rawinputfile.name, gfactors=None, weights=None, start_year=cyr) assert nonstd.array_length == RAWINPUTFILE_FUNITS calc = Calculator(policy=pol, records=nonstd, sync_years=False) # keeps raw data unchanged assert calc.current_year == cyr calc.calc_all()
def reform_results(reform_dict, puf_data): """ Return actual results of the reform specified in reform_dict. """ # pylint: disable=too-many-locals # create current-law-policy Calculator object pol1 = Policy() rec1 = Records(data=puf_data) calc1 = Calculator(policy=pol1, records=rec1, verbose=False, behavior=None) # create reform Calculator object with possible behavioral responses start_year = reform_dict['start_year'] beh2 = Behavior() if '_BE_cg' in reform_dict['value']: elasticity = reform_dict['value']['_BE_cg'] del reform_dict['value']['_BE_cg'] # in order to have a valid reform beh_assump = {start_year: {'_BE_cg': elasticity}} beh2.update_behavior(beh_assump) reform = {start_year: reform_dict['value']} pol2 = Policy() pol2.implement_reform(reform) rec2 = Records(data=puf_data) calc2 = Calculator(policy=pol2, records=rec2, verbose=False, behavior=beh2) # increment both calculators to reform's start_year calc1.advance_to_year(start_year) calc2.advance_to_year(start_year) # calculate prereform and postreform output for several years output_type = reform_dict['output_type'] num_years = 4 results = list() for _ in range(0, num_years): calc1.calc_all() prereform = getattr(calc1.records, output_type) if calc2.behavior.has_response(): calc_clp = calc2.current_law_version() calc2_br = Behavior.response(calc_clp, calc2) postreform = getattr(calc2_br.records, output_type) else: calc2.calc_all() postreform = getattr(calc2.records, output_type) diff = postreform - prereform weighted_sum_diff = (diff * calc1.records.s006).sum() * 1.0e-9 results.append(weighted_sum_diff) calc1.increment_year() calc2.increment_year() # write actual results to actual_str reform_description = reform_dict['name'] actual_str = '{}\n'.format(reform_description) actual_str += 'Tax-Calculator' for iyr in range(0, num_years): actual_str += ',{:.1f}'.format(results[iyr]) return actual_str
def test_create_tables(puf_1991, weights_1991): # create a current-law Policy object and Calculator object calc1 policy1 = Policy() records1 = Records(data=puf_1991, weights=weights_1991, start_year=2009) calc1 = Calculator(policy=policy1, records=records1) calc1.calc_all() # create a policy-reform Policy object and Calculator object calc2 reform = {2013: {'_II_rt4': [0.56]}} policy2 = Policy() policy2.implement_reform(reform) records2 = Records(data=puf_1991, weights=weights_1991, start_year=2009) calc2 = Calculator(policy=policy2, records=records2) calc2.calc_all() # test creating various distribution tables dt1 = create_difference_table(calc1.records, calc2.records, groupby='large_income_bins') assert isinstance(dt1, pd.DataFrame) dt2 = create_difference_table(calc1.records, calc2.records, groupby='webapp_income_bins') assert isinstance(dt2, pd.DataFrame) with pytest.raises(ValueError): create_difference_table(calc1.records, calc2.records, groupby='bad_bins') with pytest.raises(ValueError): create_distribution_table(calc2.records, groupby='small_income_bins', result_type='bad_result_type') with pytest.raises(ValueError): create_distribution_table(calc2.records, groupby='bad_bins', result_type='weighted_sum') dt3 = create_distribution_table(calc2.records, groupby='small_income_bins', result_type='weighted_sum', baseline_obj=calc1.records, diffs=True) assert isinstance(dt3, pd.DataFrame) calc1.increment_year() with pytest.raises(ValueError): create_difference_table(calc1.records, calc2.records, groupby='large_income_bins') with pytest.raises(ValueError): create_distribution_table(calc2.records, groupby='small_income_bins', result_type='weighted_sum', baseline_obj=calc1.records, diffs=True)
def test_dist_table_sum_row(): # Create a default Policy object policy1 = Policy() records1 = Records(data=TAXDATA, weights=WEIGHTS, start_year=2009) # Create a Calculator calc1 = Calculator(policy=policy1, records=records1) calc1.calc_all() t1 = create_distribution_table(calc1, groupby="small_income_bins", result_type="weighted_sum") t2 = create_distribution_table(calc1, groupby="large_income_bins", result_type="weighted_sum") assert np.allclose(t1[-1:], t2[-1:]) t3 = create_distribution_table(calc1, groupby="small_income_bins", result_type="weighted_avg")
def test_difference_table(cps_subsample): 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_create_difference_table(): # create current-law Policy object and use to create Calculator calc1 policy1 = Policy() puf1 = Records(data=TAX_DTA, weights=WEIGHTS, start_year=2009) calc1 = Calculator(policy=policy1, records=puf1) calc1.calc_all() # create policy-reform Policy object and use to create Calculator calc2 policy2 = Policy() reform = {2013: {'_II_rt7': [0.45]}} policy2.implement_reform(reform) puf2 = Records(data=TAX_DTA, weights=WEIGHTS, start_year=2009) calc2 = Calculator(policy=policy2, records=puf2) # create difference table and check that it is a Pandas DataFrame dtable = create_difference_table(calc1, calc2, groupby="weighted_deciles") assert isinstance(dtable, pd.DataFrame)
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_percentage_change_gdp(): """ Test Tax-Calculator macro_elasticity.py capability. """ calc1 = Calculator(policy=Policy(), records=Records(data=PUFCSV_PATH)) calc1.calc_all() policy2 = Policy() reform = {2013: {"_STD": [[12600, 25200, 12600, 18600, 25300, 12600, 2100]], "_AMT_trt1": [0.0], "_AMT_trt2": [0.0]}} policy2.implement_reform(reform) calc2 = Calculator(policy=policy2, records=Records(data=PUFCSV_PATH)) calc2.calc_all() gdp_diff = percentage_change_gdp(calc1, calc2, elasticity=0.36) assert gdp_diff > 0
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 reform_results(rid, reform_dict, puf_data, reform_2017_law): """ Return actual results of the reform specified by rid and reform_dict. """ # pylint: disable=too-many-locals rec = Records(data=puf_data) # create baseline Calculator object, calc1 pol = Policy() if reform_dict['baseline'] == '2017_law.json': pol.implement_reform(reform_2017_law) elif reform_dict['baseline'] == 'policy_current_law.json': pass else: msg = 'illegal baseline value {}' raise ValueError(msg.format(reform_dict['baseline'])) calc1 = Calculator(policy=pol, records=rec, verbose=False) # create reform Calculator object, calc2 start_year = reform_dict['start_year'] reform = dict() for name, value in reform_dict['value'].items(): reform[name] = {start_year: value} pol.implement_reform(reform) calc2 = Calculator(policy=pol, records=rec, verbose=False) # increment both Calculator objects to reform's start_year calc1.advance_to_year(start_year) calc2.advance_to_year(start_year) # calculate baseline and reform output for several years output_type = reform_dict['output_type'] num_years = 4 results = list() for _ in range(0, num_years): calc1.calc_all() baseline = calc1.array(output_type) calc2.calc_all() reform = calc2.array(output_type) diff = reform - baseline weighted_sum_diff = (diff * calc1.array('s006')).sum() * 1.0e-9 results.append(weighted_sum_diff) calc1.increment_year() calc2.increment_year() # write actual results to actual_str actual_str = '{}'.format(rid) for iyr in range(0, num_years): actual_str += ',{:.1f}'.format(results[iyr]) return actual_str
def test_mtr_pt_active(puf_subsample): """ Test whether including wages in active income causes MTRs on e00900p and e26270 to be less than -1 (i.e., -100%) """ # pylint: disable=too-many-locals rec = Records(data=puf_subsample) reform_year = 2018 # create current-law Calculator object, calc1 pol1 = Policy() calc1 = Calculator(policy=pol1, records=rec) calc1.advance_to_year(reform_year) calc1.calc_all() mtr1_e00900p = calc1.mtr('e00900p')[2] mtr1_e26270 = calc1.mtr('e26270')[2] assert min(mtr1_e00900p) > -1 assert min(mtr1_e26270) > -1 # change PT rates, calc2 reform2 = {'PT_rt7': {reform_year: 0.35}} pol2 = Policy() pol2.implement_reform(reform2) calc2 = Calculator(policy=pol2, records=rec) calc2.advance_to_year(reform_year) calc2.calc_all() mtr2_e00900p = calc2.mtr('e00900p')[2] mtr2_e26270 = calc2.mtr('e26270')[2] assert min(mtr2_e00900p) > -1 assert min(mtr2_e26270) > -1 # change PT_wages_active_income reform3 = {'PT_wages_active_income': {reform_year: True}} pol3 = Policy() pol3.implement_reform(reform3) calc3 = Calculator(policy=pol3, records=rec) calc3.advance_to_year(reform_year) calc3.calc_all() mtr3_e00900p = calc3.mtr('e00900p')[2] mtr3_e26270 = calc3.mtr('e26270')[2] assert min(mtr3_e00900p) > -1 assert min(mtr3_e26270) > -1 # change PT rates and PT_wages_active_income reform4 = { 'PT_wages_active_income': {reform_year: True}, 'PT_rt7': {reform_year: 0.35} } pol4 = Policy() pol4.implement_reform(reform4) calc4 = Calculator(policy=pol4, records=rec) calc4.advance_to_year(reform_year) calc4.calc_all() mtr4_e00900p = calc4.mtr('e00900p')[2] mtr4_e26270 = calc4.mtr('e26270')[2] assert min(mtr4_e00900p) > -1 assert min(mtr4_e26270) > -1
def test_Calculator_using_nonstd_input(rawinputfile): # check Calculator handling of raw, non-standard input data with no aging policy = Policy() policy.set_year(RAWINPUTFILE_YEAR) # set policy params to input data year nonpuf = Records(data=rawinputfile.name, start_year=RAWINPUTFILE_YEAR, # set raw input data year consider_imputations=False) # keeps raw data unchanged assert nonpuf.dim == RAWINPUTFILE_FUNITS calc = Calculator(policy=policy, records=nonpuf, sync_years=False) # keeps raw data unchanged assert calc.current_year == RAWINPUTFILE_YEAR calc.calc_all() exp_iitax = np.zeros((nonpuf.dim,)) assert_array_equal(nonpuf._iitax, exp_iitax) mtr_fica, _, _ = calc.mtr(wrt_full_compensation=False) exp_mtr_fica = np.zeros((nonpuf.dim,)) exp_mtr_fica.fill(0.153) assert_array_equal(mtr_fica, exp_mtr_fica)
def test_create_tables(): # create a current-law Policy object and Calculator object calc1 policy1 = Policy() records1 = Records(data=TAXDATA, weights=WEIGHTS, start_year=2009) calc1 = Calculator(policy=policy1, records=records1) calc1.calc_all() # create a policy-reform Policy object and Calculator object calc2 reform = {2013: {'_II_rt4': [0.56]}} policy2 = Policy() policy2.implement_reform(reform) records2 = Records(data=TAXDATA, weights=WEIGHTS, start_year=2009) calc2 = Calculator(policy=policy2, records=records2) calc2.calc_all() # create various distribution tables t2 = create_distribution_table(calc2, groupby="small_income_bins", result_type="weighted_sum") tdiff = create_difference_table(calc1, calc2, groupby="large_income_bins") tdiff_webapp = create_difference_table(calc1, calc2, groupby="webapp_income_bins")
def test_row_classifier(puf_1991, weights_1991): # create a current-law Policy object and Calculator calc1 policy1 = Policy() records1 = Records(data=puf_1991, weights=weights_1991, start_year=2009) calc1 = Calculator(policy=policy1, records=records1) calc1.calc_all() calc1_s006 = create_distribution_table(calc1.records, groupby="webapp_income_bins", result_type="weighted_sum").s006 # create a policy-reform Policy object and Calculator calc2 reform = {2013: {"_ALD_StudentLoan_hc": [1]}} policy2 = Policy() policy2.implement_reform(reform) records2 = Records(data=puf_1991, weights=weights_1991, start_year=2009) calc2 = Calculator(policy=policy2, records=records2) calc2.calc_all() calc2_s006 = create_distribution_table( calc2.records, groupby="webapp_income_bins", result_type="weighted_sum", baseline_obj=calc1.records ).s006 # use weighted sum of weights in each cell to check classifer npt.assert_array_equal(calc1_s006, calc2_s006)
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_create_tables(puf_1991, weights_1991): # create a current-law Policy object and Calculator object calc1 policy1 = Policy() records1 = Records(data=puf_1991, weights=weights_1991, start_year=2009) calc1 = Calculator(policy=policy1, records=records1) calc1.calc_all() # create a policy-reform Policy object and Calculator object calc2 reform = {2013: {'_II_rt4': [0.56]}} policy2 = Policy() policy2.implement_reform(reform) records2 = Records(data=puf_1991, weights=weights_1991, start_year=2009) calc2 = Calculator(policy=policy2, records=records2) calc2.calc_all() # test creating various distribution tables dt1 = create_difference_table(calc1.records, calc2.records, groupby='large_income_bins') dt2 = create_difference_table(calc1.records, calc2.records, groupby='webapp_income_bins') with pytest.raises(ValueError): dt = create_difference_table(calc1.records, calc2.records, groupby='bad_bins') with pytest.raises(ValueError): dt = create_distribution_table(calc2.records, groupby='small_income_bins', result_type='bad_result_type') with pytest.raises(ValueError): dt = create_distribution_table(calc2.records, groupby='bad_bins', result_type='weighted_sum') dt3 = create_distribution_table(calc2.records, groupby='small_income_bins', result_type='weighted_sum', baseline_obj=calc1.records, diffs=True) calc1.increment_year() with pytest.raises(ValueError): dt = create_difference_table(calc1.records, calc2.records, groupby='large_income_bins') with pytest.raises(ValueError): dt = create_distribution_table(calc2.records, groupby='small_income_bins', result_type='weighted_sum', baseline_obj=calc1.records, diffs=True)
def test_Calculator_using_nonstd_input(rawinputfile): # check Calculator handling of raw, non-standard input data with no aging policy = Policy() policy.set_year(RAWINPUTFILE_YEAR) # set policy params to input data year nonpuf = Records(data=rawinputfile.name, blowup_factors=None, # keeps raw data unchanged weights=None, start_year=RAWINPUTFILE_YEAR) # set raw input data year assert nonpuf.dim == RAWINPUTFILE_FUNITS calc = Calculator(policy=policy, records=nonpuf, sync_years=False) # keeps raw data unchanged assert calc.current_year == RAWINPUTFILE_YEAR calc.calc_all() exp_iitax = np.zeros((nonpuf.dim,)) assert np.allclose(nonpuf._iitax, exp_iitax) mtr_ptax, _, _ = calc.mtr(wrt_full_compensation=False) exp_mtr_ptax = np.zeros((nonpuf.dim,)) exp_mtr_ptax.fill(0.153) assert np.allclose(mtr_ptax, exp_mtr_ptax)
def test_diff_table_sum_row(puf_1991, weights_1991): # create a current-law Policy object and Calculator calc1 policy1 = Policy() records1 = Records(data=puf_1991, weights=weights_1991, start_year=2009) calc1 = Calculator(policy=policy1, records=records1) calc1.calc_all() # create a policy-reform Policy object and Calculator calc2 reform = {2013: {"_II_rt4": [0.56]}} policy2 = Policy() policy2.implement_reform(reform) records2 = Records(data=puf_1991, weights=weights_1991, start_year=2009) calc2 = Calculator(policy=policy2, records=records2) calc2.calc_all() # create two difference tables and compare their content tdiff1 = create_difference_table(calc1.records, calc2.records, groupby="small_income_bins") tdiff2 = create_difference_table(calc1.records, calc2.records, groupby="large_income_bins") non_digit_cols = ["mean", "perc_inc", "perc_cut", "share_of_change"] digit_cols = [x for x in tdiff1.columns.tolist() if x not in non_digit_cols] npt.assert_allclose(tdiff1[digit_cols][-1:], tdiff2[digit_cols][-1:]) assert np.array_equal(tdiff1[non_digit_cols][-1:], tdiff2[non_digit_cols][-1:])
def test_percentage_change_gdp(): policy1 = Policy() records1 = Records(data=TAXDATA, weights=WEIGHTS, start_year=2009) calc1 = Calculator(policy=policy1, records=records1) calc1.calc_all() reform = {2013: {"_STD": [[12600, 25200, 12600, 18600, 25300, 12600, 2100]], "_AMT_trt1": [0.0], "_AMT_trt2": [0.0]}} policy2 = Policy() policy2.implement_reform(reform) records2 = Records(data=TAXDATA, weights=WEIGHTS, start_year=2009) calc2 = Calculator(policy=policy2, records=records2) calc2.calc_all() gdp_diff = percentage_change_gdp(calc1, calc2, elasticity=0.36) assert gdp_diff > 0
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_Calculator_create_distribution_table(): policy = Policy() puf = Records(data=TAX_DTA, 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)