taxcalc 5.2.0__py3-none-any.whl → 6.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- taxcalc/__init__.py +3 -3
- taxcalc/calcfunctions.py +2 -2
- taxcalc/calculator.py +4 -4
- taxcalc/cli/tc.py +16 -19
- taxcalc/data.py +2 -3
- taxcalc/decorators.py +9 -8
- taxcalc/growfactors.py +2 -1
- taxcalc/policy.py +6 -23
- taxcalc/policy_current_law.json +31 -631
- taxcalc/records.py +78 -82
- taxcalc/records_variables.json +106 -106
- taxcalc/reforms/ARPA.out.csv +9 -9
- taxcalc/taxcalcio.py +101 -77
- taxcalc/tests/conftest.py +20 -15
- taxcalc/tests/puf_var_correl_coeffs_2016.csv +24 -24
- taxcalc/tests/puf_var_wght_means_by_year.csv +11 -11
- taxcalc/tests/pufcsv_agg_expect.csv +20 -20
- taxcalc/tests/pufcsv_mtr_expect.txt +21 -21
- taxcalc/tests/reforms.json +3 -1
- taxcalc/tests/reforms_expect.csv +54 -54
- taxcalc/tests/test_4package.py +8 -9
- taxcalc/tests/test_calculator.py +55 -18
- taxcalc/tests/test_consumption.py +2 -2
- taxcalc/tests/test_cpscsv.py +2 -24
- taxcalc/tests/test_data.py +11 -3
- taxcalc/tests/test_decorators.py +57 -52
- taxcalc/tests/test_growdiff.py +2 -2
- taxcalc/tests/test_parameters.py +101 -53
- taxcalc/tests/test_policy.py +154 -154
- taxcalc/tests/test_records.py +144 -9
- taxcalc/tests/test_reforms.py +104 -104
- taxcalc/tests/test_taxcalcio.py +13 -62
- taxcalc/utils.py +3 -3
- {taxcalc-5.2.0.dist-info → taxcalc-6.0.0.dist-info}/METADATA +3 -6
- {taxcalc-5.2.0.dist-info → taxcalc-6.0.0.dist-info}/RECORD +39 -46
- taxcalc/puf_ratios.csv +0 -26
- taxcalc/puf_weights.csv.gz +0 -0
- taxcalc/reforms/clp.out.csv +0 -10
- taxcalc/tests/test_compare.py +0 -330
- taxcalc/tests/test_compatible_data.py +0 -334
- taxcalc/tests/test_puf_var_stats.py +0 -194
- taxcalc/tests/test_pufcsv.py +0 -328
- {taxcalc-5.2.0.dist-info → taxcalc-6.0.0.dist-info}/WHEEL +0 -0
- {taxcalc-5.2.0.dist-info → taxcalc-6.0.0.dist-info}/entry_points.txt +0 -0
- {taxcalc-5.2.0.dist-info → taxcalc-6.0.0.dist-info}/licenses/LICENSE +0 -0
- {taxcalc-5.2.0.dist-info → taxcalc-6.0.0.dist-info}/top_level.txt +0 -0
taxcalc/records.py
CHANGED
@@ -23,10 +23,10 @@ class Records(Data):
|
|
23
23
|
|
24
24
|
Parameters
|
25
25
|
----------
|
26
|
-
data: string or Pandas DataFrame
|
26
|
+
data: string or Pandas DataFrame or None
|
27
27
|
string describes CSV file in which records data reside;
|
28
28
|
DataFrame already contains records data;
|
29
|
-
default value is
|
29
|
+
default value is None.
|
30
30
|
NOTE: when using custom data, set this argument to a DataFrame.
|
31
31
|
NOTE: to use your own data for a specific year with Tax-Calculator,
|
32
32
|
be sure to read the documentation on creating your own data file and
|
@@ -37,29 +37,28 @@ class Records(Data):
|
|
37
37
|
NOTE: data=None is allowed but the returned instance contains only
|
38
38
|
the data variable information in the specified VARINFO file.
|
39
39
|
|
40
|
-
start_year: integer
|
40
|
+
start_year: integer or None
|
41
41
|
specifies calendar year of the input data;
|
42
|
-
|
42
|
+
default value is None.
|
43
43
|
Note that if specifying your own data (see above NOTE) as being
|
44
44
|
a custom data set, be sure to explicitly set start_year to the
|
45
45
|
custom data's calendar year.
|
46
46
|
|
47
47
|
gfactors: GrowFactors class instance or None
|
48
48
|
containing record data growth (or extrapolation) factors.
|
49
|
+
default value is None.
|
49
50
|
|
50
|
-
weights:
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
default value is filename of the PUF weights.
|
51
|
+
weights: Pandas DataFrame or None
|
52
|
+
DataFrame contains data weights;
|
53
|
+
None creates empty weights DataFrame;
|
54
|
+
default value is None
|
55
55
|
NOTE: when using custom weights, set this argument to a DataFrame.
|
56
56
|
NOTE: see weights_scale documentation below.
|
57
57
|
|
58
|
-
adjust_ratios:
|
59
|
-
|
60
|
-
DataFrame already contains transposed/no-index adjustment ratios;
|
58
|
+
adjust_ratios: Pandas DataFrame or None
|
59
|
+
DataFrame contains transposed/no-index adjustment ratios;
|
61
60
|
None creates empty adjustment-ratios DataFrame;
|
62
|
-
default value is
|
61
|
+
default value is None.
|
63
62
|
NOTE: when using custom ratios, set this argument to a DataFrame.
|
64
63
|
NOTE: if specifying a DataFrame, set adjust_ratios to my_df defined as:
|
65
64
|
my_df = pd.read_csv('<my_ratios.csv>', index_col=0).transpose()
|
@@ -75,6 +74,7 @@ class Records(Data):
|
|
75
74
|
generated in the taxdata repository use a weights_scale of 0.01,
|
76
75
|
while TMD input data generated in the tax-microdata repository
|
77
76
|
use a 1.0 weights_scale value.
|
77
|
+
default value is 0.01.
|
78
78
|
|
79
79
|
Raises
|
80
80
|
------
|
@@ -92,20 +92,12 @@ class Records(Data):
|
|
92
92
|
|
93
93
|
Notes
|
94
94
|
-----
|
95
|
-
Typical usage when using PUF input data is as follows::
|
96
|
-
|
97
|
-
recs = Records()
|
98
|
-
|
99
|
-
which uses all the default parameters of the constructor, and
|
100
|
-
therefore, imputed variables are generated to augment the data and
|
101
|
-
initial-year grow factors are applied to the data. There are
|
102
|
-
situations in which you need to specify the values of the Record
|
103
|
-
constructor's arguments, but be sure you know exactly what you are
|
104
|
-
doing when attempting this.
|
105
|
-
|
106
95
|
Use Records.cps_constructor() to get a Records object instantiated
|
107
96
|
with CPS input data developed in the taxdata repository.
|
108
97
|
|
98
|
+
Use Records.puf_constructor() to get a Records object instantiated
|
99
|
+
with PUF input data developed in the taxdata repository.
|
100
|
+
|
109
101
|
Use Records.tmd_constructor() to get a Records object instantiated
|
110
102
|
with TMD input data developed in the tax-microdata repository.
|
111
103
|
"""
|
@@ -120,20 +112,16 @@ class Records(Data):
|
|
120
112
|
CPSCSV_YEAR = 2014
|
121
113
|
TMDCSV_YEAR = 2021
|
122
114
|
|
123
|
-
PUF_WEIGHTS_FILENAME = 'puf_weights.csv.gz'
|
124
|
-
PUF_RATIOS_FILENAME = 'puf_ratios.csv'
|
125
|
-
CPS_WEIGHTS_FILENAME = 'cps_weights.csv.gz'
|
126
|
-
CPS_RATIOS_FILENAME = None
|
127
115
|
CODE_PATH = os.path.abspath(os.path.dirname(__file__))
|
128
116
|
VARINFO_FILE_NAME = 'records_variables.json'
|
129
117
|
VARINFO_FILE_PATH = CODE_PATH
|
130
118
|
|
131
119
|
def __init__(self,
|
132
|
-
data=
|
133
|
-
start_year=
|
134
|
-
gfactors=
|
135
|
-
weights=
|
136
|
-
adjust_ratios=
|
120
|
+
data=None,
|
121
|
+
start_year=None,
|
122
|
+
gfactors=None,
|
123
|
+
weights=None,
|
124
|
+
adjust_ratios=None,
|
137
125
|
exact_calculations=False,
|
138
126
|
weights_scale=0.01):
|
139
127
|
# pylint: disable=too-many-positional-arguments
|
@@ -205,32 +193,58 @@ class Records(Data):
|
|
205
193
|
raise ValueError('not all PT_SSTB_income values are 0 or 1')
|
206
194
|
|
207
195
|
@staticmethod
|
208
|
-
def cps_constructor(
|
209
|
-
|
210
|
-
|
196
|
+
def cps_constructor(
|
197
|
+
data=None,
|
198
|
+
gfactors=GrowFactors(),
|
199
|
+
exact_calculations=False
|
200
|
+
):
|
211
201
|
"""
|
212
202
|
Static method returns a Records object instantiated with CPS
|
213
|
-
input data. This
|
214
|
-
|
215
|
-
This is a convenience method that eliminates the need to
|
216
|
-
specify all the details of the CPS input data just as the
|
217
|
-
default values of the arguments of the Records class constructor
|
218
|
-
eliminate the need to specify all the details of the PUF input
|
219
|
-
data.
|
203
|
+
input data. This is a convenience method that eliminates the
|
204
|
+
need to specify all the details of the CPS input data.
|
220
205
|
"""
|
221
206
|
if data is None:
|
222
207
|
data = os.path.join(Records.CODE_PATH, 'cps.csv.gz')
|
223
208
|
if gfactors is None:
|
224
209
|
weights = None
|
225
210
|
else:
|
226
|
-
weights = os.path.join(Records.CODE_PATH,
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
211
|
+
weights = os.path.join(Records.CODE_PATH, 'cps_weights.csv.gz')
|
212
|
+
return Records(
|
213
|
+
data=data,
|
214
|
+
start_year=Records.CPSCSV_YEAR,
|
215
|
+
gfactors=gfactors,
|
216
|
+
weights=weights,
|
217
|
+
adjust_ratios=None,
|
218
|
+
exact_calculations=exact_calculations,
|
219
|
+
weights_scale=0.01,
|
220
|
+
)
|
221
|
+
|
222
|
+
@staticmethod
|
223
|
+
def puf_constructor(
|
224
|
+
data='puf.csv',
|
225
|
+
gfactors=GrowFactors(),
|
226
|
+
weights='puf_weights.csv.gz',
|
227
|
+
ratios='puf_ratios.csv',
|
228
|
+
exact_calculations=False
|
229
|
+
): # pragma: no cover
|
230
|
+
"""
|
231
|
+
Static method returns a Records object instantiated with PUF
|
232
|
+
input data. This is a convenience method that eliminates the
|
233
|
+
need to specify all the details of the PUF input data.
|
234
|
+
"""
|
235
|
+
assert isinstance(data, str)
|
236
|
+
assert isinstance(gfactors, GrowFactors)
|
237
|
+
assert isinstance(weights, str)
|
238
|
+
assert isinstance(ratios, str)
|
239
|
+
return Records(
|
240
|
+
data=pd.read_csv(data),
|
241
|
+
start_year=Records.PUFCSV_YEAR,
|
242
|
+
gfactors=gfactors,
|
243
|
+
weights=pd.read_csv(weights),
|
244
|
+
adjust_ratios=pd.read_csv(ratios, index_col=0).transpose(),
|
245
|
+
exact_calculations=exact_calculations,
|
246
|
+
weights_scale=0.01,
|
247
|
+
)
|
234
248
|
|
235
249
|
@staticmethod
|
236
250
|
def tmd_constructor(
|
@@ -241,13 +255,8 @@ class Records(Data):
|
|
241
255
|
): # pragma: no cover
|
242
256
|
"""
|
243
257
|
Static method returns a Records object instantiated with TMD
|
244
|
-
input data. This
|
245
|
-
|
246
|
-
This is a convenience method that eliminates the need to
|
247
|
-
specify all the details of the TMD input data just as the
|
248
|
-
default values of the arguments of the Records class constructor
|
249
|
-
eliminate the need to specify all the details of the PUF input
|
250
|
-
data.
|
258
|
+
input data. This is a convenience method that eliminates the
|
259
|
+
need to specify all the details of the TMD input data.
|
251
260
|
"""
|
252
261
|
assert isinstance(data_path, Path)
|
253
262
|
assert isinstance(weights_path, Path)
|
@@ -395,42 +404,29 @@ class Records(Data):
|
|
395
404
|
|
396
405
|
def _adjust(self, year):
|
397
406
|
"""
|
398
|
-
Adjust value of income variables to match SOI distributions
|
407
|
+
Adjust value of PUF income variables to match SOI distributions
|
399
408
|
Note: adjustment must leave variables as numpy.ndarray type
|
400
409
|
"""
|
401
410
|
# pylint: disable=no-member
|
402
|
-
if self.ADJ.size > 0:
|
411
|
+
if self.ADJ.size > 0: # pragma: no cover
|
403
412
|
# Interest income
|
404
413
|
self.e00300 *= self.ADJ[f'INT{year}'].iloc[self.agi_bin].values
|
405
414
|
|
406
415
|
def _read_ratios(self, ratios):
|
407
416
|
"""
|
408
|
-
Read Records adjustment ratios
|
409
|
-
|
410
|
-
create empty DataFrame if None
|
417
|
+
Read Records PUF-related adjustment ratios using
|
418
|
+
specified transposed/no-index DataFrame as ratios or
|
419
|
+
create empty DataFrame if ratios is None.
|
411
420
|
"""
|
421
|
+
assert ratios is None or isinstance(ratios, pd.DataFrame)
|
412
422
|
if ratios is None:
|
413
423
|
setattr(self, 'ADJ', pd.DataFrame({'nothing': []}))
|
414
424
|
return
|
415
|
-
if isinstance(ratios, pd.DataFrame):
|
425
|
+
if isinstance(ratios, pd.DataFrame): # pragma: no cover
|
416
426
|
assert 'INT2013' in ratios.columns # check for transposed
|
417
427
|
assert ratios.index.name is None # check for no-index
|
418
428
|
ADJ = ratios
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
index_col=0)
|
424
|
-
else: # find file in conda package
|
425
|
-
ADJ = read_egg_csv(os.path.basename(ratios_path),
|
426
|
-
index_col=0) # pragma: no cover
|
427
|
-
ADJ = ADJ.transpose()
|
428
|
-
else:
|
429
|
-
msg = 'ratios is neither None nor a Pandas DataFrame nor a string'
|
430
|
-
raise ValueError(msg)
|
431
|
-
assert isinstance(ADJ, pd.DataFrame)
|
432
|
-
if ADJ.index.name != 'agi_bin':
|
433
|
-
ADJ.index.name = 'agi_bin'
|
434
|
-
self.ADJ = pd.DataFrame()
|
435
|
-
setattr(self, 'ADJ', ADJ.astype(np.float32))
|
436
|
-
del ADJ
|
429
|
+
self.ADJ = pd.DataFrame()
|
430
|
+
if ADJ.index.name != 'agi_bin':
|
431
|
+
ADJ.index.name = 'agi_bin'
|
432
|
+
setattr(self, 'ADJ', ADJ.astype(np.float32))
|