def test_update_depreciation_params_with_json(): expected_result = [{ 'year': 2020, 'value': { 'method': 'Expensing', 'life': 5 }, 'GDS_life': 3.0, 'ADS_life': 3.0, 'major_asset_group': 'Equipment', 'minor_asset_group': 'Computers and Software', 'system': 'GDS', 'asset_name': 'Custom software', 'BEA_code': 'ENS2' }] dp = DepreciationParams() new_dp_json = """ {"asset": [ {"year": 2020, "asset_name": "Custom software", "value": {"life": 5, "method": "Expensing"}}]} """ dp.adjust(new_dp_json) test_result = dp.select_eq(param="asset", exact_match=False, year=2020, BEA_code="ENS2") assert test_result == expected_result
def test_p_param_return_value(): assets = Assets() p = Specification() dp = DepreciationParams() calc1 = Calculator(p, dp, assets) obj = calc1.p_param('tau_int') assert np.allclose(obj, np.array([0.31774924]))
def test_store_assets(): assets = Assets() p = Specification() dp = DepreciationParams() calc1 = Calculator(p, dp, assets) calc1.store_assets() assert isinstance(calc1, Calculator)
def test_p_param_set_value(): assets = Assets() p = Specification() dp = DepreciationParams() calc1 = Calculator(p, dp, assets) new_tau_int = np.array([0.396]) calc1.p_param('tau_int', new_tau_int) assert np.allclose(calc1._Calculator__p.tau_int, new_tau_int)
def test_Calculator_exception1(): ''' Raise exception for not passing parameters object ''' assets = Assets() dp = DepreciationParams() with pytest.raises(Exception): assert Calculator(dp=dp, assets=assets)
def test_update_depreciation_bad_revision2(): ''' Check that parameter out of range raises exception ''' dp = DepreciationParams() new_dp_dict = { "asset": [{ "year": 2020, "asset_name": "Custom software", "value": { "life": 122.0, "method": "Expensing" } }] } with pytest.raises(Exception): assert dp.adjust(new_dp_dict)
def test_Calculator_exception3(): ''' Raise exception for not passing assets object ''' p = Specification() dp = DepreciationParams() with pytest.raises(Exception): assert Calculator(p=p, dp=dp)
def test_calc_by_asset(): ''' Test calc_by_asset method ''' assets = Assets() p = Specification() dp = DepreciationParams() calc = Calculator(p, dp, assets) asset_df = calc.calc_by_asset() assert ('major_asset_group' in asset_df.keys())
def test_update_depreciation_params_as_a_group(): dp = DepreciationParams() new_dp_dict = { "asset": [{ "major_asset_group": "Intellectual Property", "value": { "life": 12, "method": "DB 200%" } }] } dp.adjust(new_dp_dict) test_result = dp.select_eq(param="asset", exact_match=False, year=2020, major_asset_group="Intellectual Property") assert test_result[0]['value']['life'] == 12 assert test_result[1]['value']['life'] == 12 assert test_result[2]['value']['life'] == 12
def test_calc_by_industry(include_land, include_inventories): ''' Test calc_by_industry method ''' assets = Assets() p = Specification() dp = DepreciationParams() calc = Calculator(p, dp, assets) ind_df = calc.calc_by_industry(include_land=include_land, include_inventories=include_inventories) assert ('major_industry' in ind_df.keys())
def test_calc_base(): ''' Test calc_base method ''' assets = Assets() p = Specification() dp = DepreciationParams() calc = Calculator(p, dp, assets) calc.calc_base() calc_base_df = calc._Calculator__assets.df assert ('z_mix' in calc_base_df.keys()) assert ('rho_mix' in calc_base_df.keys())
def test_bubble_widget(): ''' Test asset bubble plot method. ''' assets = Assets() p = Specification() dp = DepreciationParams() calc = Calculator(p, dp, assets) p2 = Specification(year=2026) p2.update_specification({'CIT_rate': 0.25}) calc2 = Calculator(p2, dp, assets) fig = calc.bubble_widget(calc2) assert fig
def test_asset_share_table(include_land, include_inventories): ''' Test asset_share_table method. ''' cyr = 2018 assets = Assets() p = Specification(year=cyr) dp = DepreciationParams() calc1 = Calculator(p, dp, assets) assert calc1.current_year == cyr asset_df = calc1.asset_share_table(include_land=include_land, include_inventories=include_inventories) assert isinstance(asset_df, pd.DataFrame)
def run_model(meta_param_dict, adjustment): ''' Initializes classes from CCC that compute the model under different policies. Then calls function get output objects. ''' # update MetaParams meta_params = MetaParams() meta_params.adjust(meta_param_dict) # Get data chosen by user if meta_params.data_source == "PUF": data = retrieve_puf(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY) else: data = "cps" # Get TC params adjustments iit_mods = cs2tc.convert_policy_adjustment( adjustment["Individual and Payroll Tax Parameters"]) filtered_ccc_params = {} # filter out CCC params that will not change between baeline and # reform runs (These are the Household Savings Behavior and # Economic Assumptions) constant_param_list = [ 'omega_scg', 'omega_lcg', 'omega_xcg', 'alpha_c_e_ft', 'alpha_c_e_td', 'alpha_c_e_nt', 'alpha_c_d_ft', 'alpha_c_d_td', 'alpha_c_d_nt', 'alpha_nc_d_ft', 'alpha_nc_d_td', 'alpha_nc_d_nt', 'alpha_h_d_ft', 'alpha_h_d_td', 'alpha_h_d_nt', 'Y_td', 'Y_scg', 'Y_lcg', 'gamma', 'E_c', 'inflation_rate', 'nominal_interest_rate' ] filtered_ccc_params = OrderedDict() for k, v in adjustment['Business Tax Parameters'].items(): if k in constant_param_list: filtered_ccc_params[k] = v # Baseline CCC calculator params = Specification(year=meta_params.year, call_tc=False, iit_reform={}, data=data) params.update_specification(filtered_ccc_params) assets = Assets() dp = DepreciationParams() calc1 = Calculator(params, dp, assets) # Reform CCC calculator - includes TC adjustments params2 = Specification(year=meta_params.year, call_tc=True, iit_reform=iit_mods, data=data) params2.update_specification(adjustment["Business Tax Parameters"]) calc2 = Calculator(params2, dp, assets) comp_dict = comp_output(calc1, calc2) return comp_dict
def test_calc_other(): ''' Test calc_other method ''' assets = Assets() p = Specification() dp = DepreciationParams() calc = Calculator(p, dp, assets) df = calc.calc_by_asset() calc_other_df = calc.calc_other(df) assert ('ucc_mix' in calc_other_df.keys()) assert ('metr_mix' in calc_other_df.keys()) assert ('mettr_mix' in calc_other_df.keys()) assert ('tax_wedge_mix' in calc_other_df.keys()) assert ('eatr_mix' in calc_other_df.keys())
def test_summary_table(include_land, include_inventories): ''' Test summary_table method. ''' cyr = 2018 assets = Assets() p = Specification(year=cyr) dp = DepreciationParams() calc1 = Calculator(p, dp, assets) assert calc1.current_year == cyr p.update_specification({'CIT_rate': 0.38}) calc2 = Calculator(p, dp, assets) assert calc2.current_year == cyr summary_df = calc1.summary_table(calc2, include_land=include_land, include_inventories=include_inventories) assert isinstance(summary_df, pd.DataFrame)
def test_asset_bubble(): ''' Test asset bubble plot method. ''' assets = Assets() p = Specification() dp = DepreciationParams() calc = Calculator(p, dp, assets) p2 = Specification(year=2026) p2.update_specification({'CIT_rate': 0.25}) calc2 = Calculator(p2, dp, assets) fig = calc.asset_bubble(calc2, include_title=True) assert fig fig = calc.asset_bubble(calc2, output_variable='rho_mix', include_title=True) assert fig
def test_calc_all(): ''' Test calc_all method ''' assets = Assets() p = Specification() dp = DepreciationParams() calc = Calculator(p, dp, assets) calc.calc_all() calc_all_df = calc._Calculator__assets.df assert ('z_mix' in calc_all_df.keys()) assert ('rho_mix' in calc_all_df.keys()) assert ('ucc_mix' in calc_all_df.keys()) assert ('metr_mix' in calc_all_df.keys()) assert ('mettr_mix' in calc_all_df.keys()) assert ('tax_wedge_mix' in calc_all_df.keys()) assert ('eatr_mix' in calc_all_df.keys())
def test_range_plot(corporate): ''' Test range_plot method. ''' assets = Assets() p = Specification() dp = DepreciationParams() calc = Calculator(p, dp, assets) p2 = Specification(year=2026) p2.update_specification({'CIT_rate': 0.25}) calc2 = Calculator(p2, dp, assets) fig = calc.range_plot(calc2, corporate=corporate, include_title=True) assert fig fig = calc.range_plot(calc2, output_variable='rho', corporate=corporate, include_title=True) assert fig
def test_grouped_bar(corporate): ''' Test grouped_bar method. ''' assets = Assets() p = Specification() dp = DepreciationParams() calc = Calculator(p, dp, assets) p2 = Specification(year=2026) p2.update_specification({'CIT_rate': 0.25}) calc2 = Calculator(p2, dp, assets) fig = calc.grouped_bar(calc2, corporate=corporate) assert fig fig = calc.grouped_bar(calc2, output_variable='rho', corporate=corporate, group_by_asset=False) assert fig
def test_calc_by_methods(): """ Test the Calculator calc_by_asset and calc_by_industry methods by comparing actual and expect dataframes """ # execute Calculator calc_by methods to get actual results p = Specification() dp = DepreciationParams() assets = Assets() calc = Calculator(p, dp, assets) actual_by_asset = calc.calc_by_asset() actual_by_industry = calc.calc_by_industry() # load expected results from the calc_by_ methods expect_by_asset = pd.read_json( os.path.join(TDIR, 'run_ccc_asset_output.json')) expect_by_industry = pd.read_json( os.path.join(TDIR, 'run_ccc_industry_output.json')) # compare the actual and expect DataFrames for actual_df, expect_df in zip([actual_by_asset, actual_by_industry], [expect_by_asset, expect_by_industry]): actual_df.sort_index(inplace=True) actual_df.reset_index(inplace=True) expect_df.sort_index(inplace=True) expect_df.reset_index(inplace=True) assert tuple(actual_df.columns) == tuple(expect_df.columns) for col in expect_df.columns: try: example = getattr(actual_df, col).iloc[0] can_diff = isinstance(example, numbers.Number) if can_diff: assert np.allclose(actual_df[col].values, expect_df[col].values, atol=1e-5) else: pass except AttributeError: pass
# so to compare TCJA to 2017 law, we'll use 2017 law as the reform reform_url = ('https://raw.githubusercontent.com/' 'PSLmodels/Tax-Calculator/master/taxcalc/' 'reforms/2017_law.json') iit_reform = taxcalc.Policy.read_json_reform(reform_url) # ... specify reform that implements pre-TCJA business tax policy cyr = 2019 business_tax_reform = { 'CIT_rate': 0.35, 'BonusDeprec_3yr': 0.50, 'BonusDeprec_5yr': 0.50, 'BonusDeprec_7yr': 0.50, 'BonusDeprec_10yr': 0.50, 'BonusDeprec_15yr': 0.50, 'BonusDeprec_20yr': 0.50} # specify baseline and reform Calculator objects for 2019 calculations assets = Assets() baseline_parameters = Specification(year=cyr) dp = DepreciationParams() calc1 = Calculator(baseline_parameters, dp, assets) reform_parameters = Specification(year=cyr) reform_parameters.update_specification(business_tax_reform) calc2 = Calculator(reform_parameters, dp, assets) # do calculations by asset and by industry baseln_assets_df = calc1.calc_by_asset() reform_assets_df = calc2.calc_by_asset() baseln_industry_df = calc1.calc_by_industry() reform_industry_df = calc2.calc_by_industry() # generate dataframes with reform-minus-baseline differences diff_assets_df = diff_two_tables(reform_assets_df, baseln_assets_df) diff_industry_df = diff_two_tables(reform_industry_df, baseln_industry_df)
def test_create_depreciation_parameters_object(): dp = DepreciationParams() assert dp
def test_example_output(): """ Test that can produce expected output from code in ../../example.py script """ # execute code as found in ../../example.py script cyr = 2019 # ... specify baseline and reform Calculator objects assets = Assets() dp = DepreciationParams() baseline_parameters = Specification(year=cyr) calc1 = Calculator(baseline_parameters, dp, assets) reform_parameters = Specification(year=cyr) business_tax_adjustments = { 'CIT_rate': 0.35, 'BonusDeprec_3yr': 0.50, 'BonusDeprec_5yr': 0.50, 'BonusDeprec_7yr': 0.50, 'BonusDeprec_10yr': 0.50, 'BonusDeprec_15yr': 0.50, 'BonusDeprec_20yr': 0.50 } reform_parameters.update_specification(business_tax_adjustments) calc2 = Calculator(reform_parameters, dp, assets) # ... calculation by asset and by industry baseline_assets_df = calc1.calc_by_asset() reform_assets_df = calc2.calc_by_asset() baseline_industry_df = calc1.calc_by_industry() reform_industry_df = calc2.calc_by_industry() diff_assets_df = ccc.utils.diff_two_tables(reform_assets_df, baseline_assets_df) diff_industry_df = ccc.utils.diff_two_tables(reform_industry_df, baseline_industry_df) # ... save calculated results as csv files in ccc/test directory baseline_industry_df.to_csv(os.path.join(TDIR, 'baseline_byindustry.csv'), float_format='%.5f') reform_industry_df.to_csv(os.path.join(TDIR, 'reform_byindustry.csv'), float_format='%.5f') baseline_assets_df.to_csv(os.path.join(TDIR, 'baseline_byasset.csv'), float_format='%.5f') reform_assets_df.to_csv(os.path.join(TDIR, 'reform_byasset.csv'), float_format='%.5f') diff_industry_df.to_csv(os.path.join(TDIR, 'changed_byindustry.csv'), float_format='%.5f') diff_assets_df.to_csv(os.path.join(TDIR, 'changed_byasset.csv'), float_format='%.5f') # compare actual calculated results to expected results failmsg = '' expect_output_dir = os.path.join(TDIR, '..', '..', 'example_output') for fname in [ 'baseline_byasset', 'baseline_byindustry', 'reform_byasset', 'reform_byindustry', 'changed_byasset', 'changed_byindustry' ]: actual_path = os.path.join(TDIR, fname + '.csv') actual_df = pd.read_csv(actual_path) expect_path = os.path.join(expect_output_dir, fname + '_expected.csv') expect_df = pd.read_csv(expect_path) try: assert_frame_equal(actual_df, expect_df) # cleanup actual results if it has same contents as expected file os.remove(actual_path) except AssertionError: failmsg += 'ACTUAL-vs-EXPECT DIFFERENCES FOR {}\n'.format(fname) if failmsg: raise AssertionError('\n' + failmsg)
def test_update_depr_methods(monkeypatch): ''' Test of calcfunctions.update_depr_methods ''' p = Specification() json_str = """ {"schema": { "labels": { "asset_name": {"type": "str"}, "BEA_code": {"type": "str"}, "minor_asset_group": {"type": "str"}, "major_asset_group": {"type": "str"}, "ADS_life": {"type": "float"}, "GDS_life": {"type": "float"}, "system": {"type": "str"}, "year": { "type": "int", "validators": {"range": {"min": 2013, "max": 2030}} } } }, "asset": { "title": "Tax depreciation rules for assets", "description": "Tax depreciation rules for assets", "type": "depreciation_rules", "value": [ { "ADS_life": 10.0, "BEA_code": "1", "GDS_life": 10.0, "asset_name": "Steam engines", "major_asset_group": "Group1", "minor_asset_group": "Group1", "system": "GDS", "year": 2020, "value": {"life": 10, "method": "DB 200%"} }, { "ADS_life": 10.0, "BEA_code": "2", "GDS_life": 10.0, "asset_name": "Custom software", "major_asset_group": "Group1", "minor_asset_group": "Group1", "system": "GDS", "year": 2020, "value": {"life": 10, "method": "DB 150%"} }, { "ADS_life": 3.0, "BEA_code": "3", "GDS_life": 3.0, "asset_name": "Other furniture", "major_asset_group": "Group1", "minor_asset_group": "Group1", "system": "GDS", "year": 2020, "value": {"life": 3, "method": "SL"} }, { "ADS_life": 15.0, "BEA_code": "4", "GDS_life": 15.0, "asset_name": "Mining and oilfield machinery", "major_asset_group": "Group1", "minor_asset_group": "Group1", "system": "GDS", "year": 2020, "value": {"life": 15, "method": "Economic"} }, { "ADS_life": 27.5, "BEA_code": "5", "GDS_life": 27.5, "asset_name": "Expensing", "major_asset_group": "Group1", "minor_asset_group": "Group1", "system": "GDS", "year": 2020, "value": {"life": 27.5, "method": "Expensing"} }, { "ADS_life": 27.5, "BEA_code": "6", "GDS_life": 27.5, "asset_name": "PCs", "major_asset_group": "Group1", "minor_asset_group": "Group1", "system": "GDS", "year": 2020, "value": {"life": 27.5, "method": "DB 200%"} }, { "ADS_life": 10.0, "BEA_code": "7", "GDS_life": 10.0, "asset_name": "Terminals", "major_asset_group": "Group1", "minor_asset_group": "Group1", "system": "GDS", "year": 2020, "value": {"life": 10, "method": "DB 150%"} }, { "ADS_life": 3.0, "BEA_code": "8", "GDS_life": 3.0, "asset_name": "Manufacturing", "major_asset_group": "Group1", "minor_asset_group": "Group1", "system": "GDS", "year": 2020, "value": {"life": 3, "method": "SL"} }, { "ADS_life": 15.0, "BEA_code": "9", "GDS_life": 15.0, "asset_name": "Wind and solar", "major_asset_group": "Group1", "minor_asset_group": "Group1", "system": "GDS", "year": 2020, "value": {"life": 15, "method": "Economic"} }, { "ADS_life": 7.0, "BEA_code": "10", "GDS_life": 7.0, "asset_name": "Equipment", "major_asset_group": "Group1", "minor_asset_group": "Group1", "system": "GDS", "year": 2020, "value": {"life": 7, "method": "Expensing"} }] } } """ monkeypatch.setattr(DepreciationParams, "defaults", json_str) dp = DepreciationParams() asset_df = pd.DataFrame.from_dict({ 'bea_asset_code': ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10'] }) expected_df = pd.DataFrame(dp.asset) expected_df = pd.concat([ expected_df.drop(['value'], axis=1), expected_df['value'].apply( pd.Series) ], axis=1) expected_df.drop( columns=['asset_name', 'minor_asset_group', 'major_asset_group'], inplace=True) expected_df['bea_asset_code'] = pd.Series( ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10'], index=expected_df.index) expected_df['bonus'] = pd.Series( [1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0], index=expected_df.index) expected_df['b'] = pd.Series([2, 1.5, 1, 1, 1, 2, 1.5, 1, 1, 1], index=expected_df.index) expected_df['Y'] = pd.Series([10, 10, 3, 15, 27.5, 27.5, 10, 3, 15, 7], index=expected_df.index) print('Expected df =', expected_df) test_df = cf.update_depr_methods(asset_df, p, dp) assert_frame_equal(test_df, expected_df, check_like=True)
def test_data_year(): assets = Assets() p = Specification() dp = DepreciationParams() calc1 = Calculator(p, dp, assets) assert calc1.data_year == 2013