Пример #1
0
def test_make_Calculator_with_multiyear_reform():
    # create a Policy object and apply a policy reform
    policy3 = Policy()
    reform3 = {2015: {}}
    reform3[2015]['_STD_Aged'] = [[1600, 1300, 1600, 1300, 1600, 1300]]
    reform3[2015]['_II_em'] = [5000, 6000]  # reform values for 2015 and 2016
    reform3[2015]['_II_em_cpi'] = False
    policy3.implement_reform(reform3)
    # create a Calculator object using this policy-reform
    puf = Records(data=TAXDATA, weights=WEIGHTS, start_year=2009)
    calc3 = Calculator(policy=policy3, records=puf)
    # check that Policy object embedded in Calculator object is correct
    assert calc3.current_year == 2013
    assert calc3.policy.II_em == 3900
    assert calc3.policy.num_years == Policy.DEFAULT_NUM_YEARS
    exp_II_em = [3900, 3950, 5000] + [6000] * (Policy.DEFAULT_NUM_YEARS - 3)
    assert_allclose(calc3.policy._II_em,
                    np.array(exp_II_em),
                    atol=0.01,
                    rtol=0.0)
    calc3.increment_year()
    calc3.increment_year()
    assert calc3.current_year == 2015
    assert_allclose(calc3.policy.STD_Aged,
                    np.array([1600, 1300, 1600, 1300, 1600, 1300]),
                    atol=0.01,
                    rtol=0.0)
Пример #2
0
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)
Пример #3
0
def test_make_Calculator_with_reform_after_start_year():
    # create Policy object using custom indexing rates
    irates = {2013: 0.01, 2014: 0.01, 2015: 0.02, 2016: 0.01, 2017: 0.03}
    parm = Policy(start_year=2013, num_years=len(irates),
                  inflation_rates=irates)
    # specify reform in 2015, which is two years after Policy start_year
    reform = {2015: {}, 2016: {}}
    reform[2015]['_STD_Aged'] = [[1600, 1300, 1600, 1300, 1600, 1300]]
    reform[2015]['_II_em'] = [5000]
    reform[2016]['_II_em'] = [6000]
    reform[2016]['_II_em_cpi'] = False
    parm.implement_reform(reform)
    recs = Records(data=TAX_DTA, weights=WEIGHTS, start_year=2009)
    calc = Calculator(policy=parm, records=recs)
    # compare actual and expected parameter values over all years
    exp_STD_Aged = np.array([[1500, 1200, 1200, 1500, 1500, 1200],
                             [1550, 1200, 1200, 1550, 1550, 1200],
                             [1600, 1300, 1600, 1300, 1600, 1300],
                             [1632, 1326, 1632, 1326, 1632, 1326],
                             [1648, 1339, 1648, 1339, 1648, 1339]])
    exp_II_em = np.array([3900, 3950, 5000, 6000, 6000])
    assert_array_equal(calc.policy._STD_Aged, exp_STD_Aged)
    assert_array_equal(calc.policy._II_em, exp_II_em)
    # compare actual and expected values for 2015
    calc.increment_year()
    calc.increment_year()
    assert calc.current_year == 2015
    exp_2015_II_em = 5000
    assert_array_equal(calc.policy.II_em, exp_2015_II_em)
    exp_2015_STD_Aged = np.array([1600, 1300, 1600, 1300, 1600, 1300])
    assert_array_equal(calc.policy.STD_Aged, exp_2015_STD_Aged)
Пример #4
0
def test_proportional_change_in_gdp(cps_subsample):
    """
    Test correct and incorrect calls to proportional_change_in_gdp function.
    """
    rec = Records.cps_constructor(data=cps_subsample, no_benefits=True)
    pol = Policy()
    calc1 = Calculator(policy=pol, records=rec)
    reform = {2015: {'_II_em': [0.0]}}  # reform increases taxes and MTRs
    pol.implement_reform(reform)
    calc2 = Calculator(policy=pol, records=rec)
    assert calc1.current_year == calc2.current_year
    assert calc1.current_year == 2014  # because using CPS data
    gdpc = proportional_change_in_gdp(2014, calc1, calc2, elasticity=0.36)
    assert gdpc == 0.0  # no effect for first data year
    gdpc = proportional_change_in_gdp(2015, calc1, calc2, elasticity=0.36)
    assert gdpc == 0.0  # no effect in first year of reform
    calc1.increment_year()
    calc2.increment_year()
    assert calc1.current_year == 2015
    gdp_pchg = 100.0 * proportional_change_in_gdp(
        2016, calc1, calc2, elasticity=0.36)
    exp_pchg = -0.54  # higher MTRs imply negative expected GDP percent change
    abs_diff_pchg = abs(gdp_pchg - exp_pchg)
    if abs_diff_pchg > 0.01:
        msg = 'year,gdp_pchg,exp_pchg= {} {:.3f} {:.3f}'.format(
            2016, gdp_pchg, exp_pchg)
        assert msg == 'ERROR: gdp_pchg not close to exp_pchg'
    # skip calcN.increment_year to 2016, so calcN.current_year is still 2015
    with pytest.raises(ValueError):
        proportional_change_in_gdp(2017, calc1, calc2, elasticity=0.36)
Пример #5
0
def test_make_Calculator_with_reform_after_start_year():
    # create Policy object using custom indexing rates
    irates = {2013: 0.01, 2014: 0.01, 2015: 0.02, 2016: 0.01, 2017: 0.03}
    parm = Policy(start_year=2013,
                  num_years=len(irates),
                  inflation_rates=irates)
    # specify reform in 2015, which is two years after Policy start_year
    reform = {2015: {}, 2016: {}}
    reform[2015]['_STD_Aged'] = [[1600, 1300, 1600, 1300, 1600, 1300]]
    reform[2015]['_II_em'] = [5000]
    reform[2016]['_II_em'] = [6000]
    reform[2016]['_II_em_cpi'] = False
    parm.implement_reform(reform)
    recs = Records(data=TAXDATA, weights=WEIGHTS, start_year=2009)
    calc = Calculator(policy=parm, records=recs)
    # compare actual and expected parameter values over all years
    exp_STD_Aged = np.array([[1500, 1200, 1200, 1500, 1500, 1200],
                             [1550, 1200, 1200, 1550, 1550, 1200],
                             [1600, 1300, 1600, 1300, 1600, 1300],
                             [1632, 1326, 1632, 1326, 1632, 1326],
                             [1648, 1339, 1648, 1339, 1648, 1339]])
    exp_II_em = np.array([3900, 3950, 5000, 6000, 6000])
    assert_allclose(calc.policy._STD_Aged, exp_STD_Aged, atol=0.5, rtol=0.0)
    assert_allclose(calc.policy._II_em, exp_II_em, atol=0.001, rtol=0.0)
    # compare actual and expected values for 2015
    calc.increment_year()
    calc.increment_year()
    assert calc.current_year == 2015
    exp_2015_II_em = 5000
    assert_allclose(calc.policy.II_em, exp_2015_II_em, atol=0.0, rtol=0.0)
    exp_2015_STD_Aged = np.array([1600, 1300, 1600, 1300, 1600, 1300])
    assert_allclose(calc.policy.STD_Aged,
                    exp_2015_STD_Aged,
                    atol=0.0,
                    rtol=0.0)
def test_make_calculator_with_multiyear_reform(cps_subsample):
    """
    Test Calculator class ctor with multi-year policy reform.
    """
    rec = Records.cps_constructor(data=cps_subsample)
    year = rec.current_year
    # create a Policy object and apply a policy reform
    pol = Policy()
    reform = {
        'II_em': {
            2015: 5000,
            2016: 6000
        },
        'II_em-indexed': {
            2015: False
        },
        'STD_Aged': {
            2016: [1600, 1300, 1600, 1300, 1600]
        }
    }
    pol.implement_reform(reform)
    # create a Calculator object using this policy-reform
    calc = Calculator(policy=pol, records=rec)
    # check that Policy object embedded in Calculator object is correct
    assert pol.num_years == Policy.DEFAULT_NUM_YEARS
    assert calc.current_year == year
    assert calc.policy_param('II_em') == 3950
    exp_II_em = [3900, 3950, 5000] + [6000] * (Policy.DEFAULT_NUM_YEARS - 3)
    assert np.allclose(calc.policy_param('_II_em'), np.array(exp_II_em))
    calc.increment_year()
    calc.increment_year()
    assert calc.current_year == 2016
    assert np.allclose(calc.policy_param('STD_Aged'),
                       np.array([1600, 1300, 1600, 1300, 1600]))
Пример #7
0
def test_make_Calculator_with_reform_after_start_year(records_2009):
    # create Policy object using custom indexing rates
    irates = {2013: 0.01, 2014: 0.01, 2015: 0.02, 2016: 0.01, 2017: 0.03}
    parm = Policy(start_year=2013, num_years=len(irates),
                  inflation_rates=irates)
    # specify reform in 2015, which is two years after Policy start_year
    reform = {2015: {}, 2016: {}}
    reform[2015]['_STD_Aged'] = [[1600, 1300, 1600, 1300, 1600, 1300]]
    reform[2015]['_II_em'] = [5000]
    reform[2016]['_II_em'] = [6000]
    reform[2016]['_II_em_cpi'] = False
    parm.implement_reform(reform)
    calc = Calculator(policy=parm, records=records_2009)
    # compare actual and expected parameter values over all years
    assert np.allclose(calc.policy._STD_Aged,
                       np.array([[1500, 1200, 1200, 1500, 1500, 1200],
                                 [1550, 1200, 1200, 1550, 1550, 1200],
                                 [1600, 1300, 1600, 1300, 1600, 1300],
                                 [1632, 1326, 1632, 1326, 1632, 1326],
                                 [1648, 1339, 1648, 1339, 1648, 1339]]),
                       atol=0.5, rtol=0.0)  # handles rounding to dollars
    assert np.allclose(calc.policy._II_em,
                       np.array([3900, 3950, 5000, 6000, 6000]))
    # compare actual and expected values for 2015
    calc.increment_year()
    calc.increment_year()
    assert calc.current_year == 2015
    assert np.allclose(calc.policy.II_em, 5000)
    assert np.allclose(calc.policy.STD_Aged,
                       np.array([1600, 1300, 1600, 1300, 1600, 1300]))
Пример #8
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)
def test_make_Calculator_with_reform_after_start_year(records_2009):
    # create Policy object using custom indexing rates
    irates = {2013: 0.01, 2014: 0.01, 2015: 0.02, 2016: 0.01, 2017: 0.03}
    parm = Policy(start_year=2013,
                  num_years=len(irates),
                  inflation_rates=irates)
    # specify reform in 2015, which is two years after Policy start_year
    reform = {2015: {}, 2016: {}}
    reform[2015]['_STD_Aged'] = [[1600, 1300, 1600, 1300, 1600, 1300]]
    reform[2015]['_II_em'] = [5000]
    reform[2016]['_II_em'] = [6000]
    reform[2016]['_II_em_cpi'] = False
    parm.implement_reform(reform)
    calc = Calculator(policy=parm, records=records_2009)
    # compare actual and expected parameter values over all years
    assert np.allclose(calc.policy._STD_Aged,
                       np.array([[1500, 1200, 1200, 1500, 1500, 1200],
                                 [1550, 1200, 1200, 1550, 1550, 1200],
                                 [1600, 1300, 1600, 1300, 1600, 1300],
                                 [1632, 1326, 1632, 1326, 1632, 1326],
                                 [1648, 1339, 1648, 1339, 1648, 1339]]),
                       atol=0.5,
                       rtol=0.0)  # handles rounding to dollars
    assert np.allclose(calc.policy._II_em,
                       np.array([3900, 3950, 5000, 6000, 6000]))
    # compare actual and expected values for 2015
    calc.increment_year()
    calc.increment_year()
    assert calc.current_year == 2015
    assert np.allclose(calc.policy.II_em, 5000)
    assert np.allclose(calc.policy.STD_Aged,
                       np.array([1600, 1300, 1600, 1300, 1600, 1300]))
Пример #10
0
def test_make_calculator_with_multiyear_reform(cps_subsample):
    """
    Test Calculator class ctor with multi-year policy reform.
    """
    rec = Records.cps_constructor(data=cps_subsample)
    year = rec.current_year
    # create a Policy object and apply a policy reform
    pol = Policy()
    reform = {2015: {}, 2016: {}}
    reform[2015]['_II_em'] = [5000, 6000]  # reform values for 2015 and 2016
    reform[2015]['_II_em_cpi'] = False
    reform[2016]['_STD_Aged'] = [[1600, 1300, 1600, 1300, 1600]]
    pol.implement_reform(reform)
    # create a Calculator object using this policy-reform
    calc = Calculator(policy=pol, records=rec)
    # check that Policy object embedded in Calculator object is correct
    assert pol.num_years == Policy.DEFAULT_NUM_YEARS
    assert calc.current_year == year
    assert calc.policy_param('II_em') == 3950
    exp_II_em = [3900, 3950, 5000] + [6000] * (Policy.DEFAULT_NUM_YEARS - 3)
    assert np.allclose(calc.policy_param('_II_em'),
                       np.array(exp_II_em))
    calc.increment_year()
    calc.increment_year()
    assert calc.current_year == 2016
    assert np.allclose(calc.policy_param('STD_Aged'),
                       np.array([1600, 1300, 1600, 1300, 1600]))
def get_calculator(baseline,
                   calculator_start_year,
                   reform=None,
                   data='cps',
                   weights=None,
                   records_start_year=RECORDS_START_YEAR):
    '''
    This function creates the tax calculator object for the microsim

    Args:
        baseline: boolean, True if baseline tax policy
        calculator_start_year: integer, first year of budget window
        reform: dictionary, reform parameters
        data: DataFrame, DataFrame for Records object (opt.)
        weights: DataFrame, weights DataFrame for Records object (opt.)
        records_start_year: integer, the start year for the data and
                            weights dfs

    Returns:
        calc1: Tax Calculator Calculator object with a current_year
            equal to calculator_start_year
    '''
    # create a calculator
    policy1 = Policy()
    if data is not None and "cps" in data:
        records1 = Records.cps_constructor()
        # impute short and long term capital gains if using CPS data
        # in 2012 SOI data 6.587% of CG as short-term gains
        records1.p22250 = 0.06587 * records1.e01100
        records1.p23250 = (1 - 0.06587) * records1.e01100
        # set total capital gains to zero
        records1.e01100 = np.zeros(records1.e01100.shape[0])
    elif data is not None:
        records1 = Records(data=data,
                           weights=weights,
                           start_year=records_start_year)
    else:
        records1 = Records()

    if baseline:
        # Should not be a reform if baseline is True
        assert not reform

    if not baseline:
        policy1.implement_reform(reform)

    # the default set up increments year to 2013
    calc1 = Calculator(records=records1, policy=policy1)

    # this increment_year function extrapolates all PUF variables to
    # the next year so this step takes the calculator to the start_year
    if calculator_start_year > TC_LAST_YEAR:
        raise RuntimeError("Start year is beyond data extrapolation.")
    while calc1.current_year < calculator_start_year:
        calc1.increment_year()

    return calc1
Пример #12
0
def test_dropq_with_full_puf(puf_path):
    # specify usermods dictionary in code
    fyr = 2016
    reforms = dict()
    reforms['_II_rt4'] = [0.39, 0.40, 0.41]
    reforms['_PT_rt4'] = [0.39, 0.40, 0.41]
    reforms['_II_rt3'] = [0.31, 0.32, 0.33]
    reforms['_PT_rt3'] = [0.31, 0.32, 0.33]
    usermods = dict()
    usermods['policy'] = {fyr: reforms}
    usermods['consumption'] = {}
    usermods['behavior'] = {}
    usermods['growdiff_baseline'] = {}
    usermods['growdiff_response'] = {}
    usermods['gdp_elasticity'] = {}
    # create a Policy object (clp) containing current-law policy parameters
    clp = Policy()
    clp.implement_reform(usermods['policy'])
    # create a Records object (rec) containing all puf.csv input records
    rec = Records(data=puf_path)
    # create a Calculator object using clp policy and puf records
    calc = Calculator(policy=clp, records=rec)
    calc.increment_year()
    calc.increment_year()
    calc.increment_year()
    # create aggregate diagnostic table (adt) as a Pandas DataFrame object
    nyrs = 2
    adt = multiyear_diagnostic_table(calc, nyrs)
    taxes_fullsample = adt.loc["Combined Liability ($b)"]
    assert taxes_fullsample is not None
    # create a Public Use File object
    tax_data = pd.read_csv(puf_path)
    # call dropq.run_model
    (mY_dec, _, _, _, _, _, _, _, _, _,
     fiscal_tots) = dropq.run_model(tax_data,
                                    start_year=fyr,
                                    user_mods=usermods,
                                    return_json=False,
                                    num_years=nyrs)
    fulls_reform_revenue = taxes_fullsample.loc[fyr]
    dropq_reform_revenue = mY_dec['_combined_dec_0'].loc['sums']
    dropq_reform_revenue *= 1e-9  # convert to billions of dollars
    diff = abs(fulls_reform_revenue - dropq_reform_revenue)
    # assert that dropq revenue is similar to the fullsample calculation
    assert diff / fulls_reform_revenue < 0.01
    # assert that Reform - Baseline = Reported Delta
    delta_yr0 = fiscal_tots[0]
    baseline_yr0 = fiscal_tots[1]
    reform_yr0 = fiscal_tots[2]
    diff_yr0 = (reform_yr0.loc['combined_tax'] -
                baseline_yr0.loc['combined_tax']).values
    delta_yr0 = delta_yr0.loc['combined_tax'].values
    npt.assert_allclose(diff_yr0, delta_yr0)
Пример #13
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
Пример #14
0
def test_full_dropq_puf(puf_path):

    myvars = {}
    myvars['_II_rt4'] = [0.39, 0.40, 0.41]
    myvars['_PT_rt4'] = [0.39, 0.40, 0.41]
    myvars['_II_rt3'] = [0.31, 0.32, 0.33]
    myvars['_PT_rt3'] = [0.31, 0.32, 0.33]
    first = 2016
    user_mods = {first: myvars}

    nyrs = 2
    # create a Policy object (clp) containing current-law policy parameters
    clp = Policy()
    clp.implement_reform(user_mods)
    # create a Records object (rec) containing all puf.csv input records
    rec = Records(data=puf_path)
    # create a Calculator object using clp policy and puf records
    calc = Calculator(policy=clp, records=rec)
    calc.increment_year()
    calc.increment_year()
    calc.increment_year()
    # create aggregate diagnostic table (adt) as a Pandas DataFrame object
    adt = multiyear_diagnostic_table(calc, nyrs)
    taxes_fullsample = adt.loc["Combined Liability ($b)"]

    assert taxes_fullsample is not None

    # Create a Public Use File object
    tax_data = pd.read_csv(puf_path)

    (mY_dec, mX_dec, df_dec, pdf_dec, cdf_dec, mY_bin, mX_bin, df_bin,
        pdf_bin, cdf_bin, fiscal_tots) = dropq.run_models(tax_data,
                                                          start_year=first,
                                                          user_mods=user_mods,
                                                          return_json=False,
                                                          num_years=2)

    pure_reform_revenue = taxes_fullsample.loc[first]
    dropq_reform_revenue = mY_dec['_combined_dec_0'].loc['sums']
    dropq_reform_revenue /= 1e9  # Round to billions of dollars
    diff = abs(pure_reform_revenue - dropq_reform_revenue)
    # Assert that dropq revenue is similar to the "pure" calculation
    assert diff / dropq_reform_revenue < 0.02

    # Assert that Reform - Baseline = Reported Delta
    delta_yr0 = fiscal_tots[0]
    baseline_yr0 = fiscal_tots[1]
    reform_yr0 = fiscal_tots[2]
    diff_yr0 = (reform_yr0.loc['combined_tax'] -
                baseline_yr0.loc['combined_tax']).values
    delta_yr0 = delta_yr0.loc['combined_tax'].values
    npt.assert_array_almost_equal(diff_yr0, delta_yr0, decimal=3)
Пример #15
0
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)
Пример #16
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
Пример #17
0
def test_factor_adjustment(records_2009):
    calc = Calculator(policy=Policy(), records=records_2009, growth=Growth())
    ATXPY_pre = calc.records.BF.ATXPY[2015]
    AGDPN_pre = calc.records.BF.AGDPN[2015]
    # specify _factor_adjustment
    fa2015 = 0.01
    factor_adj = {2015: {'_factor_adjustment': [fa2015]}}
    calc.growth.update_economic_growth(factor_adj)
    assert calc.current_year == 2013
    calc.increment_year()
    calc.increment_year()
    assert calc.current_year == 2015
    assert calc.records.BF.AGDPN[2015] == AGDPN_pre + fa2015
    assert calc.records.BF.ATXPY[2015] == ATXPY_pre + fa2015
def test_puf_var_stats(tests_path, puf_fullsample):
    """
    Main logic of test.
    """
    # create a baseline Policy object containing 2017_law.json parameters
    pre_tcja_jrf = os.path.join(tests_path, '..', 'reforms', '2017_law.json')
    pre_tcja = Calculator.read_json_param_objects(pre_tcja_jrf, None)
    baseline_policy = Policy()
    baseline_policy.implement_reform(pre_tcja['policy'])
    # create a Calculator object using baseline_policy and full puf.csv sample
    rec = Records(data=puf_fullsample)
    calc = Calculator(policy=baseline_policy, records=rec, verbose=False)
    # create base tables
    table_mean = create_base_table(tests_path)
    table_corr = copy.deepcopy(table_mean)
    del table_corr['description']
    # add statistics to tables
    year_headers = ['description']
    for year in range(Policy.JSON_START_YEAR, Policy.LAST_BUDGET_YEAR + 1):
        assert year == calc.policy_current_year()
        year_headers.append(str(year))
        calc.calc_all()
        calculate_mean_stats(calc, table_mean, year)
        if year == 2016:
            calculate_corr_stats(calc, table_corr)
        if year < Policy.LAST_BUDGET_YEAR:
            calc.increment_year()
    # write tables to new CSV files
    mean_path = os.path.join(tests_path, MEAN_FILENAME + '-new')
    table_mean.sort_index(inplace=True)
    table_mean.to_csv(mean_path, header=year_headers, float_format='%8.0f')
    corr_path = os.path.join(tests_path, CORR_FILENAME + '-new')
    table_corr.sort_index(inplace=True)
    table_corr.to_csv(corr_path, float_format='%8.2f',
                      columns=table_corr.index)
    # compare new and old CSV files for nonsmall differences
    if sys.version_info.major == 2:
        # tighter tests for Python 2.7
        mean_msg = differences(mean_path, mean_path[:-4],
                               'MEAN', small=0.0)
        corr_msg = differences(corr_path, corr_path[:-4],
                               'CORR', small=0.0)
    else:
        # looser tests for Python 3.6
        mean_msg = differences(mean_path, mean_path[:-4],
                               'MEAN', small=1.0)
        corr_msg = differences(corr_path, corr_path[:-4],
                               'CORR', small=0.01)
    if mean_msg or corr_msg:
        raise ValueError(mean_msg + corr_msg)
Пример #19
0
def test_factor_adjustment(records_2009):
    calc = Calculator(policy=Policy(), records=records_2009, growth=Growth())
    ATXPY_pre = calc.records.BF.ATXPY[2015]
    AGDPN_pre = calc.records.BF.AGDPN[2015]
    # specify _factor_adjustment
    fa2015 = 0.01
    factor_adj = {2015: {'_factor_adjustment': [fa2015]}}
    calc.growth.update_economic_growth(factor_adj)
    assert calc.current_year == 2013
    calc.increment_year()
    calc.increment_year()
    assert calc.current_year == 2015
    assert calc.records.BF.AGDPN[2015] == AGDPN_pre + fa2015
    assert calc.records.BF.ATXPY[2015] == ATXPY_pre + fa2015
Пример #20
0
def test_factor_adjustment():
    recs = Records(data=TAXDATA, weights=WEIGHTS, start_year=2009)
    calc = Calculator(policy=Policy(), records=recs, growth=Growth())
    ATXPY_pre = calc.records.BF.ATXPY[2015]
    AGDPN_pre = calc.records.BF.AGDPN[2015]
    # specify _factor_adjustment
    fa2015 = 0.01
    factor_adj = {2015: {'_factor_adjustment': [fa2015]}}
    calc.growth.update_economic_growth(factor_adj)
    assert calc.current_year == 2013
    calc.increment_year()
    calc.increment_year()
    assert calc.current_year == 2015
    assert calc.records.BF.AGDPN[2015] == AGDPN_pre + fa2015
    assert calc.records.BF.ATXPY[2015] == ATXPY_pre + fa2015
Пример #21
0
def test_full_dropq_puf(puf_path):

    myvars = {}
    myvars['_II_rt4'] = [0.39, 0.40, 0.41]
    myvars['_PT_rt4'] = [0.39, 0.40, 0.41]
    myvars['_II_rt3'] = [0.31, 0.32, 0.33]
    myvars['_PT_rt3'] = [0.31, 0.32, 0.33]
    first = 2016
    user_mods = {first: myvars}

    nyrs = 2

    # Create a Policy object (clp) containing current-law policy parameters
    clp = Policy()
    clp.implement_reform(user_mods)
    # Create a Records object (rec) containing all puf.csv input records
    rec = Records(data=puf_path)
    # Create a Calculator object using clp policy and puf records
    calc = Calculator(policy=clp, records=rec)
    calc.increment_year()
    calc.increment_year()
    calc.increment_year()
    # Create aggregate diagnostic table (adt) as a Pandas DataFrame object
    adt = multiyear_diagnostic_table(calc, nyrs)
    taxes_fullsample = adt.loc["Combined Liability ($b)"]
    assert taxes_fullsample is not None
    # Create a Public Use File object
    tax_data = pd.read_csv(puf_path)
    (mY_dec, _, _, _, _, _, _, _,
     _, _, fiscal_tots) = dropq.run_models(tax_data,
                                           start_year=first,
                                           user_mods=user_mods,
                                           return_json=False,
                                           num_years=nyrs)
    pure_reform_revenue = taxes_fullsample.loc[first]
    dropq_reform_revenue = mY_dec['_combined_dec_0'].loc['sums']
    dropq_reform_revenue *= 1e-9  # convert to billions of dollars
    diff = abs(pure_reform_revenue - dropq_reform_revenue)
    # Assert that dropq revenue is similar to the "pure" calculation
    assert diff / pure_reform_revenue < 0.01
    # Assert that Reform - Baseline = Reported Delta
    delta_yr0 = fiscal_tots[0]
    baseline_yr0 = fiscal_tots[1]
    reform_yr0 = fiscal_tots[2]
    diff_yr0 = (reform_yr0.loc['combined_tax'] -
                baseline_yr0.loc['combined_tax']).values
    delta_yr0 = delta_yr0.loc['combined_tax'].values
    npt.assert_allclose(diff_yr0, delta_yr0)
Пример #22
0
def test_with_pufcsv(puf_fullsample):
    # specify usermods dictionary in code
    start_year = 2017
    reform_year = start_year
    analysis_year = 2026
    year_n = analysis_year - start_year
    reform = {'_FICA_ss_trt': [0.2]}
    usermods = dict()
    usermods['policy'] = {reform_year: reform}
    usermods['consumption'] = {}
    usermods['behavior'] = {}
    usermods['growdiff_baseline'] = {}
    usermods['growdiff_response'] = {}
    usermods['gdp_elasticity'] = {}
    seed = random_seed(usermods)
    assert seed == 1574318062
    # create a Policy object (pol) containing reform policy parameters
    pol = Policy()
    pol.implement_reform(usermods['policy'])
    # create a Records object (rec) containing all puf.csv input records
    rec = Records(data=puf_fullsample)
    # create a Calculator object using clp policy and puf records
    calc = Calculator(policy=pol, records=rec)
    while calc.current_year < analysis_year:
        calc.increment_year()
    # create aggregate diagnostic table (adt) as a Pandas DataFrame object
    adt = multiyear_diagnostic_table(calc, 1)
    taxes_fullsample = adt.loc["Combined Liability ($b)"]
    assert taxes_fullsample is not None
    fulls_reform_revenue = float(taxes_fullsample.loc[analysis_year])
    # create a Public Use File object
    tax_data = puf_fullsample
    # call run_nth_year_tax_calc_model function
    resdict = run_nth_year_tax_calc_model(year_n,
                                          start_year,
                                          tax_data,
                                          usermods,
                                          return_json=True)
    total = resdict['aggr_2']
    dropq_reform_revenue = float(total['combined_tax_9']) * 1e-9
    # assert that dropq revenue is similar to the fullsample calculation
    diff = abs(fulls_reform_revenue - dropq_reform_revenue)
    proportional_diff = diff / fulls_reform_revenue
    frmt = 'f,d,adiff,pdiff=  {:.4f}  {:.4f}  {:.4f}  {}'
    print(
        frmt.format(fulls_reform_revenue, dropq_reform_revenue, diff,
                    proportional_diff))
    assert proportional_diff < 0.0001  # one-hundredth of one percent
Пример #23
0
def test_with_pufcsv(puf_fullsample):
    # specify usermods dictionary in code
    start_year = 2017
    reform_year = start_year
    analysis_year = 2026
    year_n = analysis_year - start_year
    reform = {
        '_FICA_ss_trt': [0.2]
    }
    usermods = dict()
    usermods['policy'] = {reform_year: reform}
    usermods['consumption'] = {}
    usermods['growdiff_baseline'] = {}
    usermods['growdiff_response'] = {}
    seed = random_seed(usermods)
    assert seed == 2568216296
    # create a Policy object (pol) containing reform policy parameters
    pol = Policy()
    pol.implement_reform(usermods['policy'])
    # create a Records object (rec) containing all puf.csv input records
    rec = Records(data=puf_fullsample)
    # create a Calculator object using clp policy and puf records
    calc = Calculator(policy=pol, records=rec)
    while calc.current_year < analysis_year:
        calc.increment_year()
    # create aggregate diagnostic table (adt) as a Pandas DataFrame object
    adt = calc.diagnostic_table(1)
    taxes_fullsample = adt.loc["Combined Liability ($b)"]
    assert taxes_fullsample is not None
    fulls_reform_revenue = float(taxes_fullsample.loc[analysis_year])
    # call run_nth_year_tax_calc_model function
    resdict = run_nth_year_taxcalc_model(year_n, start_year,
                                         use_puf_not_cps=True,
                                         use_full_sample=True,
                                         user_mods=usermods,
                                         return_dict=True)
    total = resdict['aggr_2']
    tbi_reform_revenue = float(total['combined_tax_9'])
    # assert that tbi revenue is similar to the fullsample calculation
    diff = abs(fulls_reform_revenue - tbi_reform_revenue)
    proportional_diff = diff / fulls_reform_revenue
    frmt = 'f,d,adiff,pdiff=  {:.4f}  {:.4f}  {:.4f}  {}'
    print(frmt.format(fulls_reform_revenue, tbi_reform_revenue,
                      diff, proportional_diff))
    assert proportional_diff < 0.0001  # one-hundredth of one percent
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
Пример #25
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
Пример #26
0
def test_factor_target(records_2009):
    calc = Calculator(policy=Policy(), records=records_2009, growth=Growth())
    AGDPN_pre = calc.records.BF.AGDPN[2015]
    ATXPY_pre = calc.records.BF.ATXPY[2015]
    # specify _factor_target
    ft2015 = 0.04
    factor_target = {2015: {'_factor_target': [ft2015]}}
    calc.growth.update_economic_growth(factor_target)
    assert calc.current_year == 2013
    calc.increment_year()
    calc.increment_year()
    assert calc.current_year == 2015
    distance = ((ft2015 - Growth.default_real_gdp_growth_rate(2015 - 2013)) /
                calc.records.BF.APOPN[2015])
    AGDPN_post = AGDPN_pre + distance
    ATXPY_post = ATXPY_pre + distance
    assert calc.records.BF.AGDPN[2015] == AGDPN_post
    assert calc.records.BF.ATXPY[2015] == ATXPY_post
Пример #27
0
def test_factor_target(records_2009):
    calc = Calculator(policy=Policy(), records=records_2009, growth=Growth())
    AGDPN_pre = calc.records.BF.AGDPN[2015]
    ATXPY_pre = calc.records.BF.ATXPY[2015]
    # specify _factor_target
    ft2015 = 0.04
    factor_target = {2015: {'_factor_target': [ft2015]}}
    calc.growth.update_economic_growth(factor_target)
    assert calc.current_year == 2013
    calc.increment_year()
    calc.increment_year()
    assert calc.current_year == 2015
    distance = ((ft2015 - Growth.default_real_gdp_growth_rate(2015 - 2013)) /
                calc.records.BF.APOPN[2015])
    AGDPN_post = AGDPN_pre + distance
    ATXPY_post = ATXPY_pre + distance
    assert calc.records.BF.AGDPN[2015] == AGDPN_post
    assert calc.records.BF.ATXPY[2015] == ATXPY_post
Пример #28
0
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)
Пример #29
0
def taxcalc_clp_results():
    """
    Use taxcalc package on this computer to compute aggregate income tax
    and payroll tax revenues for years beginning with MIN_START_YEAR and
    ending with MAX_START_YEAR+NUMBER_OF_YEARS-1 for current-law policy.
    Return two aggregate revenue dictionaries indexed by calendar year.
    """
    calc = Calculator(policy=Policy(),
                      records=Records(data=PUF_PATH),
                      verbose=False)
    nyears = MAX_START_YEAR + NUMBER_OF_YEARS - MIN_START_YEAR - 1
    adts = list()
    for iyr in range(-1, nyears - 1):
        calc.calc_all()
        adts.append(create_diagnostic_table(calc))
        if iyr < nyears:
            calc.increment_year()
    adt = pd.concat(adts, axis=1)
    # note that adt is Pandas DataFrame object
    return (adt.xs('Ind Income Tax ($b)').to_dict(),
            adt.xs('Payroll Taxes ($b)').to_dict())
def test_puf_var_stats(tests_path, puf_fullsample):
    """
    Main logic of test.
    """
    # create a baseline Policy object containing 2017_law.json parameters
    pre_tcja_jrf = os.path.join(tests_path, '..', 'reforms', '2017_law.json')
    pre_tcja = Calculator.read_json_param_objects(pre_tcja_jrf, None)
    baseline_policy = Policy()
    baseline_policy.implement_reform(pre_tcja['policy'])
    # create a Calculator object using baseline_policy and full puf.csv sample
    rec = Records(data=puf_fullsample)
    calc = Calculator(policy=baseline_policy, records=rec, verbose=False)
    # create base tables
    table_mean = create_base_table(tests_path)
    table_corr = copy.deepcopy(table_mean)
    del table_corr['description']
    # add statistics to tables
    year_headers = ['description']
    for year in range(Policy.JSON_START_YEAR, Policy.LAST_BUDGET_YEAR + 1):
        assert year == calc.current_year
        year_headers.append(str(year))
        calc.calc_all()
        calculate_mean_stats(calc, table_mean, year)
        if year == 2016:
            calculate_corr_stats(calc, table_corr)
        if year < Policy.LAST_BUDGET_YEAR:
            calc.increment_year()
    # write tables to new CSV files
    mean_path = os.path.join(tests_path, MEAN_FILENAME + '-new')
    table_mean.sort_index(inplace=True)
    table_mean.to_csv(mean_path, header=year_headers, float_format='%8.0f')
    corr_path = os.path.join(tests_path, CORR_FILENAME + '-new')
    table_corr.sort_index(inplace=True)
    table_corr.to_csv(corr_path, float_format='%8.2f',
                      columns=table_corr.index)
    # compare new and old CSV files for nonsmall differences
    mean_msg = differences(mean_path, mean_path[:-4], 'MEAN')
    corr_msg = differences(corr_path, corr_path[:-4], 'CORR')
    if mean_msg or corr_msg:
        raise ValueError(mean_msg + corr_msg)
Пример #31
0
def test_make_Calculator_with_multiyear_reform():
    # create a Policy object and apply a policy reform
    policy3 = Policy()
    reform3 = {2015: {}}
    reform3[2015]['_STD_Aged'] = [[1600, 1300, 1600, 1300, 1600, 1300]]
    reform3[2015]['_II_em'] = [5000, 6000]  # reform values for 2015 and 2016
    reform3[2015]['_II_em_cpi'] = False
    policy3.implement_reform(reform3)
    # create a Calculator object using this policy-reform
    puf = Records(data=TAX_DTA, weights=WEIGHTS, start_year=2009)
    calc3 = Calculator(policy=policy3, records=puf)
    # check that Policy object embedded in Calculator object is correct
    assert calc3.current_year == 2013
    assert calc3.policy.II_em == 3900
    assert calc3.policy.num_years == 12
    exp_II_em = [3900, 3950, 5000] + [6000] * 9
    assert_array_equal(calc3.policy._II_em, np.array(exp_II_em))
    calc3.increment_year()
    calc3.increment_year()
    assert calc3.current_year == 2015
    assert_array_equal(calc3.policy.STD_Aged,
                       np.array([1600, 1300, 1600, 1300, 1600, 1300]))
Пример #32
0
def test_make_Calculator_with_multiyear_reform(records_2009):
    # create a Policy object and apply a policy reform
    policy3 = Policy()
    reform3 = {2015: {}}
    reform3[2015]['_STD_Aged'] = [[1600, 1300, 1600, 1300, 1600, 1300]]
    reform3[2015]['_II_em'] = [5000, 6000]  # reform values for 2015 and 2016
    reform3[2015]['_II_em_cpi'] = False
    policy3.implement_reform(reform3)
    # create a Calculator object using this policy-reform
    calc3 = Calculator(policy=policy3, records=records_2009)
    # check that Policy object embedded in Calculator object is correct
    assert calc3.current_year == 2013
    assert calc3.policy.II_em == 3900
    assert calc3.policy.num_years == Policy.DEFAULT_NUM_YEARS
    exp_II_em = [3900, 3950, 5000] + [6000] * (Policy.DEFAULT_NUM_YEARS - 3)
    assert np.allclose(calc3.policy._II_em,
                       np.array(exp_II_em))
    calc3.increment_year()
    calc3.increment_year()
    assert calc3.current_year == 2015
    assert np.allclose(calc3.policy.STD_Aged,
                       np.array([1600, 1300, 1600, 1300, 1600, 1300]))
Пример #33
0
def test_make_calculator_with_multiyear_reform(cps_subsample):
    rec = Records.cps_constructor(data=cps_subsample)
    year = rec.current_year
    # create a Policy object and apply a policy reform
    pol = Policy()
    reform = {2015: {}, 2016: {}}
    reform[2015]['_II_em'] = [5000, 6000]  # reform values for 2015 and 2016
    reform[2015]['_II_em_cpi'] = False
    reform[2016]['_STD_Aged'] = [[1600, 1300, 1600, 1300, 1600]]
    pol.implement_reform(reform)
    # create a Calculator object using this policy-reform
    calc = Calculator(policy=pol, records=rec)
    # check that Policy object embedded in Calculator object is correct
    assert calc.current_year == year
    assert calc.policy.II_em == 3950
    assert calc.policy.num_years == Policy.DEFAULT_NUM_YEARS
    exp_II_em = [3900, 3950, 5000] + [6000] * (Policy.DEFAULT_NUM_YEARS - 3)
    assert np.allclose(calc.policy._II_em, np.array(exp_II_em))
    calc.increment_year()
    calc.increment_year()
    assert calc.current_year == 2016
    assert np.allclose(calc.policy.STD_Aged,
                       np.array([1600, 1300, 1600, 1300, 1600]))
Пример #34
0
def calculator_objects(year_n, start_year,
                       use_puf_not_cps,
                       use_full_sample,
                       user_mods,
                       behavior_allowed):
    """
    This function assumes that the specified user_mods is a dictionary
      returned by the Calculator.read_json_param_objects() function.
    This function returns (calc1, calc2) where
      calc1 is pre-reform Calculator object calculated for year_n, and
      calc2 is post-reform Calculator object calculated for year_n.
    Set behavior_allowed to False when generating static results or
      set behavior_allowed to True when generating dynamic results.
    """
    # pylint: disable=too-many-arguments,too-many-locals
    # pylint: disable=too-many-branches,too-many-statements

    check_user_mods(user_mods)

    # specify Consumption instance
    consump = Consumption()
    consump_assumptions = user_mods['consumption']
    consump.update_consumption(consump_assumptions)

    # specify growdiff_baseline and growdiff_response
    growdiff_baseline = GrowDiff()
    growdiff_response = GrowDiff()
    growdiff_base_assumps = user_mods['growdiff_baseline']
    growdiff_resp_assumps = user_mods['growdiff_response']
    growdiff_baseline.update_growdiff(growdiff_base_assumps)
    growdiff_response.update_growdiff(growdiff_resp_assumps)

    # create pre-reform and post-reform GrowFactors instances
    growfactors_pre = GrowFactors()
    growdiff_baseline.apply_to(growfactors_pre)
    growfactors_post = GrowFactors()
    growdiff_baseline.apply_to(growfactors_post)
    growdiff_response.apply_to(growfactors_post)

    # create sample pd.DataFrame from specified input file and sampling scheme
    tbi_path = os.path.abspath(os.path.dirname(__file__))
    if use_puf_not_cps:
        # first try TaxBrain deployment path
        input_path = 'puf.csv.gz'
        if not os.path.isfile(input_path):
            # otherwise try local Tax-Calculator deployment path
            input_path = os.path.join(tbi_path, '..', '..', 'puf.csv')
        sampling_frac = 0.05
        sampling_seed = 2222
    else:  # if using cps input not puf input
        # first try Tax-Calculator code path
        input_path = os.path.join(tbi_path, '..', 'cps.csv.gz')
        if not os.path.isfile(input_path):
            # otherwise read from taxcalc package "egg"
            input_path = None  # pragma: no cover
            full_sample = read_egg_csv('cps.csv.gz')  # pragma: no cover
        sampling_frac = 0.03
        sampling_seed = 180
    if input_path:
        full_sample = pd.read_csv(input_path)
    if use_full_sample:
        sample = full_sample
    else:
        sample = full_sample.sample(frac=sampling_frac,
                                    random_state=sampling_seed)

    # create pre-reform Calculator instance
    if use_puf_not_cps:
        recs1 = Records(data=sample,
                        gfactors=growfactors_pre)
    else:
        recs1 = Records.cps_constructor(data=sample,
                                        gfactors=growfactors_pre)
    policy1 = Policy(gfactors=growfactors_pre)
    calc1 = Calculator(policy=policy1, records=recs1, consumption=consump)
    while calc1.current_year < start_year:
        calc1.increment_year()
    calc1.calc_all()
    assert calc1.current_year == start_year

    # specify Behavior instance
    behv = Behavior()
    behavior_assumps = user_mods['behavior']
    behv.update_behavior(behavior_assumps)

    # always prevent both behavioral response and growdiff response
    if behv.has_any_response() and growdiff_response.has_any_response():
        msg = 'BOTH behavior AND growdiff_response HAVE RESPONSE'
        raise ValueError(msg)

    # optionally prevent behavioral response
    if behv.has_any_response() and not behavior_allowed:
        msg = 'A behavior RESPONSE IS NOT ALLOWED'
        raise ValueError(msg)

    # create post-reform Calculator instance
    if use_puf_not_cps:
        recs2 = Records(data=sample,
                        gfactors=growfactors_post)
    else:
        recs2 = Records.cps_constructor(data=sample,
                                        gfactors=growfactors_post)
    policy2 = Policy(gfactors=growfactors_post)
    policy_reform = user_mods['policy']
    policy2.implement_reform(policy_reform)
    calc2 = Calculator(policy=policy2, records=recs2,
                       consumption=consump, behavior=behv)
    while calc2.current_year < start_year:
        calc2.increment_year()
    assert calc2.current_year == start_year

    # delete objects now embedded in calc1 and calc2
    del sample
    del full_sample
    del consump
    del growdiff_baseline
    del growdiff_response
    del growfactors_pre
    del growfactors_post
    del behv
    del recs1
    del recs2
    del policy1
    del policy2

    # increment Calculator objects for year_n years and calculate
    for _ in range(0, year_n):
        calc1.increment_year()
        calc2.increment_year()
    calc1.calc_all()
    if calc2.behavior_has_response():
        calc2 = Behavior.response(calc1, calc2)
    else:
        calc2.calc_all()

    # return calculated Calculator objects
    return (calc1, calc2)
Пример #35
0
def run_nth_year(year_n, start_year, is_strict, tax_dta="", user_mods="", return_json=True):


    #########################################################################
    #   Create Calculators and Masks
    #########################################################################
    records = Records(tax_dta.copy(deep=True))
    records2 = copy.deepcopy(records)
    records3 = copy.deepcopy(records)
    # add 1 dollar to gross income
    records2.e00200 += 1
    # Default Plans
    # Create a default Policy object
    params = Policy(start_year=2013)
    # Create a Calculator
    calc1 = Calculator(policy=params, records=records)

    if is_strict:
        unknown_params = get_unknown_parameters(user_mods, start_year)
        if unknown_params:
            raise ValueError("Unknown parameters: {}".format(unknown_params))

    growth_assumptions = only_growth_assumptions(user_mods, start_year)
    if growth_assumptions:
        calc1.growth.update_economic_growth(growth_assumptions)

    while calc1.current_year < start_year:
        calc1.increment_year()
    calc1.calc_all()
    assert calc1.current_year == start_year

    params2 = Policy(start_year=2013)
    # Create a Calculator with one extra dollar of income
    calc2 = Calculator(policy=params2, records=records2)
    if growth_assumptions:
        calc2.growth.update_economic_growth(growth_assumptions)

    while calc2.current_year < start_year:
        calc2.increment_year()
    calc2.calc_all()
    assert calc2.current_year == start_year

    # where do the results differ..
    soit1 = results(calc1)
    soit2 = results(calc2)
    mask = (soit1._iitax != soit2._iitax)

    # User specified Plans
    behavior_assumptions = only_behavior_assumptions(user_mods, start_year)

    reform_mods = only_reform_mods(user_mods, start_year)

    params3 = Policy(start_year=2013)
    params3.implement_reform(reform_mods)

    behavior3 = Behavior(start_year=2013)
    # Create a Calculator for the user specified plan
    calc3 = Calculator(policy=params3, records=records3, behavior=behavior3)
    if growth_assumptions:
        calc3.growth.update_economic_growth(growth_assumptions)

    if behavior_assumptions:
        calc3.behavior.update_behavior(behavior_assumptions)

    while calc3.current_year < start_year:
        calc3.increment_year()
    assert calc3.current_year == start_year

    calc3.calc_all()
    # Get a random seed based on user specified plan
    seed = random_seed_from_plan(calc3)
    np.random.seed(seed)

    start_time = time.time()
    for i in range(0, year_n):
        calc1.increment_year()
        calc3.increment_year()

    calc1.calc_all()
    if calc3.behavior.has_response():
        calc3 = Behavior.response(calc1, calc3)
    else:
        calc3.calc_all()
    soit1 = results(calc1)
    soit3 = results(calc3)
    # Means of plan Y by decile
    # diffs of plan Y by decile
    # Means of plan Y by income bin
    # diffs of plan Y by income bin
    mY_dec, mX_dec, df_dec, pdf_dec, cdf_dec, mY_bin, mX_bin, df_bin, \
        pdf_bin, cdf_bin, diff_sum, payrolltax_diff_sum, combined_diff_sum = \
        groupby_means_and_comparisons(soit1, soit3, mask)

    elapsed_time = time.time() - start_time
    print("elapsed time for this run: ", elapsed_time)
    start_year += 1

    #num_fiscal_year_total = format_print(diff_sum)
    #fica_fiscal_year_total = format_print(payrolltax_diff_sum)
    #combined_fiscal_year_total = format_print(combined_diff_sum)
    tots = [diff_sum, payrolltax_diff_sum, combined_diff_sum]
    fiscal_tots= pd.DataFrame(data=tots, index=total_row_names)

    # Get rid of negative incomes
    df_bin.drop(df_bin.index[0], inplace=True)
    pdf_bin.drop(pdf_bin.index[0], inplace=True)
    cdf_bin.drop(cdf_bin.index[0], inplace=True)
    mY_bin.drop(mY_bin.index[0], inplace=True)
    mX_bin.drop(mX_bin.index[0], inplace=True)

    if not return_json:
        return (mY_dec, mX_dec, df_dec, pdf_dec, cdf_dec, mY_bin, mX_bin,
                df_bin, pdf_bin, cdf_bin, fiscal_tots)


    decile_row_names_i = [x+'_'+str(year_n) for x in decile_row_names]

    bin_row_names_i = [x+'_'+str(year_n) for x in bin_row_names]

    total_row_names_i = [x+'_'+str(year_n) for x in total_row_names]

    mY_dec_table_i = create_json_table(mY_dec,
                                        row_names=decile_row_names_i,
                                        column_types=planY_column_types)
    mX_dec_table_i = create_json_table(mX_dec,
                                        row_names=decile_row_names_i,
                                        column_types=planY_column_types)
    df_dec_table_i = create_json_table(df_dec,
                                        row_names=decile_row_names_i,
                                        column_types=diff_column_types)

    pdf_dec_table_i = create_json_table(pdf_dec,
                                        row_names=decile_row_names_i,
                                        column_types=diff_column_types)

    cdf_dec_table_i = create_json_table(cdf_dec,
                                        row_names=decile_row_names_i,
                                        column_types=diff_column_types)

    mY_bin_table_i = create_json_table(mY_bin,
                                        row_names=bin_row_names_i,
                                        column_types=planY_column_types)
    mX_bin_table_i = create_json_table(mX_bin,
                                        row_names=bin_row_names_i,
                                        column_types=planY_column_types)

    df_bin_table_i = create_json_table(df_bin,
                                        row_names=bin_row_names_i,
                                        column_types=diff_column_types)

    pdf_bin_table_i = create_json_table(pdf_bin,
                                        row_names=bin_row_names_i,
                                        column_types=diff_column_types)

    cdf_bin_table_i = create_json_table(cdf_bin,
                                        row_names=bin_row_names_i,
                                        column_types=diff_column_types)

    fiscal_yr_total = create_json_table(fiscal_tots, row_names=total_row_names_i)
    # Make the one-item lists of strings just strings
    fiscal_yr_total = dict((k, v[0]) for k,v in fiscal_yr_total.items())

    return (mY_dec_table_i, mX_dec_table_i, df_dec_table_i, pdf_dec_table_i,
            cdf_dec_table_i, mY_bin_table_i, mX_bin_table_i, df_bin_table_i,
            pdf_bin_table_i, cdf_bin_table_i, fiscal_yr_total)
Пример #36
0
def calculate(year_n, start_year, use_puf_not_cps, use_full_sample, user_mods,
              behavior_allowed):
    """
    The calculate function assumes the specified user_mods is a dictionary
      returned by the Calculator.read_json_param_objects() function.
    The function returns (calc1, calc2, mask) where
      calc1 is pre-reform Calculator object calculated for year_n,
      calc2 is post-reform Calculator object calculated for year_n, and
      mask is boolean array marking records with reform-induced iitax diffs
    Set behavior_allowed to False when generating static results or
      set behavior_allowed to True when generating dynamic results.
    """
    # pylint: disable=too-many-arguments,too-many-locals
    # pylint: disable=too-many-branches,too-many-statements

    check_user_mods(user_mods)

    # specify Consumption instance
    consump = Consumption()
    consump_assumptions = user_mods['consumption']
    consump.update_consumption(consump_assumptions)

    # specify growdiff_baseline and growdiff_response
    growdiff_baseline = Growdiff()
    growdiff_response = Growdiff()
    growdiff_base_assumps = user_mods['growdiff_baseline']
    growdiff_resp_assumps = user_mods['growdiff_response']
    growdiff_baseline.update_growdiff(growdiff_base_assumps)
    growdiff_response.update_growdiff(growdiff_resp_assumps)

    # create pre-reform and post-reform Growfactors instances
    growfactors_pre = Growfactors()
    growdiff_baseline.apply_to(growfactors_pre)
    growfactors_post = Growfactors()
    growdiff_baseline.apply_to(growfactors_post)
    growdiff_response.apply_to(growfactors_post)

    # create sample pd.DataFrame from specified input file and sampling scheme
    stime = time.time()
    tbi_path = os.path.abspath(os.path.dirname(__file__))
    if use_puf_not_cps:
        # first try TaxBrain deployment path
        input_path = 'puf.csv.gz'
        if not os.path.isfile(input_path):
            # otherwise try local Tax-Calculator deployment path
            input_path = os.path.join(tbi_path, '..', '..', 'puf.csv')
        sampling_frac = 0.05
        sampling_seed = 180
    else:  # if using cps input not puf input
        # first try Tax-Calculator code path
        input_path = os.path.join(tbi_path, '..', 'cps.csv.gz')
        if not os.path.isfile(input_path):
            # otherwise read from taxcalc package "egg"
            input_path = None  # pragma: no cover
            full_sample = read_egg_csv('cps.csv.gz')  # pragma: no cover
        sampling_frac = 0.03
        sampling_seed = 180
    if input_path:
        full_sample = pd.read_csv(input_path)
    if use_full_sample:
        sample = full_sample
    else:
        sample = full_sample.sample(  # pylint: disable=no-member
            frac=sampling_frac,
            random_state=sampling_seed)
    if use_puf_not_cps:
        print('puf-read-time= {:.1f}'.format(time.time() - stime))
    else:
        print('cps-read-time= {:.1f}'.format(time.time() - stime))

    # create pre-reform Calculator instance
    if use_puf_not_cps:
        recs1 = Records(data=copy.deepcopy(sample), gfactors=growfactors_pre)
    else:
        recs1 = Records.cps_constructor(data=copy.deepcopy(sample),
                                        gfactors=growfactors_pre)
    policy1 = Policy(gfactors=growfactors_pre)
    calc1 = Calculator(policy=policy1, records=recs1, consumption=consump)
    while calc1.current_year < start_year:
        calc1.increment_year()
    calc1.calc_all()
    assert calc1.current_year == start_year

    # compute mask array
    res1 = calc1.dataframe(DIST_VARIABLES)
    if use_puf_not_cps:
        # create pre-reform Calculator instance with extra income
        recs1p = Records(data=copy.deepcopy(sample), gfactors=growfactors_pre)
        # add one dollar to the income of each filing unit to determine
        # which filing units undergo a resulting change in tax liability
        recs1p.e00200 += 1.0  # pylint: disable=no-member
        recs1p.e00200p += 1.0  # pylint: disable=no-member
        policy1p = Policy(gfactors=growfactors_pre)
        # create Calculator with recs1p and calculate for start_year
        calc1p = Calculator(policy=policy1p,
                            records=recs1p,
                            consumption=consump)
        while calc1p.current_year < start_year:
            calc1p.increment_year()
        calc1p.calc_all()
        assert calc1p.current_year == start_year
        # compute mask showing which of the calc1 and calc1p results differ;
        # mask is true if a filing unit's income tax liability changed after
        # a dollar was added to the filing unit's wage and salary income
        res1p = calc1p.dataframe(DIST_VARIABLES)
        mask = np.logical_not(  # pylint: disable=no-member
            np.isclose(res1.iitax, res1p.iitax, atol=0.001, rtol=0.0))
        assert np.any(mask)
    else:  # if use_cps_not_cps is False
        # indicate that no fuzzing of reform results is required
        mask = np.zeros(res1.shape[0], dtype=np.int8)

    # specify Behavior instance
    behv = Behavior()
    behavior_assumps = user_mods['behavior']
    behv.update_behavior(behavior_assumps)

    # always prevent both behavioral response and growdiff response
    if behv.has_any_response() and growdiff_response.has_any_response():
        msg = 'BOTH behavior AND growdiff_response HAVE RESPONSE'
        raise ValueError(msg)

    # optionally prevent behavioral response
    if behv.has_any_response() and not behavior_allowed:
        msg = 'A behavior RESPONSE IS NOT ALLOWED'
        raise ValueError(msg)

    # create post-reform Calculator instance
    if use_puf_not_cps:
        recs2 = Records(data=copy.deepcopy(sample), gfactors=growfactors_post)
    else:
        recs2 = Records.cps_constructor(data=copy.deepcopy(sample),
                                        gfactors=growfactors_post)
    policy2 = Policy(gfactors=growfactors_post)
    policy_reform = user_mods['policy']
    policy2.implement_reform(policy_reform)
    calc2 = Calculator(policy=policy2,
                       records=recs2,
                       consumption=consump,
                       behavior=behv)
    while calc2.current_year < start_year:
        calc2.increment_year()
    calc2.calc_all()
    assert calc2.current_year == start_year

    # increment Calculator objects for year_n years and calculate
    for _ in range(0, year_n):
        calc1.increment_year()
        calc2.increment_year()
    calc1.calc_all()
    if calc2.behavior_has_response():
        calc2 = Behavior.response(calc1, calc2)
    else:
        calc2.calc_all()

    # return calculated Calculator objects and mask
    return (calc1, calc2, mask)
Пример #37
0
def run_nth_year_gdp_elast_model(year_n,
                                 start_year,
                                 taxrec_df,
                                 user_mods,
                                 return_json=True):
    """
    The run_nth_year_gdp_elast_model function assumes user_mods is a
    dictionary returned by the Calculator.read_json_parameter_files()
    function with an extra key:value pair that is specified as
    'gdp_elasticity': {'value': <float_value>}.
    """
    # pylint: disable=too-many-arguments,too-many-locals,too-many-statements

    check_user_mods(user_mods)

    # Only makes sense to run for budget years 1 through n-1 (not for year 0)
    assert year_n > 0

    # Specify value of gdp_elasticity
    gdp_elasticity = user_mods['gdp_elasticity']['value']

    # Specify Consumption instance
    consump = Consumption()
    consump_assumps = user_mods['consumption']
    consump.update_consumption(consump_assumps)

    # Specify growdiff_baseline and growdiff_response
    growdiff_baseline = Growdiff()
    growdiff_response = Growdiff()
    growdiff_base_assumps = user_mods['growdiff_baseline']
    growdiff_resp_assumps = user_mods['growdiff_response']
    growdiff_baseline.update_growdiff(growdiff_base_assumps)
    growdiff_response.update_growdiff(growdiff_resp_assumps)

    # Create pre-reform and post-reform Growfactors instances
    growfactors_pre = Growfactors()
    growdiff_baseline.apply_to(growfactors_pre)
    growfactors_post = Growfactors()
    growdiff_baseline.apply_to(growfactors_post)
    growdiff_response.apply_to(growfactors_post)

    # Create pre-reform Calculator instance
    records1 = Records(data=taxrec_df.copy(deep=True),
                       gfactors=growfactors_pre)
    policy1 = Policy(gfactors=growfactors_pre)
    calc1 = Calculator(policy=policy1, records=records1, consumption=consump)
    while calc1.current_year < start_year:
        calc1.increment_year()
    assert calc1.current_year == start_year

    # Create post-reform Calculator instance
    records2 = Records(data=taxrec_df.copy(deep=True),
                       gfactors=growfactors_post)
    policy2 = Policy(gfactors=growfactors_post)
    policy_reform = user_mods['policy']
    policy2.implement_reform(policy_reform)
    calc2 = Calculator(policy=policy2, records=records2, consumption=consump)
    while calc2.current_year < start_year:
        calc2.increment_year()
    assert calc2.current_year == start_year

    # Seed random number generator with a seed value based on user_mods
    seed = random_seed(user_mods)
    np.random.seed(seed)  # pylint: disable=no-member
    for _ in range(0, year_n - 1):
        calc1.increment_year()
        calc2.increment_year()
    calc1.calc_all()
    calc2.calc_all()

    # Assert that the current year is one behind the year we are calculating
    assert (calc1.current_year + 1) == (start_year + year_n)
    assert (calc2.current_year + 1) == (start_year + year_n)

    # Compute gdp effect
    gdp_effect = proportional_change_gdp(calc1, calc2, gdp_elasticity)

    # Return gdp_effect results
    if return_json:
        gdp_df = pd.DataFrame(data=[gdp_effect], columns=['col0'])
        gdp_elast_names_i = [
            x + '_' + str(year_n) for x in GDP_ELAST_ROW_NAMES
        ]
        gdp_elast_total = create_json_table(gdp_df,
                                            row_names=gdp_elast_names_i,
                                            num_decimals=5)
        gdp_elast_total = dict((k, v[0]) for k, v in gdp_elast_total.items())
        return gdp_elast_total
    else:
        return gdp_effect
Пример #38
0
    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.increment_year()
calc1.increment_year()
calc2.increment_year()
calc2.increment_year()

# 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
Пример #39
0
def dropq_calculate(year_n, start_year, taxrec_df, user_mods, behavior_allowed,
                    mask_computed):
    """
    The dropq_calculate function assumes specified user_mods is
      a dictionary returned by the Calculator.read_json_parameter_files()
      function with an extra key:value pair that is specified as
      'gdp_elasticity': {'value': <float_value>}.
    The function returns (calc1, calc2, mask) where
      calc1 is pre-reform Calculator object calculated for year_n,
      calc2 is post-reform Calculator object calculated for year_n, and
      mask is boolean array if compute_mask=True or None otherwise
    """
    # pylint: disable=too-many-arguments,too-many-locals,too-many-statements

    check_user_mods(user_mods)

    # specify Consumption instance
    consump = Consumption()
    consump_assumptions = user_mods['consumption']
    consump.update_consumption(consump_assumptions)

    # specify growdiff_baseline and growdiff_response
    growdiff_baseline = Growdiff()
    growdiff_response = Growdiff()
    growdiff_base_assumps = user_mods['growdiff_baseline']
    growdiff_resp_assumps = user_mods['growdiff_response']
    growdiff_baseline.update_growdiff(growdiff_base_assumps)
    growdiff_response.update_growdiff(growdiff_resp_assumps)

    # create pre-reform and post-reform Growfactors instances
    growfactors_pre = Growfactors()
    growdiff_baseline.apply_to(growfactors_pre)
    growfactors_post = Growfactors()
    growdiff_baseline.apply_to(growfactors_post)
    growdiff_response.apply_to(growfactors_post)

    # create pre-reform Calculator instance
    recs1 = Records(data=taxrec_df.copy(deep=True), gfactors=growfactors_pre)
    policy1 = Policy(gfactors=growfactors_pre)
    calc1 = Calculator(policy=policy1, records=recs1, consumption=consump)
    while calc1.current_year < start_year:
        calc1.increment_year()
    calc1.calc_all()
    assert calc1.current_year == start_year

    # optionally compute mask
    if mask_computed:
        # create pre-reform Calculator instance with extra income
        recs1p = Records(data=taxrec_df.copy(deep=True),
                         gfactors=growfactors_pre)
        # add one dollar to total wages and salaries of each filing unit
        recs1p.e00200 += 1.0  # pylint: disable=no-member
        recs1p.e00200p += 1.0  # pylint: disable=no-member
        policy1p = Policy(gfactors=growfactors_pre)
        # create Calculator with recs1p and calculate for start_year
        calc1p = Calculator(policy=policy1p,
                            records=recs1p,
                            consumption=consump)
        while calc1p.current_year < start_year:
            calc1p.increment_year()
        calc1p.calc_all()
        assert calc1p.current_year == start_year
        # compute mask that shows which of the calc1 and calc1p results differ
        res1 = results(calc1.records)
        res1p = results(calc1p.records)
        mask = (res1.iitax != res1p.iitax)
    else:
        mask = None

    # specify Behavior instance
    behv = Behavior()
    behavior_assumps = user_mods['behavior']
    behv.update_behavior(behavior_assumps)

    # always prevent both behavioral response and growdiff response
    if behv.has_any_response() and growdiff_response.has_any_response():
        msg = 'BOTH behavior AND growdiff_response HAVE RESPONSE'
        raise ValueError(msg)

    # optionally prevent behavioral response
    if behv.has_any_response() and not behavior_allowed:
        msg = 'A behavior RESPONSE IS NOT ALLOWED'
        raise ValueError(msg)

    # create post-reform Calculator instance
    recs2 = Records(data=taxrec_df.copy(deep=True), gfactors=growfactors_post)
    policy2 = Policy(gfactors=growfactors_post)
    policy_reform = user_mods['policy']
    policy2.implement_reform(policy_reform)
    calc2 = Calculator(policy=policy2,
                       records=recs2,
                       consumption=consump,
                       behavior=behv)
    while calc2.current_year < start_year:
        calc2.increment_year()
    calc2.calc_all()
    assert calc2.current_year == start_year

    # increment Calculator objects for year_n years and calculate
    for _ in range(0, year_n):
        calc1.increment_year()
        calc2.increment_year()
    calc1.calc_all()
    if calc2.behavior.has_response():
        calc2 = Behavior.response(calc1, calc2)
    else:
        calc2.calc_all()

    # return calculated Calculator objects and mask
    return (calc1, calc2, mask)
def get_calculator(baseline,
                   calculator_start_year,
                   reform=None,
                   data='cps',
                   gfactors=None,
                   weights=None,
                   records_start_year=RECORDS_START_YEAR):
    '''
    This function creates the tax calculator object for the microsim

    Args:
        baseline (bool): `True` if baseline tax policy
        calculator_start_year (integer): first year of budget window
        reform (dictionary): IIT reform parameters
        data (string or Pandas DataFrame): path to file or DataFrame
            for Tax-Calculator Records object (optional)
        weights (DataFrame): weights DataFrame for Tax-Calculator
            Records object (optional)
        records_start_year (integer): the start year for the data and
            weights dfs

    Returns:
        calc1 (Tax Calculator Calculator object): TC Calculator object
            with a current_year equal to calculator_start_year
    '''
    # create a calculator
    policy1 = Policy()
    if data is not None and "cps" in data:
        records1 = Records.cps_constructor()
        # impute short and long term capital gains if using CPS data
        # in 2012 SOI data 6.587% of CG as short-term gains
        records1.p22250 = 0.06587 * records1.e01100
        records1.p23250 = (1 - 0.06587) * records1.e01100
        # set total capital gains to zero
        records1.e01100 = np.zeros(records1.e01100.shape[0])
    elif data is not None:  # pragma: no cover
        records1 = Records(data=data,
                           gfactors=gfactors,
                           weights=weights,
                           start_year=records_start_year)  # pragma: no cover
    else:
        records1 = Records()  # pragma: no cover

    if baseline:
        # Should not be a reform if baseline is True
        assert not reform

    if not baseline:
        update_policy(policy1, reform)

    # the default set up increments year to 2013
    calc1 = Calculator(records=records1, policy=policy1)
    print('Calculator initial year = ', calc1.current_year)

    # this increment_year function extrapolates all PUF variables to
    # the next year so this step takes the calculator to the start_year
    if calculator_start_year > TC_LAST_YEAR:
        raise RuntimeError("Start year is beyond data extrapolation.")
    while calc1.current_year < calculator_start_year:
        calc1.increment_year()

    return calc1
Пример #41
0
def calculators(year_n, start_year,
                use_puf_not_cps,
                use_full_sample,
                user_mods):
    """
    This function assumes that the specified user_mods is a dictionary
      returned by the Calculator.read_json_param_objects() function.
    This function returns (calc1, calc2) where
      calc1 is pre-reform Calculator object for year_n, and
      calc2 is post-reform Calculator object for year_n.
    Neither Calculator object has had the calc_all() method executed.
    """
    # pylint: disable=too-many-locals,too-many-branches,too-many-statements

    check_user_mods(user_mods)

    # specify Consumption instance
    consump = Consumption()
    consump_assumptions = user_mods['consumption']
    consump.update_consumption(consump_assumptions)

    # specify growdiff_baseline and growdiff_response
    growdiff_baseline = GrowDiff()
    growdiff_response = GrowDiff()
    growdiff_base_assumps = user_mods['growdiff_baseline']
    growdiff_resp_assumps = user_mods['growdiff_response']
    growdiff_baseline.update_growdiff(growdiff_base_assumps)
    growdiff_response.update_growdiff(growdiff_resp_assumps)

    # create pre-reform and post-reform GrowFactors instances
    growfactors_pre = GrowFactors()
    growdiff_baseline.apply_to(growfactors_pre)
    growfactors_post = GrowFactors()
    growdiff_baseline.apply_to(growfactors_post)
    growdiff_response.apply_to(growfactors_post)

    # create sample pd.DataFrame from specified input file and sampling scheme
    tbi_path = os.path.abspath(os.path.dirname(__file__))
    if use_puf_not_cps:
        # first try TaxBrain deployment path
        input_path = 'puf.csv.gz'
        if not os.path.isfile(input_path):
            # otherwise try local Tax-Calculator deployment path
            input_path = os.path.join(tbi_path, '..', '..', 'puf.csv')
        sampling_frac = 0.05
        sampling_seed = 2222
    else:  # if using cps input not puf input
        # first try Tax-Calculator code path
        input_path = os.path.join(tbi_path, '..', 'cps.csv.gz')
        if not os.path.isfile(input_path):
            # otherwise read from taxcalc package "egg"
            input_path = None  # pragma: no cover
            full_sample = read_egg_csv('cps.csv.gz')  # pragma: no cover
        sampling_frac = 0.03
        sampling_seed = 180
    if input_path:
        full_sample = pd.read_csv(input_path)
    if use_full_sample:
        sample = full_sample
    else:
        sample = full_sample.sample(frac=sampling_frac,
                                    random_state=sampling_seed)

    # create pre-reform Calculator instance
    if use_puf_not_cps:
        recs1 = Records(data=sample,
                        gfactors=growfactors_pre)
    else:
        recs1 = Records.cps_constructor(data=sample,
                                        gfactors=growfactors_pre)
    policy1 = Policy(gfactors=growfactors_pre)
    calc1 = Calculator(policy=policy1, records=recs1, consumption=consump)
    while calc1.current_year < start_year:
        calc1.increment_year()
    assert calc1.current_year == start_year

    # create post-reform Calculator instance
    if use_puf_not_cps:
        recs2 = Records(data=sample,
                        gfactors=growfactors_post)
    else:
        recs2 = Records.cps_constructor(data=sample,
                                        gfactors=growfactors_post)
    policy2 = Policy(gfactors=growfactors_post)
    policy_reform = user_mods['policy']
    policy2.implement_reform(policy_reform)
    calc2 = Calculator(policy=policy2, records=recs2, consumption=consump)
    while calc2.current_year < start_year:
        calc2.increment_year()
    assert calc2.current_year == start_year

    # delete objects now embedded in calc1 and calc2
    del sample
    del full_sample
    del consump
    del growdiff_baseline
    del growdiff_response
    del growfactors_pre
    del growfactors_post
    del recs1
    del recs2
    del policy1
    del policy2

    # increment Calculator objects for year_n years
    for _ in range(0, year_n):
        calc1.increment_year()
        calc2.increment_year()

    # return Calculator objects
    return (calc1, calc2)
Пример #42
0
def calculate_baseline_and_reform(year_n, start_year, taxrec_df, user_mods):
    """
    calculate_baseline_and_reform function assumes specified user_mods is
    a dictionary returned by the Calculator.read_json_parameter_files()
    function with an extra key:value pair that is specified as
    'gdp_elasticity': {'value': <float_value>}.
    """
    # pylint: disable=too-many-locals,too-many-branches,too-many-statements

    check_user_mods(user_mods)

    # Specify Consumption instance
    consump = Consumption()
    consump_assumptions = user_mods['consumption']
    consump.update_consumption(consump_assumptions)

    # Specify growdiff_baseline and growdiff_response
    growdiff_baseline = Growdiff()
    growdiff_response = Growdiff()
    growdiff_base_assumps = user_mods['growdiff_baseline']
    growdiff_resp_assumps = user_mods['growdiff_response']
    growdiff_baseline.update_growdiff(growdiff_base_assumps)
    growdiff_response.update_growdiff(growdiff_resp_assumps)

    # Create pre-reform and post-reform Growfactors instances
    growfactors_pre = Growfactors()
    growdiff_baseline.apply_to(growfactors_pre)
    growfactors_post = Growfactors()
    growdiff_baseline.apply_to(growfactors_post)
    growdiff_response.apply_to(growfactors_post)

    # Create pre-reform Calculator instance
    recs1 = Records(data=taxrec_df.copy(deep=True), gfactors=growfactors_pre)
    policy1 = Policy(gfactors=growfactors_pre)
    calc1 = Calculator(policy=policy1, records=recs1, consumption=consump)
    while calc1.current_year < start_year:
        calc1.increment_year()
    calc1.calc_all()
    assert calc1.current_year == start_year

    # Create pre-reform Calculator instance with extra income
    recs1p = Records(data=taxrec_df.copy(deep=True), gfactors=growfactors_pre)
    # add one dollar to total wages and salaries of each filing unit
    recs1p.e00200 += 1.0  # pylint: disable=no-member
    policy1p = Policy(gfactors=growfactors_pre)
    calc1p = Calculator(policy=policy1p, records=recs1p, consumption=consump)
    while calc1p.current_year < start_year:
        calc1p.increment_year()
    calc1p.calc_all()
    assert calc1p.current_year == start_year

    # Construct mask to show which of the calc1 and calc1p results differ
    soit1 = results(calc1)
    soit1p = results(calc1p)
    mask = (soit1._iitax != soit1p._iitax)  # pylint: disable=protected-access

    # Specify Behavior instance
    behv = Behavior()
    behavior_assumps = user_mods['behavior']
    behv.update_behavior(behavior_assumps)

    # Prevent both behavioral response and growdiff response
    if behv.has_any_response() and growdiff_response.has_any_response():
        msg = 'BOTH behavior AND growdiff_response HAVE RESPONSE'
        raise ValueError(msg)

    # Create post-reform Calculator instance with behavior
    recs2 = Records(data=taxrec_df.copy(deep=True), gfactors=growfactors_post)
    policy2 = Policy(gfactors=growfactors_post)
    policy_reform = user_mods['policy']
    policy2.implement_reform(policy_reform)
    calc2 = Calculator(policy=policy2,
                       records=recs2,
                       consumption=consump,
                       behavior=behv)
    while calc2.current_year < start_year:
        calc2.increment_year()
    calc2.calc_all()
    assert calc2.current_year == start_year

    # Seed random number generator with a seed value based on user_mods
    seed = random_seed(user_mods)
    print('seed={}'.format(seed))
    np.random.seed(seed)  # pylint: disable=no-member

    # Increment Calculator objects for year_n years and calculate
    for _ in range(0, year_n):
        calc1.increment_year()
        calc2.increment_year()
    calc1.calc_all()
    if calc2.behavior.has_response():
        calc2 = Behavior.response(calc1, calc2)
    else:
        calc2.calc_all()

    # Return calculated results and mask
    soit1 = results(calc1)
    soit2 = results(calc2)
    return soit1, soit2, mask
Пример #43
0
def calculators(year_n, start_year,
                use_puf_not_cps,
                use_full_sample,
                user_mods):
    """
    This function assumes that the specified user_mods is a dictionary
      returned by the Calculator.read_json_param_objects() function.
    This function returns (calc1, calc2) where
      calc1 is pre-reform Calculator object for year_n, and
      calc2 is post-reform Calculator object for year_n.
    Neither Calculator object has had the calc_all() method executed.
    """
    # pylint: disable=too-many-locals,too-many-branches,too-many-statements

    check_user_mods(user_mods)

    # specify Consumption instance
    consump = Consumption()
    consump_assumptions = user_mods['consumption']
    consump.update_consumption(consump_assumptions)

    # specify growdiff_baseline and growdiff_response
    growdiff_baseline = GrowDiff()
    growdiff_response = GrowDiff()
    growdiff_base_assumps = user_mods['growdiff_baseline']
    growdiff_resp_assumps = user_mods['growdiff_response']
    growdiff_baseline.update_growdiff(growdiff_base_assumps)
    growdiff_response.update_growdiff(growdiff_resp_assumps)

    # create pre-reform and post-reform GrowFactors instances
    growfactors_pre = GrowFactors()
    growdiff_baseline.apply_to(growfactors_pre)
    growfactors_post = GrowFactors()
    growdiff_baseline.apply_to(growfactors_post)
    growdiff_response.apply_to(growfactors_post)

    # create sample pd.DataFrame from specified input file and sampling scheme
    tbi_path = os.path.abspath(os.path.dirname(__file__))
    if use_puf_not_cps:
        # first try TaxBrain deployment path
        input_path = 'puf.csv.gz'
        if not os.path.isfile(input_path):
            # otherwise try local Tax-Calculator deployment path
            input_path = os.path.join(tbi_path, '..', '..', 'puf.csv')
        sampling_frac = 0.05
        sampling_seed = 2222
    else:  # if using cps input not puf input
        # first try Tax-Calculator code path
        input_path = os.path.join(tbi_path, '..', 'cps.csv.gz')
        if not os.path.isfile(input_path):
            # otherwise read from taxcalc package "egg"
            input_path = None  # pragma: no cover
            full_sample = read_egg_csv('cps.csv.gz')  # pragma: no cover
        sampling_frac = 0.03
        sampling_seed = 180
    if input_path:
        full_sample = pd.read_csv(input_path)
    if use_full_sample:
        sample = full_sample
    else:
        sample = full_sample.sample(frac=sampling_frac,
                                    random_state=sampling_seed)

    # create pre-reform Calculator instance
    if use_puf_not_cps:
        recs1 = Records(data=sample,
                        gfactors=growfactors_pre)
    else:
        recs1 = Records.cps_constructor(data=sample,
                                        gfactors=growfactors_pre)
    policy1 = Policy(gfactors=growfactors_pre)
    calc1 = Calculator(policy=policy1, records=recs1, consumption=consump)
    while calc1.current_year < start_year:
        calc1.increment_year()
    assert calc1.current_year == start_year

    # create post-reform Calculator instance
    if use_puf_not_cps:
        recs2 = Records(data=sample,
                        gfactors=growfactors_post)
    else:
        recs2 = Records.cps_constructor(data=sample,
                                        gfactors=growfactors_post)
    policy2 = Policy(gfactors=growfactors_post)
    policy_reform = user_mods['policy']
    policy2.implement_reform(policy_reform)
    calc2 = Calculator(policy=policy2, records=recs2, consumption=consump)
    while calc2.current_year < start_year:
        calc2.increment_year()
    assert calc2.current_year == start_year

    # delete objects now embedded in calc1 and calc2
    del sample
    del full_sample
    del consump
    del growdiff_baseline
    del growdiff_response
    del growfactors_pre
    del growfactors_post
    del recs1
    del recs2
    del policy1
    del policy2

    # increment Calculator objects for year_n years
    for _ in range(0, year_n):
        calc1.increment_year()
        calc2.increment_year()

    # return Calculator objects
    return (calc1, calc2)
Пример #44
0
def run_nth_year_mtr_calc(year_n, start_year, tax_dta, user_mods="", return_json=True):

    #Only makes sense to run for budget years 1 through n-1 (not for year 0)
    assert year_n > 0

    elasticity_gdp = elasticity_of_gdp_year_n(user_mods, year_n)

    #########################################################################
    #   Create Calculators and Masks
    #########################################################################
    records = Records(tax_dta.copy(deep=True))
    records3 = Records(tax_dta.copy(deep=True))

    # Default Plans
    # Create a default Policy object
    params = Policy(start_year=2013)
    # Create a Calculator
    calc1 = Calculator(policy=params, records=records)

    growth_assumptions = only_growth_assumptions(user_mods, start_year)
    if growth_assumptions:
        calc1.growth.update_economic_growth(growth_assumptions)

    while calc1.current_year < start_year:
        calc1.increment_year()
    assert calc1.current_year == start_year


    # User specified Plans
    reform_mods = only_reform_mods(user_mods, start_year)
    params3 = Policy(start_year=2013)
    params3.implement_reform(reform_mods)

    behavior3 = Behavior(start_year=2013)
    # Create a Calculator for the user specified plan
    calc3 = Calculator(policy=params3, records=records3, behavior=behavior3)
    if growth_assumptions:
        calc3.growth.update_economic_growth(growth_assumptions)

    while calc3.current_year < start_year:
        calc3.increment_year()
    assert calc3.current_year == start_year
    # Get a random seed based on user specified plan
    seed = random_seed_from_plan(calc3)
    np.random.seed(seed)

    for i in range(0, year_n-1):
        calc1.increment_year()
        calc3.increment_year()

    calc1.calc_all()
    calc3.calc_all()

    mtr_fica_x, mtr_iit_x, mtr_combined_x = calc1.mtr()
    mtr_fica_y, mtr_iit_y, mtr_combined_y = calc3.mtr()

    #Assert that the current year is one behind the year we are calculating
    assert (calc1.current_year + 1) == (start_year + year_n)
    assert (calc3.current_year + 1) == (start_year + year_n)

    after_tax_mtr_x = 1 - ((mtr_combined_x * calc1.records.c00100 *
                        calc1.records.s006).sum()/
                        (calc1.records.c00100 * calc1.records.s006).sum())

    after_tax_mtr_y = 1 - ((mtr_combined_y * calc3.records.c00100 *
                        calc3.records.s006).sum()/
                        (calc3.records.c00100 * calc3.records.s006).sum())

    diff_avg_mtr_combined_y = after_tax_mtr_y - after_tax_mtr_x
    percent_diff_mtr = diff_avg_mtr_combined_y / after_tax_mtr_x

    gdp_effect_y = percent_diff_mtr * elasticity_gdp

    gdp_df = pd.DataFrame(data=[gdp_effect_y], columns=["col0"])

    if not return_json:
        return gdp_effect_y

    gdp_elast_names_i = [x+'_'+str(year_n) for x in GDP_elasticity_row_names]

    gdp_elast_total = create_json_table(gdp_df, row_names=gdp_elast_names_i, num_decimals=5)

    # Make the one-item lists of strings just strings
    gdp_elast_total = dict((k, v[0]) for k,v in gdp_elast_total.items())

    return gdp_elast_total
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.increment_year()
calc1.increment_year()
calc2.increment_year()
calc2.increment_year()

# 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