def test_1(): """ Test calculation of AGI adjustment for half of Self-Employment Tax, which is the FICA payroll tax on self-employment income. """ agi_ovar_num = 10 # specify a reform that simplifies the hand calculations mte = 100000 # lower than current-law to simplify hand calculations ssr = 0.124 # current law OASDI ee+er payroll tax rate mrr = 0.029 # current law HI ee+er payroll tax rate reform = { 2015: { '_SS_Earnings_c': [mte], '_FICA_ss_trt': [ssr], '_FICA_mc_trt': [mrr] } } funit = ( u'RECID,MARS,e00200,e00200p,e00900,e00900p,e00900s\n' u'1, 2, 200000, 200000,200000, 0, 200000\n' u'2, 1, 100000, 100000,200000, 200000, 0\n' ) # ==== Filing unit with RECID=1: # The expected AGI for this filing unit is $400,000 minus half of # the spouse's Self-Employment Tax (SET), which represents the # "employer share" of the SET. The spouse pays OASDI SET on only # $100,000 of self-employment income, which implies a tax of # $12,400. The spouse also pays HI SET on 0.9235 * 200000 * 0.029, # which implies a tax of $5,356.30. So, the spouse's total SET is # the sum of the two, which equals $17,756.30. # The SET AGI adjustment is one-half of that amount, which is $8,878.15. # So, filing unit's AGI is $400,000 less this, which is $391,121.85. expected_agi_1 = '391121.85' # ==== Filing unit with RECID=2: # The expected AGI for this filing unit is $300,000 minus half of # the individual's Self-Employment Tax (SET), which represents the # "employer share" of the SET. The individual pays no OASDI SET # because wage and salary income was already at the MTE. So, the # only SET the individual pays is for HI, which is a tax equal to # 0.9235 * 200000 * 0.029, or $5,356.30. One half of that amount # is $2,678.15, which implies the AGI is $297,321.85. expected_agi_2 = '297321.85' input_dataframe = pd.read_csv(StringIO(funit)) inctax = IncomeTaxIO(input_data=input_dataframe, tax_year=2015, policy_reform=reform, exact_calculations=False, blowup_input_data=False, output_weights=False, output_records=False, csv_dump=False) output = inctax.calculate() output_lines_list = output.split('\n') output_vars_list = output_lines_list[0].split() agi = output_vars_list[agi_ovar_num - 1] assert agi == expected_agi_1 output_vars_list = output_lines_list[1].split() agi = output_vars_list[agi_ovar_num - 1] assert agi == expected_agi_2
def test_1(): """ Test calculation of AGI adjustment for half of Self-Employment Tax, which is the payroll tax on self-employment income. """ agi_ovar_num = 10 # specify a reform that simplifies the hand calculations mte = 100000 # lower than current-law to simplify hand calculations ssr = 0.124 # current law OASDI ee+er payroll tax rate mrr = 0.029 # current law HI ee+er payroll tax rate reform = { 2015: { '_SS_Earnings_c': [mte], '_FICA_ss_trt': [ssr], '_FICA_mc_trt': [mrr] } } funit = (u'RECID,MARS,e00200,e00200p,e00900,e00900p,e00900s\n' u'1, 2, 200000, 200000,200000, 0, 200000\n' u'2, 1, 100000, 100000,200000, 200000, 0\n') # ==== Filing unit with RECID=1: # The expected AGI for this filing unit is $400,000 minus half of # the spouse's Self-Employment Tax (SET), which represents the # "employer share" of the SET. The spouse pays OASDI SET on only # $100,000 of self-employment income, which implies a tax of # $12,400. The spouse also pays HI SET on 0.9235 * 200000 * 0.029, # which implies a tax of $5,356.30. So, the spouse's total SET is # the sum of the two, which equals $17,756.30. # The SET AGI adjustment is one-half of that amount, which is $8,878.15. # So, filing unit's AGI is $400,000 less this, which is $391,121.85. expected_agi_1 = '391121.85' # ==== Filing unit with RECID=2: # The expected AGI for this filing unit is $300,000 minus half of # the individual's Self-Employment Tax (SET), which represents the # "employer share" of the SET. The individual pays no OASDI SET # because wage and salary income was already at the MTE. So, the # only SET the individual pays is for HI, which is a tax equal to # 0.9235 * 200000 * 0.029, or $5,356.30. One half of that amount # is $2,678.15, which implies the AGI is $297,321.85. expected_agi_2 = '297321.85' input_dataframe = pd.read_csv(StringIO(funit)) inctax = IncomeTaxIO(input_data=input_dataframe, tax_year=2015, policy_reform=reform, exact_calculations=False, blowup_input_data=False, output_weights=False, output_records=False, csv_dump=False) output = inctax.calculate() output_lines_list = output.split('\n') output_vars_list = output_lines_list[0].split() agi = output_vars_list[agi_ovar_num - 1] assert agi == expected_agi_1 output_vars_list = output_lines_list[1].split() agi = output_vars_list[agi_ovar_num - 1] assert agi == expected_agi_2
def test_1(): """ Test IncomeTaxIO constructor with no policy reform. """ taxyear = 2020 inctax = IncomeTaxIO(input_filename=FAUX_PUF_CSV, tax_year=taxyear, reform_filename=None, blowup_input_data=False) assert inctax.tax_year() == taxyear
def test_2(): """ Test IncomeTaxIO calculate method with no output writing. """ taxyear = 2020 inctax = IncomeTaxIO(input_filename=FAUX_PUF_CSV, tax_year=taxyear, reform_filename=None, blowup_input_data=False) inctax.calculate(write_output_file=False) assert inctax.tax_year() == taxyear
def test_1(rawinputfile): # pylint: disable=redefined-outer-name """ Test IncomeTaxIO constructor with no policy reform and no blowup. """ IncomeTaxIO.show_iovar_definitions() taxyear = 2021 inctax = IncomeTaxIO(input_data=rawinputfile.name, tax_year=taxyear, policy_reform=None, blowup_input_data=False) assert inctax.tax_year() == taxyear
def test_1(rawinputfile): # pylint: disable=redefined-outer-name """ Test IncomeTaxIO constructor with no policy reform and no blowup. """ IncomeTaxIO.show_iovar_definitions() taxyear = 2021 inctax = IncomeTaxIO(input_data=rawinputfile.name, tax_year=taxyear, policy_reform=None, blowup_input_data=True) assert inctax.tax_year() == taxyear
def test_3(rawinputfile, reformfile1): # pylint: disable=redefined-outer-name """ Test IncomeTaxIO calculate method with no output writing and with blowup. """ taxyear = 2021 inctax = IncomeTaxIO(input_data=rawinputfile.name, tax_year=taxyear, policy_reform=reformfile1.name, blowup_input_data=False) output = inctax.calculate() assert output == EXPECTED_OUTPUT
def test_5(rawinputfile): # pylint: disable=redefined-outer-name """ Test IncomeTaxIO calculate method with no output writing and no blowup and no reform, using the output_records option. """ taxyear = 2021 inctax = IncomeTaxIO(input_data=rawinputfile.name, tax_year=taxyear, policy_reform=None, blowup_input_data=False, output_records=True) inctax.output_records(writing_output_file=False) assert inctax.tax_year() == taxyear
def test_4(reformfile2): # pylint: disable=redefined-outer-name """ Test IncomeTaxIO calculate method with no output writing and with blowup. """ input_stream = StringIO(RAWINPUTFILE_CONTENTS) input_dataframe = pd.read_csv(input_stream) taxyear = 2021 inctax = IncomeTaxIO(input_data=input_dataframe, tax_year=taxyear, policy_reform=reformfile2.name, blowup_input_data=False) output = inctax.calculate() assert output == EXPECTED_OUTPUT
def test_3(rawinputfile, reformfile1): # pylint: disable=redefined-outer-name """ Test IncomeTaxIO calculate method with no output writing and no blowup, using file name for IncomeTaxIO constructor input_data. """ taxyear = 2021 inctax = IncomeTaxIO(input_data=rawinputfile.name, tax_year=taxyear, policy_reform=reformfile1.name, exact_calculations=False, blowup_input_data=False, output_weights=False, output_records=False, csv_dump=False) output = inctax.calculate() assert output == EXPECTED_OUTPUT
def test_creation_with_blowup(rawinputfile, blowup, weights_out): """ Test IncomeTaxIO instantiation with no policy reform and with blowup. """ # for fixture args, pylint: disable=redefined-outer-name IncomeTaxIO.show_iovar_definitions() taxyear = 2021 inctax = IncomeTaxIO(input_data=rawinputfile.name, tax_year=taxyear, policy_reform=None, exact_calculations=False, blowup_input_data=blowup, output_weights=weights_out, output_records=False, csv_dump=False) assert inctax.tax_year() == taxyear
def test_2(rawinputfile): # pylint: disable=redefined-outer-name """ Test IncomeTaxIO calculate method with no output writing and no blowup. """ taxyear = 2021 reform_dict = { 2016: {'_SS_Earnings_c': [300000]}, 2018: {'_SS_Earnings_c': [500000]}, 2020: {'_SS_Earnings_c': [700000]} } inctax = IncomeTaxIO(input_data=rawinputfile.name, tax_year=taxyear, policy_reform=reform_dict, blowup_input_data=False) output = inctax.calculate(output_mtr=True) assert output == EXPECTED_OUTPUT_MTR
def test_2(rawinputfile): # pylint: disable=redefined-outer-name """ Test IncomeTaxIO calculate method with no output writing and no blowup. """ taxyear = 2021 reform_dict = { 2016: {'_SS_Earnings_c': [300000]}, 2018: {'_SS_Earnings_c': [500000]}, 2020: {'_SS_Earnings_c': [700000]} } inctax = IncomeTaxIO(input_data=rawinputfile.name, tax_year=taxyear, policy_reform=reform_dict, blowup_input_data=False) output = inctax.calculate() assert output == EXPECTED_OUTPUT
def test_2(): """ Test calculation of Additional Child Tax Credit (CTC) when at least one of taxpayer and spouse have wage-and-salary income above the FICA maximum taxable earnings. """ ctc_ovar_num = 22 actc_ovar_num = 23 # specify a contrived example -- implausible policy and a large family --- # in order to make the hand calculations easier actc_thd = 35000 mte = 53000 reform = { 2015: { '_ACTC_Income_thd': [actc_thd], '_SS_Earnings_c': [mte], '_ALD_Investment_ec_base_all': [False] } } funit = ( u'RECID,MARS,XTOT,n24,e00200,e00200p\n' u'1, 2, 9, 7, 60000, 60000\n' ) # The maximum CTC in the above situation is $7,000, but only $1,140 can # be paid as a nonrefundable CTC. Because the family has 3+ kids, they # can compute their refundable CTC amount in a way that uses the # employee share of FICA taxes paid on wage-and-salary income. In this # case, the employee share is the sum of HI FICA (0.0145*60000) $870 and # OASDI FICA (0.062*53000) $3,286, which is $4,156, which is larger than # the $3,700 available to smaller families. expected_ctc = '1140.00' expected_actc = '4156.00' input_dataframe = pd.read_csv(StringIO(funit)) inctax = IncomeTaxIO(input_data=input_dataframe, tax_year=2015, policy_reform=reform, exact_calculations=False, blowup_input_data=False, output_weights=False, output_records=False, csv_dump=False) output = inctax.calculate() output_vars_list = output.split() ctc = output_vars_list[ctc_ovar_num - 1] actc = output_vars_list[actc_ovar_num - 1] assert ctc == expected_ctc assert actc == expected_actc
def test_2(): """ Test calculation of Additional Child Tax Credit (CTC) when at least one of taxpayer and spouse have wage-and-salary income above the FICA maximum taxable earnings. """ ctc_ovar_num = 22 actc_ovar_num = 23 # specify a contrived example -- implausible policy and a large family --- # in order to make the hand calculations easier actc_thd = 35000 mte = 53000 reform = { 2015: { '_ACTC_Income_thd': [actc_thd], '_SS_Earnings_c': [mte], '_ALD_Investment_ec_base_all': [False] } } funit = (u'RECID,MARS,XTOT,n24,e00200,e00200p\n' u'1, 2, 9, 7, 60000, 60000\n') # The maximum CTC in the above situation is $7,000, but only $1,140 can # be paid as a nonrefundable CTC. Because the family has 3+ kids, they # can compute their refundable CTC amount in a way that uses the # employee share of FICA taxes paid on wage-and-salary income. In this # case, the employee share is the sum of HI FICA (0.0145*60000) $870 and # OASDI FICA (0.062*53000) $3,286, which is $4,156, which is larger than # the $3,700 available to smaller families. expected_ctc = '1140.00' expected_actc = '4156.00' input_dataframe = pd.read_csv(StringIO(funit)) inctax = IncomeTaxIO(input_data=input_dataframe, tax_year=2015, policy_reform=reform, exact_calculations=False, blowup_input_data=False, output_weights=False, output_records=False, csv_dump=False) output = inctax.calculate() output_vars_list = output.split() ctc = output_vars_list[ctc_ovar_num - 1] actc = output_vars_list[actc_ovar_num - 1] assert ctc == expected_ctc assert actc == expected_actc
def test_4(reformfile2): # pylint: disable=redefined-outer-name """ Test IncomeTaxIO calculate method with no output writing and no blowup, using DataFrame for IncomeTaxIO constructor input_data. """ input_stream = StringIO(RAWINPUTFILE_CONTENTS) input_dataframe = pd.read_csv(input_stream) taxyear = 2021 inctax = IncomeTaxIO(input_data=input_dataframe, tax_year=taxyear, policy_reform=reformfile2.name, exact_calculations=False, blowup_input_data=False, output_weights=False, output_records=False, csv_dump=False) output = inctax.calculate() assert output == EXPECTED_OUTPUT
def test_incorrect_creation_1(input_data, exact): """ Ensure a ValueError is raised when created with invalid data pointers """ with pytest.raises(ValueError): IncomeTaxIO( input_data=input_data, tax_year=2013, policy_reform=None, exact_calculations=exact, blowup_input_data=True, output_weights=False, output_records=False, csv_dump=False )
def test_incorrect_creation_2(rawinputfile, year, reform): """ Ensure a ValueError is raised when created with invalid reform params """ # for fixture args, pylint: disable=redefined-outer-name with pytest.raises(ValueError): IncomeTaxIO( input_data=rawinputfile.name, tax_year=year, policy_reform=reform, exact_calculations=False, blowup_input_data=True, output_weights=False, output_records=False, csv_dump=False )
def main(): """ Contains command-line interface to the Tax-Calculator IncomeTaxIO class. """ # parse command-line arguments: parser = argparse.ArgumentParser( prog='python inctax.py', description=('Writes to a file the federal income tax OUTPUT for the ' 'tax filing units specified in the INPUT file with the ' 'OUTPUT computed from the INPUT for the TAXYEAR using ' 'the Tax-Calculator. ' 'The INPUT file is a CSV-formatted file that contains ' 'variable names that are a subset of the ' 'Records.VALID_READ_VARS set. The OUTPUT file is in ' 'Internet-TAXSIM format. The OUTPUT filename is the ' 'INPUT filename (excluding the .csv suffix or ' '.gz suffix, or both) followed by ' 'a string equal to "-YY" (where the YY is the last two ' 'digits in the TAXYEAR) and all that is followed by a ' 'trailing string. The trailing string is ".out-inctax" ' 'if no --reform option is specified; otherwise the ' 'trailing string is ".out-inctax-REFORM" (excluding any ' '".json" ending to the REFORM filename). The OUTPUT ' 'file contains the first 28 Internet-TAXSIM output ' 'variables. Use --iohelp flag for more information. ' 'For details on the Internet-TAXSIM version 9.3 ' 'OUTPUT format, go to ' 'http://users.nber.org/~taxsim/taxsim-calc9/')) parser.add_argument('--iohelp', help=('optional flag to show INPUT and OUTPUT ' 'variable definitions and exit'), default=False, action="store_true") parser.add_argument('--reform', help=('REFORM is name of optional file that contains ' 'tax reform provisions; the provisions are ' 'specified using JSON that may include ' '//-comments. No REFORM filename implies use ' 'of current-law policy.'), default=None) parser.add_argument('--exact', help=('optional flag to suppress smoothing in income ' 'tax calculations that eliminate marginal-tax-' 'rate-complicating "stair-steps". The default ' 'is to smooth, and therefore, not to do the ' ' exact calculations called for in the tax ' 'law.'), default=False, action="store_true") parser.add_argument('--blowup', help=('optional flag that triggers the default ' 'imputation and blowup (or aging) logic built ' 'into the Tax-Calculator that will age the ' 'INPUT data from Records.PUF_YEAR to TAXYEAR. ' 'No --blowup option implies INPUT data are ' 'considered raw data that are not aged or ' 'adjusted in any way.'), default=False, action="store_true") parser.add_argument('--weights', help=('optional flag that causes OUTPUT to have an ' 'additional variable [29] containing the s006 ' 'sample weight, which will be aged if the ' '--blowup option is used'), default=False, action="store_true") output = parser.add_mutually_exclusive_group(required=False) output.add_argument('--records', help=('optional flag that causes the output file to ' 'be a CSV-formatted file containing for each ' 'INPUT filing unit the TAXYEAR values of each ' 'variable in the Records.VALID_READ_VARS set. ' 'If the --records option is specified, the ' 'output file name will be the same as if the ' 'option was not specified, except that the ' '".out-inctax" part is replaced by ".records"'), default=False, action="store_true") output.add_argument('--csvdump', help=('optional flag that causes the output file to ' 'be a CSV-formatted file containing for each ' 'INPUT filing unit the TAXYEAR values of each ' 'variable in the Records.VALID_READ_VARS set ' 'and in the Records.CALCULATED_VARS set. ' 'If the --csvdump option is specified, the ' 'output file name will be the same as if the ' 'option was not specified, except that the ' '".out-inctax" part is replaced by ".csvdump"'), default=False, action="store_true") parser.add_argument('INPUT', nargs='?', default='', help=('INPUT is name of required CSV file that ' 'contains a subset of variables included in ' 'the Records.VALID_READ_VARS set. ' 'INPUT must end in ".csv".')) parser.add_argument('TAXYEAR', nargs='?', default=0, help=('TAXYEAR is calendar year for which federal ' 'income taxes are computed (e.g., 2013).'), type=int) args = parser.parse_args() # optionally show INPUT and OUTPUT variable definitions and exit if args.iohelp: IncomeTaxIO.show_iovar_definitions() return 0 # check INPUT filename if args.INPUT == '': sys.stderr.write('ERROR: must specify INPUT file name;\n') sys.stderr.write('USAGE: python inctax.py --help\n') return 1 # check TAXYEAR value if args.TAXYEAR == 0: sys.stderr.write('ERROR: must specify TAXYEAR >= 2013;\n') sys.stderr.write('USAGE: python inctax.py --help\n') return 1 # instantiate IncometaxIO object and do federal income tax calculations inctax = IncomeTaxIO(input_data=args.INPUT, tax_year=args.TAXYEAR, policy_reform=args.reform, exact_calculations=args.exact, blowup_input_data=args.blowup, output_weights=args.weights, output_records=args.records, csv_dump=args.csvdump) if args.records: inctax.output_records(writing_output_file=True) elif args.csvdump: inctax.csv_dump(writing_output_file=True) else: inctax.calculate(writing_output_file=True, output_weights=args.weights) # return no-error exit code return 0
def main(): """ Contains command-line interface to the Tax-Calculator IncomeTaxIO class. """ # parse command-line arguments: parser = argparse.ArgumentParser( prog='python inctax.py', description=('Writes to a file the federal income tax OUTPUT for the ' 'tax filing units specified in the INPUT file with the ' 'OUTPUT computed from the INPUT for the TAXYEAR using ' 'the Tax-Calculator. ' 'The INPUT file is a CSV-formatted file that contains ' 'variable names that include the Records.MUST_READ_VARS ' 'set plus other variables. The OUTPUT file is in ' 'Internet-TAXSIM format. The OUTPUT filename is the ' 'INPUT filename (excluding the .csv suffix or ' '.gz suffix, or both) followed by ' 'a string equal to "-YY" (where the YY is the last two ' 'digits in the TAXYEAR) and all that is followed by a ' 'trailing string. The trailing string is ".out-inctax" ' 'if no --reform option is specified; otherwise the ' 'trailing string is ".out-inctax-REFORM" (excluding any ' '".json" ending to the REFORM filename). The OUTPUT ' 'file contains the first 28 Internet-TAXSIM output ' 'variables. Use --iohelp flag for more information. ' 'For details on the Internet-TAXSIM version 9.3 ' 'OUTPUT format, go to ' 'http://users.nber.org/~taxsim/taxsim-calc9/')) parser.add_argument('--iohelp', help=('optional flag to show INPUT and OUTPUT ' 'variable definitions and exit'), default=False, action="store_true") parser.add_argument('--reform', help=('REFORM is name of optional file that contains ' 'tax reform provisions; the provisions are ' 'specified using JSON that may include ' '//-comments. No REFORM filename implies use ' 'of current-law policy.'), default=None) parser.add_argument('--exact', help=('optional flag to suppress smoothing in income ' 'tax calculations that eliminate marginal-tax-' 'rate-complicating "stair-steps". The default ' 'is to smooth, and therefore, not to do the ' ' exact calculations called for in the tax ' 'law.'), default=False, action="store_true") parser.add_argument('--blowup', help=('optional flag that triggers the default ' 'blowup (or aging) logic built ' 'into the Tax-Calculator that will age the ' 'INPUT data from Records.PUF_YEAR to TAXYEAR. ' 'No --blowup option implies INPUT data are ' 'considered raw data that are not aged or ' 'adjusted in any way.'), default=False, action="store_true") parser.add_argument('--weights', help=('optional flag that causes OUTPUT to have an ' 'additional variable [29] containing the s006 ' 'sample weight, which will be aged if the ' '--blowup option is used'), default=False, action="store_true") output = parser.add_mutually_exclusive_group(required=False) output.add_argument('--records', help=('optional flag that causes the output file to ' 'be a CSV-formatted file containing for each ' 'INPUT filing unit the TAXYEAR values of each ' 'variable in the Records.USABLE_READ_VARS set. ' 'If the --records option is specified, the ' 'output file name will be the same as if the ' 'option was not specified, except that the ' '".out-inctax" part is replaced by ".records"'), default=False, action="store_true") output.add_argument('--csvdump', help=('optional flag that causes the output file to ' 'be a CSV-formatted file containing for each ' 'INPUT filing unit the TAXYEAR values of each ' 'variable in the Records.USABLE_READ_VARS set ' 'and in the Records.CALCULATED_VARS set. ' 'If the --csvdump option is specified, the ' 'output file name will be the same as if the ' 'option was not specified, except that the ' '".out-inctax" part is replaced by ".csvdump"'), default=False, action="store_true") parser.add_argument('INPUT', nargs='?', default='', help=('INPUT is name of required CSV file that ' 'contains a subset of variables included in ' 'the Records.USABLE_READ_VARS set. ' 'INPUT must end in ".csv".')) parser.add_argument('TAXYEAR', nargs='?', default=0, help=('TAXYEAR is calendar year for which federal ' 'income taxes are computed (e.g., 2013).'), type=int) args = parser.parse_args() # optionally show INPUT and OUTPUT variable definitions and exit if args.iohelp: IncomeTaxIO.show_iovar_definitions() return 0 # check INPUT filename if args.INPUT == '': sys.stderr.write('ERROR: must specify INPUT file name;\n') sys.stderr.write('USAGE: python inctax.py --help\n') return 1 # check TAXYEAR value if args.TAXYEAR == 0: sys.stderr.write('ERROR: must specify TAXYEAR >= 2013;\n') sys.stderr.write('USAGE: python inctax.py --help\n') return 1 # instantiate IncometaxIO object and do federal income tax calculations inctax = IncomeTaxIO(input_data=args.INPUT, tax_year=args.TAXYEAR, policy_reform=args.reform, exact_calculations=args.exact, blowup_input_data=args.blowup, output_weights=args.weights, output_records=args.records, csv_dump=args.csvdump) if args.records: inctax.output_records(writing_output_file=True) elif args.csvdump: inctax.calculate(writing_output_file=False, exact_output=args.exact, output_weights=args.weights) inctax.csv_dump(writing_output_file=True) else: inctax.calculate(writing_output_file=True, exact_output=args.exact, output_weights=args.weights) # return no-error exit code return 0
def main(): """ Contains command-line interface to the Tax-Calculator IncomeTaxIO class. """ # parse command-line arguments: parser = argparse.ArgumentParser( prog='python inctax.py', description=('Writes to a file the federal income tax OUTPUT for the ' 'tax filing units specified in the INPUT file with the ' 'OUTPUT computed from the INPUT for the TAXYEAR using ' 'the Tax-Calculator. ' 'The INPUT file is a CSV-formatted file that contains ' 'variable names that are a subset of the ' 'Records.VALID_READ_VARS set. The OUTPUT file is in ' 'Internet-TAXSIM format. The OUTPUT filename is the ' 'INPUT filename (excluding the .csv suffix or ' '.gz suffix, or both) followed by ' 'a string equal to "-YY" (where the YY is the last two ' 'digits in the TAXYEAR) and all that is followed by a ' 'trailing string. The trailing string is ".out-inctax" ' 'if no --reform option is specified; otherwise the ' 'trailing string is ".out-inctax-REFORM" (excluding any ' '".json" ending to the REFORM filename). The OUTPUT ' 'file contains the first 28 Internet-TAXSIM output ' 'variables. Use --iohelp flag for more information. ' 'For details on the Internet-TAXSIM version 9.3 ' 'OUTPUT format, go to ' 'http://users.nber.org/~taxsim/taxsim-calc9/')) parser.add_argument('--iohelp', help=('optional flag to show INPUT and OUTPUT ' 'variable definitions and exit without trying ' 'to read the INPUT file, so INPUT and TAXYEAR ' 'can be any meaningless pair of character (as ' 'long as the second character is a digit) ' '(e.g., "i 0" or "x 1" or ". 9")'), default=False, action="store_true") parser.add_argument('--reform', help=('REFORM is name of optional file that contains ' 'tax reform provisions; the provisions are ' 'specified using JSON that may include ' '//-comments. No REFORM filename implies use ' 'of current-law policy.'), default=None) parser.add_argument('--blowup', help=('optional flag that triggers the default ' 'imputation and blowup (or aging) logic built ' 'into the Tax-Calculator that will age the ' 'INPUT data from Records.PUF_YEAR to TAXYEAR. ' 'No --blowup option implies INPUT data are ' 'considered raw data that are not aged or ' 'adjusted in any way.'), default=False, action="store_true") parser.add_argument('--weights', help=('optional flag that causes OUTPUT to have an ' 'additional variable [29] containing the s006 ' 'sample weight, which will be aged if the ' '--blowup option is used'), default=False, action="store_true") parser.add_argument('INPUT', help=('INPUT is name of required CSV file that ' 'contains a subset of variables included in ' 'the Records.VALID_READ_VARS set. ' 'INPUT must end in ".csv".')) parser.add_argument('TAXYEAR', help=('TAXYEAR is calendar year for which federal ' 'income taxes are computed (e.g., 2013).'), type=int) args = parser.parse_args() # optionally show INPUT and OUTPUT variable definitions and exit if args.iohelp: IncomeTaxIO.show_iovar_definitions() return 0 # instantiate IncometaxIO object and do federal income tax calculations inctax = IncomeTaxIO(input_data=args.INPUT, tax_year=args.TAXYEAR, policy_reform=args.reform, blowup_input_data=args.blowup) inctax.calculate(writing_output_file=True, output_weights=args.weights) # return no-error exit code return 0
def main(): """ Contains command-line interface to the Tax-Calculator IncomeTaxIO class. """ # parse command-line arguments: parser = argparse.ArgumentParser( prog='python inctax.py', description=('Writes to a file the federal income tax OUTPUT for the ' 'tax filing units specified in the INPUT file with the ' 'OUTPUT computed from the INPUT for the TAXYEAR using ' 'the Tax-Calculator. ' 'The INPUT file is a CSV-formatted file that contains ' 'variable names that are a subset of the ' 'Records.VALID_READ_VARS set. The OUTPUT file is in ' 'Internet-TAXSIM format. The OUTPUT filename is the ' 'INPUT filename (excluding the .csv suffix or ' '.gz suffix, or both) followed by ' 'a string equal to "-YY" (where the YY is the last two ' 'digits in the TAXYEAR) and all that is followed by a ' 'trailing string. The trailing string is ".out-inctax" ' 'if no --reform option is specified; otherwise the ' 'trailing string is ".out-inctax-REFORM" (excluding any ' '".json" ending to the REFORM filename). The OUTPUT ' 'file contains the first 28 Internet-TAXSIM output ' 'variables. Use --iohelp flag for more information. ' 'For details on the Internet-TAXSIM version 9.3 ' 'OUTPUT format, go to ' 'http://users.nber.org/~taxsim/taxsim-calc9/')) parser.add_argument('--iohelp', help=('optional flag to show INPUT and OUTPUT ' 'variable definitions and exit without trying ' 'to read the INPUT file, so INPUT and TAXYEAR ' 'can be any meaningless pair of character (as ' 'long as the second character is a digit) ' '(e.g., "i 0" or "x 1" or ". 9")'), default=False, action="store_true") parser.add_argument('--reform', help=('REFORM is name of optional file that contains ' 'tax reform provisions; the provisions are ' 'specified using JSON that may include ' '//-comments. No REFORM filename implies use ' 'of current-law policy.'), default=None) parser.add_argument('--blowup', help=('optional flag that triggers the default ' 'imputation and blowup (or aging) logic built ' 'into the Tax-Calculator that will age the ' 'INPUT data from Records.PUF_YEAR to TAXYEAR. ' 'No --blowup option implies INPUT data are ' 'considered raw data that are not aged or ' 'adjusted in any way.'), default=False, action="store_true") parser.add_argument('--weights', help=('optional flag that causes OUTPUT to have an ' 'additional variable [29] containing the s006 ' 'sample weight, which will be aged if the ' '--blowup option is used'), default=False, action="store_true") parser.add_argument('--records', help=('optional flag that causes the output file to ' 'be a CSV-formatted file containing for each ' 'INPUT filing unit the TAXYEAR values of each ' 'variable in the Records.VALID_READ_VARS set. ' 'If the --records option is specified, the ' 'output file name will be the same as if the ' 'option was not specified, except that the ' '".out-inctax" part is replaced by ".records"'), default=False, action="store_true") parser.add_argument('INPUT', help=('INPUT is name of required CSV file that ' 'contains a subset of variables included in ' 'the Records.VALID_READ_VARS set. ' 'INPUT must end in ".csv".')) parser.add_argument('TAXYEAR', help=('TAXYEAR is calendar year for which federal ' 'income taxes are computed (e.g., 2013).'), type=int) args = parser.parse_args() # optionally show INPUT and OUTPUT variable definitions and exit if args.iohelp: IncomeTaxIO.show_iovar_definitions() return 0 # instantiate IncometaxIO object and do federal income tax calculations inctax = IncomeTaxIO(input_data=args.INPUT, tax_year=args.TAXYEAR, policy_reform=args.reform, blowup_input_data=args.blowup, output_records=args.records) if args.records: inctax.output_records(writing_output_file=True) else: inctax.calculate(writing_output_file=True, output_weights=args.weights) # return no-error exit code return 0
def main(): """ Contains command-line interface to the Tax-Calculator IncomeTaxIO class. """ # parse command-line arguments: parser = argparse.ArgumentParser( prog="python inctax.py", description=( "Writes to a file the federal income tax OUTPUT for the " "tax filing units specified in the INPUT file with the " "OUTPUT computed from the INPUT for the TAXYEAR using " "the Tax-Calculator. " "The INPUT file is a CSV-formatted file that includes " "a subset of IRS-SOI PUF variables. The OUTPUT file uses " "Internet-TAXSIM format. The OUTPUT filename is the " "INPUT filename (excluding the .csv suffix, the .csv.gz " "suffix, or the .gz suffix) followed by " 'a string equal to "-YY" (where the YY is the last two ' "digits in the TAXYEAR) and all that is followed by a " 'trailing string. The trailing string is ".out-inctax" ' "if no --reform option is specified; otherwise the " 'trailing string is ".out-inctax-REFORM" (excluding any ' '".json" ending to the REFORM filename). The OUTPUT ' "file contains the first 28 Internet-TAXSIM output " "variables. Use --iohelp flag for more information. " "For details on the Internet-TAXSIM version 9.3 " "OUTPUT format, go to " "http://users.nber.org/~taxsim/taxsim-calc9/" ), ) parser.add_argument( "--iohelp", help=( "optional flag to show INPUT and OUTPUT " "variable definitions and exit without trying " "to read the INPUT file, so INPUT and TAXYEAR " "can be any meaningless pair of character (as " "long as the second character is a digit) " '(e.g., "i 0" or "x 1" or ". 9")' ), default=False, action="store_true", ) parser.add_argument( "--reform", help=( "REFORM is name of optional file that contains " "tax reform provisions; the provisions are " "specified using JSON that may include " "//-comments. No REFORM filename implies use " "of current-law policy." ), default=None, ) parser.add_argument( "--mtrinc", help=( "MTRINC is name of income type for which " "marginal tax rates are computed. No MTRINC " "implies using taxpayer earnings as the income " "type for which to compute marginal tax rates." ), default="e00200p", ) parser.add_argument( "--blowup", help=( "optional flag that causes INPUT variables to " "be aged using default blowup factors from the " "year of the INPUT data to the TAXYEAR. No " "--blowup option implies INPUT data are not " "adjusted in any way." ), default=False, action="store_true", ) parser.add_argument( "INPUT", help=( "INPUT is name of required CSV file that " "contains a subset of IRS-SOI PUF variables. " "The CSV file may be included in a compressed " 'GZIP file with the name ending in ".gz".' ), ) parser.add_argument( "TAXYEAR", help=("TAXYEAR is calendar year for which income " "taxes are computed (e.g., 2013)."), type=int ) args = parser.parse_args() # optionally show INPUT and OUTPUT variable definitions and exit if args.iohelp: IncomeTaxIO.show_iovar_definitions() return 0 # instantiate IncometaxIO object and do tax calculations inctax = IncomeTaxIO( input_filename=args.INPUT, tax_year=args.TAXYEAR, reform_filename=args.reform, blowup_input_data=args.blowup ) inctax.calculate(mtr_inctype=args.mtrinc) # return no-error exit code return 0