def test_ce_aftertax_income(puf_1991, weights_1991): # test certainty_equivalent() function con = 10000 cmin = 1000 assert con == round(certainty_equivalent(con, 0, cmin), 6) assert con > round(certainty_equivalent((math.log(con) - 0.1), 1, cmin), 6) # test with require_no_agg_tax_change equal to False cyr = 2020 # specify calc1 and calc_all() for cyr pol1 = Policy() rec1 = Records(data=puf_1991, weights=weights_1991, start_year=2009) calc1 = Calculator(policy=pol1, records=rec1) calc1.advance_to_year(cyr) calc1.calc_all() # specify calc2 and calc_all() for cyr pol2 = Policy() reform = {2018: {'_II_em': [0.0]}} pol2.implement_reform(reform) rec2 = Records(data=puf_1991, weights=weights_1991, start_year=2009) calc2 = Calculator(policy=pol2, records=rec2) calc2.advance_to_year(cyr) calc2.calc_all() cedict = ce_aftertax_income(calc1, calc2, require_no_agg_tax_change=False) assert cedict['year'] == cyr # test with require_no_agg_tax_change equal to True with pytest.raises(ValueError): ce_aftertax_income(calc1, calc2, require_no_agg_tax_change=True) # test with require_no_agg_tax_change equal to False and custom_params params = {'crra_list': [0, 2], 'cmin_value': 2000} with pytest.raises(ValueError): ce_aftertax_income(calc1, calc2, require_no_agg_tax_change=True, custom_params=params)
def test_ce_aftertax_income(cps_subsample): # test certainty_equivalent() function with con>cmin con = 5000 cmin = 1000 assert con == round(certainty_equivalent(con, 0, cmin), 6) assert con > round(certainty_equivalent((math.log(con) - 0.1), 1, cmin), 6) # test certainty_equivalent() function with con<cmin con = 500 cmin = 1000 assert con == round(certainty_equivalent(con, 0, cmin), 6) # test with require_no_agg_tax_change equal to False rec = Records.cps_constructor(data=cps_subsample) cyr = 2020 # specify calc1 and calc_all() for cyr pol = Policy() calc1 = Calculator(policy=pol, records=rec) calc1.advance_to_year(cyr) calc1.calc_all() # specify calc2 and calc_all() for cyr reform = {2018: {'_II_em': [0.0]}} pol.implement_reform(reform) calc2 = Calculator(policy=pol, records=rec) calc2.advance_to_year(cyr) calc2.calc_all() cedict = ce_aftertax_income(calc1, calc2, require_no_agg_tax_change=False) assert cedict['year'] == cyr # test with require_no_agg_tax_change equal to True with pytest.raises(ValueError): ce_aftertax_income(calc1, calc2, require_no_agg_tax_change=True) # test with require_no_agg_tax_change equal to False and custom_params params = {'crra_list': [0, 2], 'cmin_value': 2000} with pytest.raises(ValueError): ce_aftertax_income(calc1, calc2, require_no_agg_tax_change=True, custom_params=params)
def analyze(self, writing_output_file=False, output_tables=False, output_graphs=False, output_ceeu=False, output_dump=False, output_sqldb=False): """ Conduct tax analysis. Parameters ---------- writing_output_file: boolean whether or not to generate and write output file output_tables: boolean whether or not to generate and write distributional tables to a text file output_graphs: boolean whether or not to generate and write HTML graphs of average and marginal tax rates by income percentile output_ceeu: boolean whether or not to calculate and write to stdout standard certainty-equivalent expected-utility statistics output_dump: boolean whether or not to replace standard output with all input and calculated variables using their Tax-Calculator names output_sqldb: boolean whether or not to write SQLite3 database with dump table containing same output as written by output_dump to a csv file Returns ------- Nothing """ # pylint: disable=too-many-arguments,too-many-branches # in order to use print(), pylint: disable=superfluous-parens if len(self.calc.policy.reform_warnings) > 0: warn = 'PARAMETER VALUE WARNING(S): (read documentation)\n{}{}' print( warn.format(self.calc.policy.reform_warnings, 'CONTINUING WITH CALCULATIONS...')) calc_clp_calculated = False if output_dump or output_sqldb: (mtr_paytax, mtr_inctax, _) = self.calc.mtr(wrt_full_compensation=False) else: # do not need marginal tax rates mtr_paytax = None mtr_inctax = None if self.behavior_has_any_response: self.calc = Behavior.response(self.calc_clp, self.calc) calc_clp_calculated = True else: self.calc.calc_all() # optionally conduct normative welfare analysis if output_ceeu: if self.behavior_has_any_response: ceeu_results = 'SKIP --ceeu output because baseline and ' ceeu_results += 'reform cannot be sensibly compared\n ' ceeu_results += ' ' ceeu_results += 'when specifying "behavior" with --assump ' ceeu_results += 'option' elif self.calc.records.s006.sum() <= 0.: ceeu_results = 'SKIP --ceeu output because ' ceeu_results += 'sum of weights is not positive' else: self.calc_clp.calc_all() calc_clp_calculated = True cedict = ce_aftertax_income(self.calc_clp, self.calc, require_no_agg_tax_change=False) ceeu_results = TaxCalcIO.ceeu_output(cedict) else: ceeu_results = None # extract output if writing_output_file if writing_output_file: self.write_output_file(output_dump, mtr_paytax, mtr_inctax) self.write_doc_file() # optionally write --sqldb output to SQLite3 database if output_sqldb: self.write_sqldb_file(mtr_paytax, mtr_inctax) # optionally write --tables output to text file if output_tables: if not calc_clp_calculated: self.calc_clp.calc_all() calc_clp_calculated = True self.write_tables_file() # optionally write --graphs output to HTML files if output_graphs: if not calc_clp_calculated: self.calc_clp.calc_all() calc_clp_calculated = True self.write_graph_files() # optionally write --ceeu output to stdout if ceeu_results: print(ceeu_results)
def static_analysis(self, writing_output_file=False, output_graph=False, output_ceeu=False, output_dump=False): """ Conduct STATIC tax analysis for INPUT and write or return OUTPUT. Parameters ---------- writing_output_file: boolean output_graph: boolean whether or not to generate and show HTML graphs of average and marginal tax rates by income percentile output_ceeu: boolean whether or not to calculate and write to stdout standard certainty-equivalent expected-utility statistics output_dump: boolean whether or not to replace standard output with all input and calculated variables using their Tax-Calculator names Returns ------- Nothing """ # pylint: disable=too-many-arguments,too-many-locals,too-many-branches # conduct STATIC tax analysis if output_dump: (mtr_paytax, mtr_inctax, _) = self._calc.mtr(wrt_full_compensation=False) else: # do not need marginal tax rates self._calc.calc_all() # optionally conduct normative welfare analysis if output_ceeu: self._calc_clp.calc_all() cedict = ce_aftertax_income(self._calc_clp, self._calc, require_no_agg_tax_change=False) ceeu_results = TaxCalcIO.ceeu_output(cedict) else: ceeu_results = None # extract output if writing_output_file if writing_output_file: if output_dump: outdf = self.dump_output(mtr_inctax, mtr_paytax) else: outdf = self.standard_output() assert len(outdf.index) == self._calc.records.dim outdf.to_csv(self._output_filename, index=False, float_format='%.2f') # optionally write --graph output to HTML files if output_graph: atr_data = atr_graph_data(self._calc_clp, self._calc) atr_plot = xtr_graph_plot(atr_data) atr_fname = self._output_filename.replace('.csv', '-atr.html') atr_title = 'ATR by Income Percentile' write_graph_file(atr_plot, atr_fname, atr_title) mtr_data = mtr_graph_data(self._calc_clp, self._calc, alt_e00200p_text='Taxpayer Earnings') mtr_plot = xtr_graph_plot(mtr_data) mtr_fname = self._output_filename.replace('.csv', '-mtr.html') mtr_title = 'MTR by Income Percentile' write_graph_file(mtr_plot, mtr_fname, mtr_title) # optionally write --ceeu output to stdout if ceeu_results: print(ceeu_results) # pylint: disable=superfluous-parens