Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TaxBrain does not work like Tax-Calculator #427

Closed
martinholmer opened this issue Dec 5, 2016 · 2 comments
Closed

TaxBrain does not work like Tax-Calculator #427

martinholmer opened this issue Dec 5, 2016 · 2 comments
Assignees
Milestone

Comments

@martinholmer
Copy link
Contributor

martinholmer commented Dec 5, 2016

The discussion of Tax-Calculator pull request 1081 has generated this TaxBrain question/bug-report.

The issue is that TaxBrain does not handle certain tax reforms in the same way as they are handled by (a) Tax-Calculator with the reform specified as a reform dictionary, (b) Tax-Calculator with the reform specified as a JSON reform file, and (c) TaxBrain with the reform uploaded as a JSON reform file. Below I show the difference in results between, on the one hand, using TaxBrain's traditional input page to specify the reform and, on the one hand, the three other ways of specifying that reform. The fact that there is any difference in results between these four ways of specifying the same reform represents, in my mind, a bug. The results generated for a reform should be consistent across all the four ways of using Tax-Calculator. Because I always get lost in the maze of the webapp-public repo, I have no idea why the traditional TaxBrain input way of using Tax-Calculator does not produce the same results as the other three ways of using Tax-Calculator. So, there is a question about why there is this difference in results across the four ways of using Tax-Calculator.

Using an example reform, I show below how the (a), (b), and (c) methods of using Tax-Calculator all produce an error message and stop before doing any tax calculations. Then I show that specifying this same example reform on the traditional TaxBrain input page does not generate an error, the calculations are done, and the displayed reform results are absurd. The details are below.

@talumbau @brendancol @MattHJensen @feenberg

Example Reform

Consider a highly unrealistic reform in which the total personal exemption for a filing unit beginning in 2016 is equal to XTOT*XTOT*4050 dollars (instead of the current-law value of XTOT*4050). We are going to play the role of a user who want to simulate this reform by specifying the 2016 value of the _II_em policy variable to be XTOT*4050 (instead of the current-law value of 4050). That user, if (s)he has access to the puf.csv file on their local computer, has four ways of trying to simulate that reform. Here is what happens when the user tries these four ways of specifying the reform.

(a) Using Tax-Calculator locally with the reform specified as a reform dictionary

$ cat II_em_expression.py
from taxcalc import *
pol = Policy()
ref = {2016: {"_II_em": [XTOT*4050]}}
pol.implement_reform(ref)
calc = Calculator(policy=pol, records=Records())
calc.advance_to_year(2016)
calc.calc_all()
dtable = create_diagnostic_table(calc)
print dtable
$ python II_em_expression.py | grep Exemption
Traceback (most recent call last):
  File "II_em_expression.py", line 3, in <module>
    ref = {2016: {"_II_em": [XTOT*4050]}}
NameError: name 'XTOT' is not defined

$ cat II_em_expression.py
from taxcalc import *
pol = Policy()
ref = {2016: {"_II_em": ["XTOT*4050"]}}
pol.implement_reform(ref)
calc = Calculator(policy=pol, records=Records())
calc.advance_to_year(2016)
calc.calc_all()
dtable = create_diagnostic_table(calc)
print dtable
$ python II_em_expression.py | grep Exemption
Traceback (most recent call last):
  File "II_em_expression.py", line 4, in <module>
    pol.implement_reform(ref)
  File "/Users/mrh/work/OSPC/tax-calculator/taxcalc/policy.py", line 324, in implement_reform
    self._update({year: reform[year]})
  File "/Users/mrh/work/OSPC/tax-calculator/taxcalc/parameters.py", line 351, in _update
    num_years=num_years_to_expand)
  File "/Users/mrh/work/OSPC/tax-calculator/taxcalc/parameters.py", line 539, in expand_array
    x = np.array(ParametersBase.strip_Nones(x), np.float64)
ValueError: could not convert string to float: XTOT*4050

$ cat II_em_expression.py
from taxcalc import *
pol = Policy()
ref = {2016: {"_II_em": "XTOT*4050"}}
pol.implement_reform(ref)
calc = Calculator(policy=pol, records=Records())
calc.advance_to_year(2016)
calc.calc_all()
dtable = create_diagnostic_table(calc)
print dtable
$ python II_em_expression.py | grep Exemption
Traceback (most recent call last):
  File "II_em_expression.py", line 4, in <module>
    pol.implement_reform(ref)
  File "/Users/mrh/work/OSPC/tax-calculator/taxcalc/policy.py", line 324, in implement_reform
    self._update({year: reform[year]})
  File "/Users/mrh/work/OSPC/tax-calculator/taxcalc/parameters.py", line 351, in _update
    num_years=num_years_to_expand)
  File "/Users/mrh/work/OSPC/tax-calculator/taxcalc/parameters.py", line 536, in expand_array
    raise ValueError(msg)
ValueError: expand_array expects x to be a list or numpy array

(b) Using Tax-Calculator locally with the reform specified as a JSON reform file

$ cat II_em_expression.json
{
    "_II_em": {"2016": [XTOT*4050]}
}
$ python inctax.py puf.csv 2016 --blowup --weights --reform II_em_expression.json
Traceback (most recent call last):
  ... [snip] ...
ValueError: Policy reform text below contains invalid JSON:
No JSON object could be decoded
Above location of the first error may be approximate.
The invalid JSON reform text is between the lines:
XX----.----1----.----2----.----3----.----4----.----5----.----6----.----7
01{ "_II_em": {"2016": [XTOT*4050]} }
02
XX----.----1----.----2----.----3----.----4----.----5----.----6----.----7

$ cat II_em_expression.json
{
    "_II_em": {"2016": "[XTOT*4050]"}
}
$ python inctax.py puf.csv 2016 --blowup --weights --reform II_em_expression.json
Traceback (most recent call last):
  ... [snip] ...
ValueError: expand_array expects x to be a list or numpy array

$ cat II_em_expression.json
{
    "_II_em": {"2016": ["XTOT*4050"]}
}
$ python inctax.py puf.csv 2016 --blowup --weights --reform II_em_expression.json
Traceback (most recent call last):
  ... [snip] ...
ValueError: could not convert string to float: XTOT*4050

(c) Using TaxBrain with the reform uploaded as a JSON reform file

SAME RESULTS AS IN (b)

(d) Using TaxBrain with the reform specified on the traditional input page

See complete TaxBrain tax reform results here.
Those results claim that, even though every single-member filing unit's personal exemption is the same and every multiple-member filing unit's personal exemption is larger, the amount of income tax revenue is larger (not smaller). For example, the 2016 results show income tax revenue is up by $159.3 billion. The puzzled user who looks into this absurd result would find that pre-reform personal exemptions total $1,267.3 billion in 2016, but the post-reform personal exemptions were essentially zero instead of being larger than $1,267.3 billion.

@martinholmer
Copy link
Contributor Author

A TaxBrain bug was reported in issue #427 on 04-Dec-2016. There has been at least one new TaxBrain release since then, but the bug still persists. What is the schedule for fixing this bug?

@talumbau @PeterDSteinberg @brittainhard @MattHJensen

@martinholmer
Copy link
Contributor Author

Pull request #452 resolves TaxBrain issue #427, which is being closed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants