示例#1
0
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
示例#2
0
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)
示例#3
0
def test_mtr_graph_data(records_2009):
    calc = Calculator(policy=Policy(), records=records_2009)
    with pytest.raises(ValueError):
        gdata = mtr_graph_data(calc,
                               calc,
                               mars='bad',
                               income_measure='agi',
                               dollar_weighting=True)
    with pytest.raises(ValueError):
        gdata = mtr_graph_data(calc,
                               calc,
                               mars=0,
                               income_measure='expanded_income',
                               dollar_weighting=True)
    with pytest.raises(ValueError):
        gdata = mtr_graph_data(calc, calc, mars=list())
    with pytest.raises(ValueError):
        gdata = mtr_graph_data(calc, calc, mtr_measure='badtax')
    with pytest.raises(ValueError):
        gdata = mtr_graph_data(calc, calc, income_measure='badincome')
    with pytest.raises(ValueError):
        calcx = Calculator(policy=Policy(), records=records_2009)
        calcx.advance_to_year(2020)
        gdata = mtr_graph_data(calcx, calc)
    gdata = mtr_graph_data(calc,
                           calc,
                           mars=1,
                           mtr_wrt_full_compen=True,
                           income_measure='wages',
                           dollar_weighting=True)
    assert type(gdata) == dict
示例#4
0
文件: data.py 项目: MattHJensen/plots
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
示例#5
0
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 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_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_Calculator_advance_to_year(records_2009):
    policy = Policy()
    calc = Calculator(policy=policy, records=records_2009)
    calc.advance_to_year(2016)
    assert calc.current_year == 2016
    with pytest.raises(ValueError):
        calc.advance_to_year(2015)
示例#10
0
def test_Calculator_advance_to_year(records_2009):
    policy = Policy()
    calc = Calculator(policy=policy, records=records_2009)
    calc.advance_to_year(2016)
    assert calc.current_year == 2016
    with pytest.raises(ValueError):
        calc.advance_to_year(2015)
示例#11
0
文件: data.py 项目: PSLmodels/plots
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)
示例#12
0
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)
示例#13
0
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)
示例#14
0
def test_calculator_advance_to_year(cps_subsample):
    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)
示例#15
0
def test_Calculator_advance_to_year():
    policy = Policy()
    puf = Records(data=TAXDATA, weights=WEIGHTS, start_year=2009)
    calc = Calculator(policy=policy, records=puf)
    calc.advance_to_year(2016)
    assert calc.current_year == 2016
    with pytest.raises(ValueError):
        calc.advance_to_year(2015)
def test_Calculator_advance_to_year():
    policy = Policy()
    puf = Records(data=TAXDATA, weights=WEIGHTS, start_year=2009)
    calc = Calculator(policy=policy, records=puf)
    calc.advance_to_year(2016)
    assert calc.current_year == 2016
    with pytest.raises(ValueError):
        calc.advance_to_year(2015)
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)
示例#18
0
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
示例#19
0
 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)
示例#20
0
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 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
示例#22
0
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
示例#23
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, no_benefits=True)
    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)
示例#24
0
def test_Calculator_results_consistency(pit_fullsample, gst_sample,
                                        cit_crosssample):
    # generate calculated-variable dataframe for full sample in second year
    recs = Records(data=pit_fullsample)
    grecs = GSTRecords(data=gst_sample)
    crecs = CorpRecords(data=cit_crosssample)
    calc = Calculator(policy=Policy(),
                      records=recs,
                      gstrecords=grecs,
                      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 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
示例#26
0
def reform_results(rid, reform_dict, reform_2017_law):
    """
    Return actual results of the reform specified by rid and reform_dict.
    """
    # pylint: disable=too-many-locals
    rec = Records.cps_constructor()
    # 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
示例#27
0
def test_mtr_graph_data(records_2009):
    calc = Calculator(policy=Policy(), records=records_2009)
    with pytest.raises(ValueError):
        gdata = mtr_graph_data(calc, calc, mars="bad", income_measure="agi", dollar_weighting=True)
    with pytest.raises(ValueError):
        gdata = mtr_graph_data(calc, calc, mars=0, income_measure="expanded_income", dollar_weighting=True)
    with pytest.raises(ValueError):
        gdata = mtr_graph_data(calc, calc, mars=list())
    with pytest.raises(ValueError):
        gdata = mtr_graph_data(calc, calc, mtr_measure="badtax")
    with pytest.raises(ValueError):
        gdata = mtr_graph_data(calc, calc, income_measure="badincome")
    with pytest.raises(ValueError):
        calcx = Calculator(policy=Policy(), records=records_2009)
        calcx.advance_to_year(2020)
        gdata = mtr_graph_data(calcx, calc)
    gdata = mtr_graph_data(calc, calc, mars=1, mtr_wrt_full_compen=True, income_measure="wages", dollar_weighting=True)
    assert type(gdata) == dict
示例#28
0
def test_atr_graph_data(records_2009):
    calc = Calculator(policy=Policy(), records=records_2009)
    with pytest.raises(ValueError):
        gdata = atr_graph_data(calc, calc, mars='bad')
    with pytest.raises(ValueError):
        gdata = atr_graph_data(calc, calc, mars=0)
    with pytest.raises(ValueError):
        gdata = atr_graph_data(calc, calc, mars=list())
    with pytest.raises(ValueError):
        gdata = atr_graph_data(calc, calc, atr_measure='badtax')
    with pytest.raises(ValueError):
        calcx = Calculator(policy=Policy(), records=records_2009)
        calcx.advance_to_year(2020)
        gdata = atr_graph_data(calcx, calc)
    gdata = atr_graph_data(calc, calc, mars=1, atr_measure='combined')
    gdata = atr_graph_data(calc, calc, atr_measure='itax')
    gdata = atr_graph_data(calc, calc, atr_measure='ptax')
    assert type(gdata) == dict
示例#29
0
def test_atr_graph_data(records_2009):
    calc = Calculator(policy=Policy(), records=records_2009)
    with pytest.raises(ValueError):
        gdata = atr_graph_data(calc, calc, mars="bad")
    with pytest.raises(ValueError):
        gdata = atr_graph_data(calc, calc, mars=0)
    with pytest.raises(ValueError):
        gdata = atr_graph_data(calc, calc, mars=list())
    with pytest.raises(ValueError):
        gdata = atr_graph_data(calc, calc, atr_measure="badtax")
    with pytest.raises(ValueError):
        calcx = Calculator(policy=Policy(), records=records_2009)
        calcx.advance_to_year(2020)
        gdata = atr_graph_data(calcx, calc)
    gdata = atr_graph_data(calc, calc, mars=1, atr_measure="combined")
    gdata = atr_graph_data(calc, calc, atr_measure="itax")
    gdata = atr_graph_data(calc, calc, atr_measure="ptax")
    assert type(gdata) == dict
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
示例#31
0
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
示例#32
0
def test_Calculator_create_difference_table(puf_1991, weights_1991):
    # create current-law Policy object and use to create Calculator calc1
    policy1 = Policy()
    puf1 = Records(data=puf_1991, weights=weights_1991, start_year=2009)
    calc1 = Calculator(policy=policy1, records=puf1)
    calc1.advance_to_year(2013)
    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=puf_1991, weights=weights_1991, start_year=2009)
    calc2 = Calculator(policy=policy2, records=puf2)
    calc2.advance_to_year(2013)
    calc2.calc_all()
    # create difference table and check that it is a Pandas DataFrame
    dtable = create_difference_table(calc1.records,
                                     calc2.records,
                                     groupby="weighted_deciles")
    assert isinstance(dtable, pd.DataFrame)
示例#33
0
def test_atr_graph_data(cps_subsample):
    pol = Policy()
    rec = Records.cps_constructor(data=cps_subsample)
    calc = Calculator(policy=pol, records=rec)
    with pytest.raises(ValueError):
        atr_graph_data(calc, calc, mars='bad')
    with pytest.raises(ValueError):
        atr_graph_data(calc, calc, mars=0)
    with pytest.raises(ValueError):
        atr_graph_data(calc, calc, mars=list())
    with pytest.raises(ValueError):
        atr_graph_data(calc, calc, atr_measure='badtax')
    gdata = atr_graph_data(calc, calc, mars=1, atr_measure='combined')
    gdata = atr_graph_data(calc, calc, atr_measure='itax')
    gdata = atr_graph_data(calc, calc, atr_measure='ptax')
    assert isinstance(gdata, dict)
    with pytest.raises(ValueError):
        calcx = Calculator(policy=pol, records=rec)
        calcx.advance_to_year(2020)
        atr_graph_data(calcx, calc)
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)
示例#35
0
def test_credit_reforms(puf_subsample):
    """
    Test personal credit reforms using puf.csv subsample
    """
    rec = Records(data=puf_subsample)
    reform_year = 2017
    # create current-law Calculator object, calc1
    pol = Policy()
    calc1 = Calculator(policy=pol, records=rec)
    calc1.advance_to_year(reform_year)
    calc1.calc_all()
    itax1 = calc1.weighted_total('iitax')
    # create personal-refundable-credit-reform Calculator object, calc2
    reform = {reform_year: {'_II_credit': [[1000, 1000, 1000, 1000, 1000]]}}
    pol.implement_reform(reform)
    calc2 = Calculator(policy=pol, records=rec)
    calc2.advance_to_year(reform_year)
    calc2.calc_all()
    itax2 = calc2.weighted_total('iitax')
    # create personal-nonrefundable-credit-reform Calculator object, calc3
    reform = {reform_year: {'_II_credit_nr': [[1000, 1000, 1000, 1000, 1000]]}}
    pol = Policy()
    pol.implement_reform(reform)
    calc3 = Calculator(policy=pol, records=rec)
    calc3.advance_to_year(reform_year)
    calc3.calc_all()
    itax3 = calc3.weighted_total('iitax')
    # check income tax revenues generated by the three Calculator objects
    assert itax2 < itax1  # because refundable credits lower revenues
    assert itax3 > itax2  # because nonrefundable credits lower revenues less
    assert itax3 < itax1  # because nonrefundable credits lower revenues some
def test_credit_reforms(puf_subsample):
    """
    Test personal credit reforms using puf.csv subsample
    """
    rec = Records(data=puf_subsample)
    reform_year = 2017
    # create current-law Calculator object, calc1
    pol = Policy()
    calc1 = Calculator(policy=pol, records=rec)
    calc1.advance_to_year(reform_year)
    calc1.calc_all()
    itax1 = calc1.weighted_total('iitax')
    # create personal-refundable-credit-reform Calculator object, calc2
    reform = {'II_credit': {reform_year: [1000, 1000, 1000, 1000, 1000]}}
    pol.implement_reform(reform)
    calc2 = Calculator(policy=pol, records=rec)
    calc2.advance_to_year(reform_year)
    calc2.calc_all()
    itax2 = calc2.weighted_total('iitax')
    # create personal-nonrefundable-credit-reform Calculator object, calc3
    reform = {'II_credit_nr': {reform_year: [1000, 1000, 1000, 1000, 1000]}}
    pol = Policy()
    pol.implement_reform(reform)
    calc3 = Calculator(policy=pol, records=rec)
    calc3.advance_to_year(reform_year)
    calc3.calc_all()
    itax3 = calc3.weighted_total('iitax')
    # check income tax revenues generated by the three Calculator objects
    assert itax2 < itax1  # because refundable credits lower revenues
    assert itax3 > itax2  # because nonrefundable credits lower revenues less
    assert itax3 < itax1  # because nonrefundable credits lower revenues some
示例#37
0
文件: data.py 项目: MattHJensen/plots
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 = 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
示例#38
0
def test_Calculator_create_difference_table(puf_1991, weights_1991):
    # create current-law Policy object and use to create Calculator calc1
    policy1 = Policy()
    puf1 = Records(data=puf_1991, weights=weights_1991, start_year=2009)
    calc1 = Calculator(policy=policy1, records=puf1)
    calc1.advance_to_year(2013)
    calc1.calc_all()
    # create policy-reform Policy object and use to create Calculator calc2
    policy2 = Policy()
    reform = {
        2013: {'_II_rt7': [0.45]},
        2013: {'_ALD_Investment_ec_base_code_active': [True]},
        0: {'ALD_Investment_ec_base_code': 'e00300 + e00650 + p23250'}
    }
    policy2.implement_reform(reform)
    puf2 = Records(data=puf_1991, weights=weights_1991, start_year=2009)
    calc2 = Calculator(policy=policy2, records=puf2)
    calc2.advance_to_year(2013)
    calc2.calc_all()
    # create difference table and check that it is a Pandas DataFrame
    dtable = create_difference_table(calc1.records, calc2.records,
                                     groupby="weighted_deciles")
    assert isinstance(dtable, pd.DataFrame)
示例#39
0
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
示例#40
0
def taxcalc_results(start_year, reform_dict, itax_clp, fica_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))
    calc.advance_to_year(start_year)
    adt = calc.diagnostic_table(num_years=NUMBER_OF_YEARS)
    # note that adt is Pandas DataFrame object
    itax_ref = adt.xs('Ind inc tax ($b)').to_dict()
    fica_ref = adt.xs('Payroll tax ($b)').to_dict()
    itax_diff = {}
    fica_diff = {}
    for year in itax_ref:
        itax_diff[year] = round(itax_ref[year] - itax_clp[year], 1)
        fica_diff[year] = round(fica_ref[year] - fica_clp[year], 1)
    return (itax_diff, fica_diff)
示例#41
0
文件: data.py 项目: PSLmodels/plots
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
示例#42
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 = {2018: {'_II_em': [0.0]}}
    pol.implement_reform(reform)
    calc2 = Calculator(policy=pol, records=rec)
    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)
示例#43
0
def test_credit_reforms(puf_path):  # pylint: disable=redefined-outer-name
    """
    Test personal credit reforms using small puf.csv sub-sample
    """
    # pylint: disable=too-many-locals
    reform_year = 2017
    fullsample = pd.read_csv(puf_path)
    subsample = fullsample.sample(
        frac=0.05,  # pylint: disable=no-member
        random_state=180)
    # create current-law Calculator object, calc1
    recs1 = Records(data=subsample)
    calc1 = Calculator(policy=Policy(), records=recs1)
    calc1.advance_to_year(reform_year)
    calc1.calc_all()
    itax1 = (calc1.records.iitax * calc1.records.s006).sum()
    # create personal-refundable-credit-reform Calculator object, calc2
    recs2 = Records(data=subsample)
    policy2 = Policy()
    reform = {reform_year: {'_II_credit': [[1000, 1000, 1000, 1000, 1000]]}}
    policy2.implement_reform(reform)
    calc2 = Calculator(policy=policy2, records=recs2)
    calc2.advance_to_year(reform_year)
    calc2.calc_all()
    itax2 = (calc2.records.iitax * calc2.records.s006).sum()
    # create personal-nonrefundable-credit-reform Calculator object, calc3
    recs3 = Records(data=subsample)
    policy3 = Policy()
    reform = {reform_year: {'_II_credit_nr': [[1000, 1000, 1000, 1000, 1000]]}}
    policy3.implement_reform(reform)
    calc3 = Calculator(policy=policy3, records=recs3)
    calc3.advance_to_year(reform_year)
    calc3.calc_all()
    itax3 = (calc3.records.iitax * calc3.records.s006).sum()
    # check income tax revenues generated by the three Calculator objects
    assert itax2 < itax1  # because refundable credits lower revenues
    assert itax3 > itax2  # because nonrefundable credits lower revenues less
    assert itax3 < itax1  # because nonrefundable credits lower revenues some
示例#44
0
def test_benefits(tests_path, cps_fullsample):
    """
    Test CPS benefits.
    """
    # pylint: disable=too-many-locals
    benefit_names = ['ssi', 'mcare', 'mcaid', 'snap', 'wic',
                     'tanf', 'vet', 'housing']
    # write benefits_actual.csv file
    recs = Records.cps_constructor(data=cps_fullsample)
    start_year = recs.current_year
    calc = Calculator(policy=Policy(), records=recs, verbose=False)
    assert calc.current_year == start_year
    year_list = list()
    bname_list = list()
    benamt_list = list()
    bencnt_list = list()
    benavg_list = list()
    for year in range(start_year, Policy.LAST_BUDGET_YEAR + 1):
        calc.advance_to_year(year)
        size = calc.array('XTOT')
        wght = calc.array('s006')
        # compute benefit aggregate amounts and head counts and average benefit
        # (head counts include all members of filing unit receiving a benefit,
        #  which means benavg is f.unit benefit amount divided by f.unit size)
        for bname in benefit_names:
            ben = calc.array('{}_ben'.format(bname))
            benamt = round((ben * wght).sum() * 1e-9, 3)
            bencnt = round((size[ben > 0] * wght[ben > 0]).sum() * 1e-6, 3)
            benavg = round(benamt / bencnt, 1)
            year_list.append(year)
            bname_list.append(bname)
            benamt_list.append(benamt)
            bencnt_list.append(bencnt)
            benavg_list.append(benavg)
    adict = {'year': year_list,
             'bname': bname_list,
             'benamt': benamt_list,
             'bencnt': bencnt_list,
             'benavg': benavg_list}
    adf = pd.DataFrame(data=adict,
                       columns=['year', 'bname', 'benamt', 'bencnt', 'benavg'])
    ben_act_path = os.path.join(tests_path, 'benefits_actual.csv')
    adf.to_csv(ben_act_path, index=False)
    # read benefits_expect.csv file
    ben_exp_path = os.path.join(tests_path, 'benefits_expect.csv')
    edf = pd.read_csv(ben_exp_path)
    # compare benefit information
    atol = 0.0001
    rtol = 0.0
    diffs = False
    for col in ['benamt', 'bencnt', 'benavg']:
        if not np.allclose(adf[col], edf[col], atol=atol, rtol=rtol):
            diffs = True
    if diffs:
        msg = 'CPS BENEFITS RESULTS DIFFER\n'
        msg += '-------------------------------------------------\n'
        msg += '--- NEW RESULTS IN benefits_actual.txt FILE   ---\n'
        msg += '--- if new OK, copy benefits_actual.txt to    ---\n'
        msg += '---                 benefits_expect.txt       ---\n'
        msg += '---            and rerun test.                ---\n'
        msg += '-------------------------------------------------\n'
        raise ValueError(msg)
    else:
        os.remove(ben_act_path)
示例#45
0
    beh2 = Behavior()
    if "_BE_cg" in REFORMS_JSON.get(this_reform).get("value"):
        elasticity = REFORMS_JSON[this_reform]["value"]["_BE_cg"]
        del REFORMS_JSON[this_reform]["value"]["_BE_cg"]  # to not break reform
        beh_assump = {start_year: {"_BE_cg": elasticity}}
        beh2.update_behavior(beh_assump)
    reform = {start_year: REFORMS_JSON.get(this_reform).get("value")}
    pol2 = Policy()
    pol2.implement_reform(reform)
    rec2 = Records(data=PUF_DATA)
    calc2 = Calculator(policy=pol2, records=rec2, verbose=False, behavior=beh2)
    output_type = REFORMS_JSON.get(this_reform).get("output_type")
    reform_name = REFORMS_JSON.get(this_reform).get("name")

    # increment both calculators to reform's start_year
    calc1.advance_to_year(start_year)
    calc2.advance_to_year(start_year)

    # calculate prereform and postreform for num_years
    reform_results = []
    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
示例#46
0
def test_reform_json_and_output():
    """
    Check that each JSON reform file can be converted into a reform dictionary
    that can then be passed to the Policy class implement_reform method that
    generates no parameter_errors.
    Then use each reform to generate static tax results for small set of
    filing units in a single tax_year and compare those results with
    expected results from a CSV-formatted file.
    """

    # pylint: disable=too-many-statements,too-many-locals

    # embedded function used only in test_reform_json_and_output
    def write_res_file(calc, resfilename):
        """
        Write calc output to CSV-formatted file with resfilename.
        """
        varlist = [
            'RECID', 'c00100', 'standard', 'c04800', 'iitax', 'payrolltax'
        ]
        # varnames  AGI    STD         TaxInc    ITAX     PTAX
        stats = calc.dataframe(varlist)
        stats['RECID'] = stats['RECID'].astype(int)
        with open(resfilename, 'w') as resfile:
            stats.to_csv(resfile, index=False, float_format='%.2f')

    # embedded function used only in test_reform_json_and_output
    def res_and_out_are_same(base):
        """
        Return True if base.res.csv and base.out.csv file contents are same;
        return False if base.res.csv and base.out.csv file contents differ.
        """
        resdf = pd.read_csv(base + '.res.csv')
        outdf = pd.read_csv(base + '.out.csv')
        diffs = False
        for col in resdf:
            if col in outdf:
                if not np.allclose(resdf[col], outdf[col]):
                    diffs = True
            else:
                diffs = True
        return not diffs

    # specify Records object containing cases data
    tax_year = 2020
    cases_path = os.path.join(CUR_PATH, '..', 'taxcalc', 'cases.csv')
    cases = Records(
        data=cases_path,
        start_year=tax_year,  # set raw input data year
        gfactors=None,  # keeps raw data unchanged
        weights=None,
        adjust_ratios=None)
    # specify list of reform failures
    failures = list()
    # specify current-law-policy Calculator object
    calc = Calculator(policy=Policy(), records=cases, verbose=False)
    calc.advance_to_year(tax_year)
    calc.calc_all()
    res_path = cases_path.replace('cases.csv', 'clp.res.csv')
    write_res_file(calc, res_path)
    if res_and_out_are_same(res_path.replace('.res.csv', '')):
        os.remove(res_path)
    else:
        failures.append(res_path)
    del calc
    # read 2017_law.json reform file and specify its parameters dictionary
    pre_tcja_jrf = os.path.join(CUR_PATH, '..', 'taxcalc', '2017_law.json')
    pre_tcja = Policy.read_json_reform(pre_tcja_jrf)
    # check reform file contents and reform results for each reform
    reforms_path = os.path.join(CUR_PATH, '..', 'taxcalc', '*.json')
    json_reform_files = glob.glob(reforms_path)
    for jrf in json_reform_files:
        # determine reform's baseline by reading contents of jrf
        with open(jrf, 'r') as rfile:
            jrf_text = rfile.read()
        pre_tcja_baseline = 'Reform_Baseline: 2017_law.json' in jrf_text
        # implement the reform relative to its baseline
        reform = Policy.read_json_reform(jrf_text)
        pol = Policy()  # current-law policy
        if pre_tcja_baseline:
            pol.implement_reform(pre_tcja)
            assert not pol.parameter_errors
        pol.implement_reform(reform)
        assert not pol.parameter_errors
        calc = Calculator(policy=pol, records=cases, verbose=False)
        calc.advance_to_year(tax_year)
        calc.calc_all()
        res_path = jrf.replace('.json', '.res.csv')
        write_res_file(calc, res_path)
        if res_and_out_are_same(res_path.replace('.res.csv', '')):
            os.remove(res_path)
        else:
            failures.append(res_path)
        del calc
    if failures:
        msg = 'Following reforms have res-vs-out differences:\n'
        for ref in failures:
            msg += '{}\n'.format(os.path.basename(ref))
        raise ValueError(msg)
def test_itemded_component_amounts(year, cvname, hcname, puf_fullsample):
    """
    Check that all c04470 components are adjusted to reflect the filing
    unit's standard-vs-itemized-deduction decision.  Check for 2018
    (when current law has no Pease phaseout of itemized deductions and
    already has complete haircuts for Casualty and Miscellaneous deductions)
    and 2017 (when current law has a Pease phaseout of itemized deductions
    and has no haircuts).  The calcfunctions.py code makes no attempt to
    adjust the components for the effects of Pease-like phaseout or any other
    type of limitation on total itemized deductions, so the pre-2018 tests
    here use c21060, instead of c04470, as the itemized deductions total.
    """
    # pylint: disable=too-many-locals
    recs = Records(data=puf_fullsample)
    # policy1 such that everybody itemizes deductions and all are allowed
    policy1 = Policy()
    reform1 = {
        'STD_Aged': {year: [0.0, 0.0, 0.0, 0.0, 0.0]},
        'STD': {year: [0.0, 0.0, 0.0, 0.0, 0.0]}
    }
    policy1.implement_reform(reform1)
    assert not policy1.parameter_errors
    # policy2 such that everybody itemizes deductions but one is disallowed
    policy2 = Policy()
    reform2 = {
        'STD_Aged': {year: [0.0, 0.0, 0.0, 0.0, 0.0]},
        'STD': {year: [0.0, 0.0, 0.0, 0.0, 0.0]},
        hcname: {year: 1.0}
    }
    policy2.implement_reform(reform2)
    assert not policy2.parameter_errors
    # compute tax liability in specified year
    calc1 = Calculator(policy=policy1, records=recs, verbose=False)
    calc1.advance_to_year(year)
    calc1.calc_all()
    calc2 = Calculator(policy=policy2, records=recs, verbose=False)
    calc2.advance_to_year(year)
    calc2.calc_all()
    # confirm that nobody is taking the standard deduction
    assert np.allclose(calc1.array('standard'), 0.)
    assert np.allclose(calc2.array('standard'), 0.)
    # calculate different in total itemized deductions
    if year == 2017:
        # pre-Pease limitation total itemized deductions
        itmded1 = calc1.weighted_total('c21060') * 1e-9
        itmded2 = calc2.weighted_total('c21060') * 1e-9
    elif year == 2018:
        # total itemized deductions (no Pease-like limitation)
        itmded1 = calc1.weighted_total('c04470') * 1e-9
        itmded2 = calc2.weighted_total('c04470') * 1e-9
    else:
        raise ValueError('illegal year value = {}'.format(year))
    difference_in_total_itmded = itmded1 - itmded2
    # calculate itemized component amount
    component_amt = calc1.weighted_total(cvname) * 1e-9
    # confirm that component amount is equal to difference in total deductions
    if year == 2017 and cvname == 'c19700':
        atol = 0.009
    elif year == 2017 and cvname == 'c19200':
        atol = 0.010
    else:
        atol = 0.00001
    if not np.allclose(component_amt, difference_in_total_itmded, atol=atol):
        txt = '\n{}={:.3f}  !=  {:.3f}=difference_in_total_itemized_deductions'
        msg = txt.format(cvname, component_amt, difference_in_total_itmded)
        raise ValueError(msg)
示例#48
0
def test_reform_json_and_output(tests_path):
    """
    Check that each JSON reform file can be converted into a reform dictionary
    that can then be passed to the Policy class implement_reform method that
    generates no parameter_errors.
    Then use each reform to generate static tax results for small set of
    filing units in a single tax_year and compare those results with
    expected results from a text file.
    """
    # pylint: disable=too-many-statements,too-many-locals
    used_dist_stats = ['c00100',  # AGI
                       'c04600',  # personal exemptions
                       'standard',  # standard deduction
                       'c04800',  # regular taxable income
                       'c05800',  # income tax before credits
                       'iitax',  # income tax after credits
                       'payrolltax',  # payroll taxes
                       'aftertax_income']  # aftertax expanded income
    unused_dist_stats = set(DIST_TABLE_COLUMNS) - set(used_dist_stats)
    renamed_columns = {'c00100': 'AGI',
                       'c04600': 'pexempt',
                       'standard': 'stdded',
                       'c04800': 'taxinc',
                       'c05800': 'tax-wo-credits',
                       'iitax': 'inctax',
                       'payrolltax': 'paytax',
                       'aftertax_income': 'ataxinc'}

    # embedded function used only in test_reform_json_and_output
    def write_distribution_table(calc, resfilename):
        """
        Write abbreviated distribution table calc to file with resfilename.
        """
        dist, _ = calc.distribution_tables(None, 'standard_income_bins',
                                           scaling=False)
        for stat in unused_dist_stats:
            del dist[stat]
        dist = dist[used_dist_stats]
        dist.rename(mapper=renamed_columns, axis='columns', inplace=True)
        with open(resfilename, 'w') as resfile:
            dist.to_string(resfile, float_format='%7.0f')

    # embedded function used only in test_reform_json_and_output
    def res_and_out_are_same(base):
        """
        Return True if base.res and base.out file contents are the same;
        return False if base.res and base.out file contents differ.
        """
        with open(base + '.res') as resfile:
            act_res = resfile.read()
        with open(base + '.out') as outfile:
            exp_res = outfile.read()
        # check to see if act_res & exp_res have differences
        return not nonsmall_diffs(act_res.splitlines(True),
                                  exp_res.splitlines(True))
    # specify Records object containing cases data
    tax_year = 2020
    cases_path = os.path.join(tests_path, '..', 'reforms', 'cases.csv')
    cases = Records(data=cases_path,
                    gfactors=None,  # keeps raw data unchanged
                    weights=None,
                    adjust_ratios=None,
                    start_year=tax_year)  # set raw input data year
    # specify list of reform failures
    failures = list()
    # specify current-law-policy Calculator object
    calc1 = Calculator(policy=Policy(), records=cases, verbose=False)
    calc1.advance_to_year(tax_year)
    calc1.calc_all()
    res_path = cases_path.replace('cases.csv', 'clp.res')
    write_distribution_table(calc1, res_path)
    if res_and_out_are_same(res_path.replace('.res', '')):
        os.remove(res_path)
    else:
        failures.append(res_path)
    # read 2017_law.json reform file and specify its parameters dictionary
    pre_tcja_jrf = os.path.join(tests_path, '..', 'reforms', '2017_law.json')
    pre_tcja = Calculator.read_json_param_objects(pre_tcja_jrf, None)
    # check reform file contents and reform results for each reform
    reforms_path = os.path.join(tests_path, '..', 'reforms', '*.json')
    json_reform_files = glob.glob(reforms_path)
    for jrf in json_reform_files:
        # determine reform's baseline by reading contents of jrf
        with open(jrf, 'r') as rfile:
            jrf_text = rfile.read()
            pre_tcja_baseline = 'Reform_Baseline: 2017_law.json' in jrf_text
        # implement the reform relative to its baseline
        reform = Calculator.read_json_param_objects(jrf_text, None)
        pol = Policy()  # current-law policy
        if pre_tcja_baseline:
            pol.implement_reform(pre_tcja['policy'])
        pol.implement_reform(reform['policy'])
        assert not pol.parameter_errors
        calc2 = Calculator(policy=pol, records=cases, verbose=False)
        calc2.advance_to_year(tax_year)
        calc2.calc_all()
        res_path = jrf.replace('.json', '.res')
        write_distribution_table(calc2, res_path)
        if res_and_out_are_same(res_path.replace('.res', '')):
            os.remove(res_path)
        else:
            failures.append(res_path)
    if failures:
        msg = 'Following reforms have res-vs-out differences:\n'
        for ref in failures:
            msg += '{}\n'.format(os.path.basename(ref))
        raise ValueError(msg)
def test_reform_json_and_output(tests_path):
    """
    Check that each JSON reform file can be converted into a reform dictionary
    that can then be passed to the Policy class implement_reform method that
    generates no parameter_errors.
    Then use each reform to generate static tax results for small set of
    filing units in a single tax_year and compare those results with
    expected results from a CSV-formatted file.
    """
    # pylint: disable=too-many-statements,too-many-locals

    # embedded function used only in test_reform_json_and_output
    def write_res_file(calc, resfilename):
        """
        Write calc output to CSV-formatted file with resfilename.
        """
        varlist = [
            'RECID', 'c00100', 'standard', 'c04800', 'iitax', 'payrolltax'
        ]
        # varnames  AGI    STD         TaxInc    ITAX     PTAX
        stats = calc.dataframe(varlist)
        stats['RECID'] = stats['RECID'].astype(int)
        with open(resfilename, 'w') as resfile:
            stats.to_csv(resfile, index=False, float_format='%.2f')

    # embedded function used only in test_reform_json_and_output
    def res_and_out_are_same(base):
        """
        Return True if base.res.csv and base.out.csv file contents are same;
        return False if base.res.csv and base.out.csv file contents differ.
        """
        resdf = pd.read_csv(base + '.res.csv')
        outdf = pd.read_csv(base + '.out.csv')
        diffs = False
        for col in resdf:
            if col in outdf:
                if not np.allclose(resdf[col], outdf[col]):
                    diffs = True
            else:
                diffs = True
        return not diffs

    # specify Records object containing cases data
    tax_year = 2020
    cases_path = os.path.join(tests_path, '..', 'reforms', 'cases.csv')
    cases = Records(data=cases_path,
                    start_year=tax_year,  # set raw input data year
                    gfactors=None,  # keeps raw data unchanged
                    weights=None,
                    adjust_ratios=None)
    # specify list of reform failures
    failures = list()
    # specify current-law-policy Calculator object
    calc = Calculator(policy=Policy(), records=cases, verbose=False)
    calc.advance_to_year(tax_year)
    calc.calc_all()
    res_path = cases_path.replace('cases.csv', 'clp.res.csv')
    write_res_file(calc, res_path)
    if res_and_out_are_same(res_path.replace('.res.csv', '')):
        os.remove(res_path)
    else:
        failures.append(res_path)
    del calc
    # read 2017_law.json reform file and specify its parameters dictionary
    pre_tcja_jrf = os.path.join(tests_path, '..', 'reforms', '2017_law.json')
    pre_tcja = Policy.read_json_reform(pre_tcja_jrf)
    # check reform file contents and reform results for each reform
    reforms_path = os.path.join(tests_path, '..', 'reforms', '*.json')
    json_reform_files = glob.glob(reforms_path)
    for jrf in json_reform_files:
        # determine reform's baseline by reading contents of jrf
        with open(jrf, 'r') as rfile:
            jrf_text = rfile.read()
        pre_tcja_baseline = 'Reform_Baseline: 2017_law.json' in jrf_text
        # implement the reform relative to its baseline
        reform = Policy.read_json_reform(jrf_text)
        pol = Policy()  # current-law policy
        if pre_tcja_baseline:
            pol.implement_reform(pre_tcja)
            assert not pol.parameter_errors
        pol.implement_reform(reform)
        assert not pol.parameter_errors
        calc = Calculator(policy=pol, records=cases, verbose=False)
        calc.advance_to_year(tax_year)
        calc.calc_all()
        res_path = jrf.replace('.json', '.res.csv')
        write_res_file(calc, res_path)
        if res_and_out_are_same(res_path.replace('.res.csv', '')):
            os.remove(res_path)
        else:
            failures.append(res_path)
        del calc
    if failures:
        msg = 'Following reforms have res-vs-out differences:\n'
        for ref in failures:
            msg += '{}\n'.format(os.path.basename(ref))
        raise ValueError(msg)
    reforms_json = json.load(json_file)
num_reforms = len(reforms_json)

# create two calculators, one for baseline and the other for reforms
tax_dta1 = pd.read_csv(PUF_PATH)
records1 = Records(tax_dta1)
policy1 = Policy(start_year=2013)
calc1 = Calculator(records=records1, policy=policy1)

tax_dta2 = pd.read_csv(PUF_PATH)
records2 = Records(tax_dta2)
policy2 = Policy(start_year=2013)
calc2 = Calculator(records=records2, policy=policy2)

# increment both calculators to 2015, when most reforms start
calc1.advance_to_year(2015)
calc2.advance_to_year(2015)

# create a dictionary to save all results
results = {}

# runs one reform a time, each reform for 4 years
# modify the number of reform & number of years as needed
for i in range(1, num_reforms + 1):
    # make two deep copies so the originals could be used again in next loop
    c1 = copy.deepcopy(calc1)
    c2 = copy.deepcopy(calc2)

    # fetch this reform from json and implement in policy object
    this_reform = 'r' + str(i)
    start_year = reforms_json.get(this_reform).get("start_year")
def test_agg(tests_path, cps_fullsample):
    """
    Test current-law aggregate taxes using cps.csv file.
    """
    # pylint: disable=too-many-statements,too-many-locals
    nyrs = 10
    # create a baseline Policy object with current-law policy parameters
    baseline_policy = Policy()
    # create a Records object (rec) containing all cps.csv input records
    recs = Records.cps_constructor(data=cps_fullsample)
    # create a Calculator object using baseline policy and cps records
    calc = Calculator(policy=baseline_policy, records=recs)
    calc.advance_to_year(START_YEAR)
    calc_start_year = calc.current_year
    # create aggregate diagnostic table (adt) as a Pandas DataFrame object
    adt = calc.diagnostic_table(nyrs).round(1)  # column labels are int
    taxes_fullsample = adt.loc["Combined Liability ($b)"]
    # compare actual DataFrame, adt, with the expected DataFrame, edt
    aggres_path = os.path.join(tests_path, 'cpscsv_agg_expect.csv')
    edt = pd.read_csv(aggres_path, index_col=False)  # column labels are str
    edt.drop('Unnamed: 0', axis='columns', inplace=True)
    assert len(adt.columns.values) == len(edt.columns.values)
    diffs = False
    for icol in adt.columns.values:
        if not np.allclose(adt[icol], edt[str(icol)]):
            diffs = True
    if diffs:
        new_filename = '{}{}'.format(aggres_path[:-10], 'actual.csv')
        adt.to_csv(new_filename, float_format='%.1f')
        msg = 'CPSCSV AGG RESULTS DIFFER\n'
        msg += '-------------------------------------------------\n'
        msg += '--- NEW RESULTS IN cpscsv_agg_actual.csv FILE ---\n'
        msg += '--- if new OK, copy cpscsv_agg_actual.csv to  ---\n'
        msg += '---                 cpscsv_agg_expect.csv     ---\n'
        msg += '---            and rerun test.                ---\n'
        msg += '-------------------------------------------------\n'
        raise ValueError(msg)
    # create aggregate diagnostic table using unweighted sub-sample of records
    rn_seed = 180  # to ensure sub-sample is always the same
    subfrac = 0.03  # sub-sample fraction
    subsample = cps_fullsample.sample(frac=subfrac, random_state=rn_seed)
    recs_subsample = Records.cps_constructor(data=subsample)
    calc_subsample = Calculator(policy=baseline_policy, records=recs_subsample)
    calc_subsample.advance_to_year(START_YEAR)
    adt_subsample = calc_subsample.diagnostic_table(nyrs)
    # compare combined tax liability from full and sub samples for each year
    taxes_subsample = adt_subsample.loc["Combined Liability ($b)"]
    msg = ''
    for cyr in range(calc_start_year, calc_start_year + nyrs):
        if cyr == calc_start_year:
            reltol = 0.0141
        else:
            reltol = 0.0105
        if not np.allclose(taxes_subsample[cyr], taxes_fullsample[cyr],
                           atol=0.0, rtol=reltol):
            reldiff = (taxes_subsample[cyr] / taxes_fullsample[cyr]) - 1.
            line1 = '\nCPSCSV AGG SUB-vs-FULL RESULTS DIFFER IN {}'
            line2 = '\n  when subfrac={:.3f}, rtol={:.4f}, seed={}'
            line3 = '\n  with sub={:.3f}, full={:.3f}, rdiff={:.4f}'
            msg += line1.format(cyr)
            msg += line2.format(subfrac, reltol, rn_seed)
            msg += line3.format(taxes_subsample[cyr],
                                taxes_fullsample[cyr],
                                reldiff)
    if msg:
        raise ValueError(msg)
def main(mpc_e17500, mpc_e18400, mpc_e19800, mpc_e20400):
    """
    Highest-level logic of consumption.py script that produces Tax-Calculator
    marginal-tax-rate results running the taxcalc package on this computer.
    """
    # pylint: disable=too-many-locals
    # pylint: disable=too-many-statements
    if not os.path.isfile(PUFCSV_PATH):
        sys.stderr.write('ERROR: file {} does not exist\n'.format(PUFCSV_PATH))
        return 1
    cyr = 2014
    # compute mtr under current-law policy with no consumption response
    recs0 = Records(data=PUFCSV_PATH)
    calc0 = Calculator(policy=Policy(), records=recs0,
                       consumption=None, verbose=False)
    calc0.advance_to_year(cyr)
    wghts = calc0.records.s006
    (mtr0_fica, mtr0_itax, _) = calc0.mtr(income_type_str='e00200p',
                                          wrt_full_compensation=False)
    # compute mtr under current-law policy with specified consumption response
    consump = Consumption()
    consump_mpc = {cyr: {'_MPC_e17500': [mpc_e17500],
                         '_MPC_e18400': [mpc_e18400],
                         '_MPC_e19800': [mpc_e19800],
                         '_MPC_e20400': [mpc_e20400]}}
    consump.update_consumption(consump_mpc)
    recs1 = Records(data=PUFCSV_PATH)
    calc1 = Calculator(policy=Policy(), records=recs1,
                       consumption=consump, verbose=False)
    calc1.advance_to_year(cyr)
    assert calc1.consumption.current_year == cyr
    (mtr1_fica, mtr1_itax, _) = calc1.mtr(income_type_str='e00200p',
                                          wrt_full_compensation=False)
    # compare unweighted mtr results with and without consumption response
    epsilon = 1.0e-6  # this would represent a mtr of 0.0001 percent
    assert np.allclose(mtr1_fica, mtr0_fica, atol=epsilon, rtol=0.0)
    mtr_raw_diff = mtr1_itax - mtr0_itax
    mtr1_itax = np.where(np.logical_and(mtr_raw_diff > 0.0,
                                        mtr_raw_diff < epsilon),
                         mtr0_itax, mtr1_itax)  # zero out small positive diffs
    num_total = mtr1_itax.size
    num_increases = np.sum(np.greater(mtr1_itax, mtr0_itax))
    num_decreases = np.sum(np.less(mtr1_itax, mtr0_itax))
    num_nochanges = num_total - num_increases - num_decreases
    res = 'unweighted_num_of_mtr_{}_with_consump_response= {:6d} ({:5.1f}%)\n'
    sys.stdout.write(res.format('increases', num_increases,
                                (100.0 * num_increases) / num_total))
    sys.stdout.write(res.format('decreases', num_decreases,
                                (100.0 * num_decreases) / num_total))
    sys.stdout.write(res.format('nochanges', num_nochanges,
                                (100.0 * num_nochanges) / num_total))
    sys.stdout.write(res.format('all_units', num_total, 100.0))
    # compute average size of decreases in mtr_itax
    mtr_pre = mtr0_itax[mtr1_itax < mtr0_itax]
    assert mtr_pre.size == num_decreases
    avg_pre = np.mean(mtr_pre)
    res = 'unweighted_abs_mean_no_c_resp(for_decreases)mtr_itax= {:.4f}\n'
    sys.stdout.write(res.format(avg_pre))
    mtr_diff = mtr1_itax - mtr0_itax
    mtr_neg = mtr_diff[mtr_diff < 0.0]
    assert mtr_neg.size == num_decreases
    avg_neg = np.mean(mtr_neg)
    assert avg_neg < 0.0
    res = 'unweighted_abs_mean_change(for_decreases)in_mtr_itax= {:.4f}\n'
    sys.stdout.write(res.format(-avg_neg))
    res = '   ratio_of_abs_change_in_mtr_itax_and_no_c_resp_mtr_itax= {:.3f}\n'
    sys.stdout.write(res.format(-avg_neg / avg_pre))
    # compare weighted mtr results with and without consumption response
    wghts_pre = wghts[mtr1_itax < mtr0_itax]
    assert wghts_pre.size == num_decreases
    res = 'weighted_percent_of_units_with_mtr_decrease= {:.1f}%\n'
    frac = wghts_pre.sum() / wghts.sum()
    sys.stdout.write(res.format(100.0 * frac))
    res = '   ratio_of_abs_change_in_mtr_itax_and_no_c_resp_mtr_itax= {:.3f}\n'
    w_avg_pre = np.mean((mtr_pre * wghts_pre).sum() / wghts_pre.sum())
    w_avg_neg = np.mean((mtr_neg * wghts_pre).sum() / wghts_pre.sum())
    sys.stdout.write(res.format(-w_avg_neg / w_avg_pre))
    # return no-error exit code
    return 0
def test_compatible_data(cps_subsample, puf_subsample,
                         allparams, reform_xx,
                         tc_objs, allparams_batch):
    """
    Test that the compatible_data attribute in policy_current_law.json
    is accurate by implementing the min and max values of each parameter
    as reforms and ensuring that revenue differs from baseline when for
    at least one of these reforms when using datasets marked compatible
    and does not differ when using datasets marked as incompatible.
    """
    # pylint: disable=too-many-arguments,too-many-locals
    # pylint: disable=too-many-statements,too-many-branches

    # Check NPARAMS value
    assert NPARAMS == len(allparams)

    # Get taxcalc objects from tc_objs fixture
    rec_xx, c_xx, puftest = tc_objs

    # These parameters are exempt because they are not active under
    # current law and activating them would deactivate other parameters,
    # or if it is difficult to devise a test for them.
    exempt_from_testing = [
        'CG_ec', 'CG_reinvest_ec_rt',
        'II_prt', 'ID_prt', 'ID_crt',
        'CR_SchR_hc', 'ACTC_ChildNum'
    ]

    # Loop through the parameters in allparams_batch
    errmsg = 'ERROR: {} {}\n'
    errors = ''
    for pname in allparams_batch:
        param = allparams_batch[pname]
        max_listed = param['valid_values']['max']
        # handle links to other params or self
        if isinstance(max_listed, str):
            if isinstance(allparams[max_listed]['value'][0], list):
                max_val = allparams[max_listed]['value'][0]
            else:
                max_val = float(allparams[max_listed]['value'][0])
        else:
            if isinstance(param['value'][0], list):
                max_val = [max_listed] * len(param['value'][0])
            else:
                max_val = max_listed
        min_listed = param['valid_values']['min']
        if isinstance(min_listed, str):
            if isinstance(allparams[min_listed]['value'][0], list):
                min_val = allparams[min_listed]['value'][0]
            else:
                min_val = float(allparams[min_listed]['value'][0])
        else:
            if isinstance(param['value'][0], list):
                min_val = [min_listed] * len(param['value'][0])
            else:
                min_val = min_listed
        # create reform dictionaries
        max_reform = copy.deepcopy(reform_xx)
        min_reform = copy.deepcopy(reform_xx)
        max_reform[XX_YEAR][str(pname)] = [max_val]
        min_reform[XX_YEAR][str(pname)] = [min_val]
        # assess whether max reform changes results
        if puftest:
            rec_yy = Records(data=puf_subsample)
        else:
            rec_yy = Records.cps_constructor(data=cps_subsample)
        p_yy = Policy()
        p_yy.implement_reform(max_reform, raise_errors=False)
        c_yy = Calculator(policy=p_yy, records=rec_yy, verbose=False)
        c_yy.advance_to_year(TEST_YEAR)
        c_yy.calc_all()
        if pname.startswith('BEN') and pname.endswith('_repeal'):
            max_reform_change = (
                c_yy.weighted_total('benefit_cost_total') -
                c_xx.weighted_total('benefit_cost_total')
            )
        else:
            max_reform_change = (
                c_yy.weighted_total('combined') -
                c_xx.weighted_total('combined')
            )
        min_reform_change = 0
        # assess whether min reform changes results, if max reform did not
        if max_reform_change == 0:
            p_yy = Policy()
            p_yy.implement_reform(min_reform, raise_errors=False)
            c_yy = Calculator(policy=p_yy, records=rec_xx)
            c_yy.advance_to_year(TEST_YEAR)
            c_yy.calc_all()
            if pname.startswith('BEN') and pname.endswith('_repeal'):
                min_reform_change = (
                    c_yy.weighted_total('benefit_cost_total') -
                    c_xx.weighted_total('benefit_cost_total')
                )
            else:
                min_reform_change = (
                    c_yy.weighted_total('combined') -
                    c_xx.weighted_total('combined')
                )
            if min_reform_change == 0 and pname not in exempt_from_testing:
                if puftest:
                    if param['compatible_data']['puf'] is True:
                        errors += errmsg.format(pname, 'is not True for puf')
                else:
                    if param['compatible_data']['cps'] is True:
                        errors += errmsg.format(pname, 'is not True for cps')
        if max_reform_change != 0 or min_reform_change != 0:
            if puftest:
                if param['compatible_data']['puf'] is False:
                    errors += errmsg.format(pname, 'is not False for puf')
            else:
                if param['compatible_data']['cps'] is False:
                    errors += errmsg.format(pname, 'is not False for cps')
    # test failure if any errors
    if errors:
        print(errors)
        assert 'compatible_data' == 'invalid'