taxcalc 5.1.0__py3-none-any.whl → 5.3.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.
Files changed (44) hide show
  1. taxcalc/__init__.py +3 -3
  2. taxcalc/calcfunctions.py +21 -16
  3. taxcalc/calculator.py +3 -3
  4. taxcalc/cli/tc.py +15 -11
  5. taxcalc/data.py +1 -1
  6. taxcalc/decorators.py +9 -8
  7. taxcalc/growfactors.py +2 -1
  8. taxcalc/policy.py +13 -5
  9. taxcalc/policy_current_law.json +1191 -1395
  10. taxcalc/puf_ratios.csv +24 -24
  11. taxcalc/puf_weights.csv.gz +0 -0
  12. taxcalc/reforms/2017_law.json +2 -0
  13. taxcalc/reforms/ARPA.out.csv +9 -9
  14. taxcalc/taxcalcio.py +41 -26
  15. taxcalc/tests/conftest.py +1 -1
  16. taxcalc/tests/cpscsv_agg_expect.csv +26 -26
  17. taxcalc/tests/puf_var_correl_coeffs_2016.csv +24 -24
  18. taxcalc/tests/puf_var_wght_means_by_year.csv +80 -80
  19. taxcalc/tests/pufcsv_agg_expect.csv +26 -26
  20. taxcalc/tests/pufcsv_mtr_expect.txt +21 -21
  21. taxcalc/tests/reforms.json +3 -1
  22. taxcalc/tests/reforms_expect.csv +48 -48
  23. taxcalc/tests/test_4package.py +8 -9
  24. taxcalc/tests/test_calculator.py +152 -151
  25. taxcalc/tests/test_compare.py +2 -2
  26. taxcalc/tests/test_consumption.py +2 -2
  27. taxcalc/tests/test_cpscsv.py +4 -3
  28. taxcalc/tests/test_decorators.py +57 -52
  29. taxcalc/tests/test_growdiff.py +2 -2
  30. taxcalc/tests/test_parameters.py +59 -53
  31. taxcalc/tests/test_policy.py +229 -251
  32. taxcalc/tests/test_puf_var_stats.py +2 -2
  33. taxcalc/tests/test_pufcsv.py +5 -4
  34. taxcalc/tests/test_records.py +5 -1
  35. taxcalc/tests/test_reforms.py +101 -99
  36. taxcalc/tests/test_taxcalcio.py +10 -4
  37. taxcalc/utils.py +3 -3
  38. {taxcalc-5.1.0.dist-info → taxcalc-5.3.0.dist-info}/METADATA +3 -6
  39. {taxcalc-5.1.0.dist-info → taxcalc-5.3.0.dist-info}/RECORD +43 -44
  40. taxcalc/reforms/clp.out.csv +0 -10
  41. {taxcalc-5.1.0.dist-info → taxcalc-5.3.0.dist-info}/WHEEL +0 -0
  42. {taxcalc-5.1.0.dist-info → taxcalc-5.3.0.dist-info}/entry_points.txt +0 -0
  43. {taxcalc-5.1.0.dist-info → taxcalc-5.3.0.dist-info}/licenses/LICENSE +0 -0
  44. {taxcalc-5.1.0.dist-info → taxcalc-5.3.0.dist-info}/top_level.txt +0 -0
@@ -54,14 +54,15 @@ def test_incorrect_implement_reform_usage():
54
54
  with pytest.raises(paramtools.ValidationError):
55
55
  pol.implement_reform([])
56
56
  with pytest.raises(paramtools.ValidationError):
57
- pol.implement_reform({2099: {'II_em': 99000}})
57
+ pol.implement_reform({2099: {"II_em": 99000}})
58
58
  pol.set_year(2019)
59
59
  with pytest.raises(paramtools.ValidationError):
60
- pol.implement_reform({2018: {'II_em': 99000}})
60
+ pol.implement_reform({2018: {"II_em": 99000}})
61
61
  with pytest.raises(paramtools.ValidationError):
62
- pol.implement_reform({2020: {'II_em': -1000}})
62
+ pol.implement_reform({2020: {"II_em": -1000}})
63
63
 
64
64
 
65
+ @pytest.mark.local
65
66
  def test_json_reform_url():
66
67
  """
67
68
  Test reading a JSON reform from a URL. Results from the URL are expected
@@ -89,8 +90,8 @@ def test_json_reform_url():
89
90
  }
90
91
  }
91
92
  """
92
- reform_url = ('https://raw.githubusercontent.com/PSLmodels/'
93
- 'Tax-Calculator/master/taxcalc/reforms/ptaxes0.json')
93
+ reform_url = ("https://raw.githubusercontent.com/PSLmodels/"
94
+ "Tax-Calculator/master/taxcalc/reforms/ptaxes0.json")
94
95
  params_str = Policy.read_json_reform(reform_str)
95
96
  params_url = Policy.read_json_reform(reform_url)
96
97
  assert params_str == params_url
@@ -191,7 +192,7 @@ def test_constant_inflation_rate_with_reform():
191
192
  fyr = 2034
192
193
  ryr = fyr - 1
193
194
  reform = {
194
- 'II_em': {(ryr - 3): 1000, # to avoid divide-by-zero under TCJA
195
+ "II_em": {(ryr - 3): 1000, # to avoid divide-by-zero under TCJA
195
196
  ryr: 20000}
196
197
  }
197
198
  pol.implement_reform(reform)
@@ -217,7 +218,7 @@ def test_variable_inflation_rate_with_reform():
217
218
  assert pol._II_em[2013 - syr] == 3900
218
219
  # implement reform in 2020 which is two years before the last year, 2022
219
220
  reform = {
220
- 'II_em': {2018: 1000, # to avoid divide-by-zero under TCJA
221
+ "II_em": {2018: 1000, # to avoid divide-by-zero under TCJA
221
222
  2020: 20000}
222
223
  }
223
224
  pol.implement_reform(reform)
@@ -257,15 +258,14 @@ def test_multi_year_reform():
257
258
  wfactor[syr + i] = 1.0 + wratelist[i]
258
259
  # specify multi-year reform using a param:year:value-fomatted dictionary
259
260
  reform = {
260
- 'SS_Earnings_c': {2016: 300000,
261
+ "SS_Earnings_c": {2016: 300000,
261
262
  2017: 500000,
262
263
  2019: 700000},
263
- 'SS_Earnings_c-indexed': {2017: False,
264
+ "SS_Earnings_c-indexed": {2017: False,
264
265
  2019: True},
265
- 'CTC_c': {2015: 2000},
266
- 'EITC_c': {2016: [900, 5000, 8000, 9000],
266
+ "EITC_c": {2016: [900, 5000, 8000, 9000],
267
267
  2019: [1200, 7000, 10000, 12000]},
268
- 'II_em': {2016: 7000,
268
+ "II_em": {2016: 7000,
269
269
  2019: 9000}
270
270
  }
271
271
  # implement multi-year reform
@@ -280,42 +280,16 @@ def test_multi_year_reform():
280
280
  check_eitc_c(pol, reform, ifactor)
281
281
  check_ii_em(pol, reform, ifactor)
282
282
  check_ss_earnings_c(pol, reform, wfactor)
283
- check_ctc_c(pol, reform)
284
283
  # end of test_multi_year_reform with the check_* functions below:
285
284
 
286
285
 
287
- def check_ctc_c(ppo, reform):
288
- """
289
- Compare actual and expected _CTC_c parameter values
290
- generated by the test_multi_year_reform() function above.
291
- Ensure that future-year values in policy_current_law.json
292
- are overwritten by reform.
293
- """
294
- actual = {}
295
- arr = getattr(ppo, '_CTC_c')
296
- for i in range(0, ppo.num_years):
297
- actual[ppo.start_year + i] = arr[i]
298
- assert actual[2013] == 1000
299
- assert actual[2014] == 1000
300
- e2015 = reform['CTC_c'][2015]
301
- assert actual[2015] == e2015
302
- e2016 = actual[2015]
303
- assert actual[2016] == e2016
304
- e2017 = actual[2016]
305
- assert actual[2017] == e2017
306
- e2018 = actual[2017]
307
- assert actual[2018] == e2018
308
- e2019 = actual[2018]
309
- assert actual[2019] == e2019
310
-
311
-
312
286
  def check_eitc_c(ppo, reform, ifactor):
313
287
  """
314
288
  Compare actual and expected _EITC_c parameter values
315
289
  generated by the test_multi_year_reform() function above.
316
290
  """
317
291
  actual = {}
318
- arr = getattr(ppo, '_EITC_c')
292
+ arr = getattr(ppo, "_EITC_c")
319
293
  alen = len(arr[0])
320
294
  for i in range(0, ppo.num_years):
321
295
  actual[ppo.start_year + i] = arr[i]
@@ -325,13 +299,13 @@ def check_eitc_c(ppo, reform, ifactor):
325
299
  atol=0.01, rtol=0.0)
326
300
  assert np.allclose(actual[2015], [503, 3359, 5548, 6242],
327
301
  atol=0.01, rtol=0.0)
328
- e2016 = reform['EITC_c'][2016]
302
+ e2016 = reform["EITC_c"][2016]
329
303
  assert np.allclose(actual[2016], e2016, atol=0.01, rtol=0.0)
330
304
  e2017 = [ifactor[2016] * actual[2016][j] for j in range(0, alen)]
331
305
  assert np.allclose(actual[2017], e2017, atol=0.01, rtol=0.0)
332
306
  e2018 = [ifactor[2017] * actual[2017][j] for j in range(0, alen)]
333
307
  assert np.allclose(actual[2018], e2018, atol=0.01, rtol=0.0)
334
- e2019 = reform['EITC_c'][2019]
308
+ e2019 = reform["EITC_c"][2019]
335
309
  assert np.allclose(actual[2019], e2019, atol=0.01, rtol=0.0)
336
310
  e2020 = [ifactor[2019] * actual[2019][j] for j in range(0, alen)]
337
311
  assert np.allclose(actual[2020], e2020, atol=0.01, rtol=0.0)
@@ -347,19 +321,19 @@ def check_ii_em(ppo, reform, ifactor):
347
321
  generated by the test_multi_year_reform() function above.
348
322
  """
349
323
  actual = {}
350
- arr = getattr(ppo, '_II_em')
324
+ arr = getattr(ppo, "_II_em")
351
325
  for i in range(0, ppo.num_years):
352
326
  actual[ppo.start_year + i] = arr[i]
353
327
  assert actual[2013] == 3900
354
328
  assert actual[2014] == 3950
355
329
  assert actual[2015] == 4000
356
- e2016 = reform['II_em'][2016]
330
+ e2016 = reform["II_em"][2016]
357
331
  assert actual[2016] == e2016
358
332
  e2017 = ifactor[2016] * actual[2016]
359
333
  assert np.allclose([actual[2017]], [e2017], atol=0.01, rtol=0.0)
360
334
  e2018 = ifactor[2017] * actual[2017]
361
335
  assert np.allclose([actual[2018]], [e2018], atol=0.01, rtol=0.0)
362
- e2019 = reform['II_em'][2019]
336
+ e2019 = reform["II_em"][2019]
363
337
  assert actual[2019] == e2019
364
338
  e2020 = ifactor[2019] * actual[2019]
365
339
  assert np.allclose([actual[2020]], [e2020], atol=0.01, rtol=0.0)
@@ -375,19 +349,19 @@ def check_ss_earnings_c(ppo, reform, wfactor):
375
349
  generated by the test_multi_year_reform() function above.
376
350
  """
377
351
  actual = {}
378
- arr = getattr(ppo, '_SS_Earnings_c')
352
+ arr = getattr(ppo, "_SS_Earnings_c")
379
353
  for i in range(0, ppo.num_years):
380
354
  actual[ppo.start_year + i] = arr[i]
381
355
  assert actual[2013] == 113700
382
356
  assert actual[2014] == 117000
383
357
  assert actual[2015] == 118500
384
- e2016 = reform['SS_Earnings_c'][2016]
358
+ e2016 = reform["SS_Earnings_c"][2016]
385
359
  assert actual[2016] == e2016
386
- e2017 = reform['SS_Earnings_c'][2017]
360
+ e2017 = reform["SS_Earnings_c"][2017]
387
361
  assert actual[2017] == e2017
388
362
  e2018 = actual[2017] # no indexing after 2017
389
363
  assert actual[2018] == e2018
390
- e2019 = reform['SS_Earnings_c'][2019]
364
+ e2019 = reform["SS_Earnings_c"][2019]
391
365
  assert actual[2019] == e2019
392
366
  e2020 = wfactor[2019] * actual[2019] # indexing after 2019
393
367
  assert np.allclose([actual[2020]], [e2020], atol=0.01, rtol=0.0)
@@ -410,7 +384,7 @@ def test_implement_reform_raises_on_no_year():
410
384
  """
411
385
  Test that implement_reform raises error for missing year.
412
386
  """
413
- reform = {'STD_Aged': [1400, 1200, 1400, 1400, 1400]}
387
+ reform = {"STD_Aged": [1400, 1200, 1400, 1400, 1400]}
414
388
  ppo = Policy()
415
389
  with pytest.raises(paramtools.ValidationError):
416
390
  ppo.implement_reform(reform)
@@ -421,7 +395,7 @@ def test_implement_reform_raises_on_early_year():
421
395
  Test that implement_reform raises error for early year.
422
396
  """
423
397
  ppo = Policy()
424
- reform = {'STD_Aged': {2010: [1400, 1100, 1100, 1400, 1400]}}
398
+ reform = {"STD_Aged": {2010: [1400, 1100, 1100, 1400, 1400]}}
425
399
  with pytest.raises(paramtools.ValidationError):
426
400
  ppo.implement_reform(reform)
427
401
 
@@ -431,7 +405,7 @@ def test_reform_with_default_indexed():
431
405
  Test that implement_reform indexes after first reform year.
432
406
  """
433
407
  ppo = Policy()
434
- reform = {'II_em': {2015: 4300}}
408
+ reform = {"II_em": {2015: 4300}}
435
409
  ppo.implement_reform(reform)
436
410
  # II_em has a default indexing status of true, so
437
411
  # in 2016 its value should be greater than 4300
@@ -444,7 +418,7 @@ def test_reform_makes_no_changes_before_year():
444
418
  Test that implement_reform makes no changes before first reform year.
445
419
  """
446
420
  ppo = Policy()
447
- reform = {'II_em': {2015: 4400}, 'II_em-indexed': {2015: True}}
421
+ reform = {"II_em": {2015: 4400}, "II_em-indexed": {2015: True}}
448
422
  ppo.implement_reform(reform)
449
423
  ppo.set_year(2015)
450
424
  assert np.allclose(ppo._II_em[:3], np.array([3900, 3950, 4400]),
@@ -545,7 +519,7 @@ def test_pop_the_cap_reform():
545
519
  assert mte[2015 - syr] == 118500
546
520
  assert mte[2016 - syr] == 118500
547
521
  # specify a "pop the cap" reform that eliminates MTE cap in 2016
548
- reform = {'SS_Earnings_c': {2016: 9e99}}
522
+ reform = {"SS_Earnings_c": {2016: 9e99}}
549
523
  ppo.implement_reform(reform)
550
524
  mte = ppo._SS_Earnings_c
551
525
  assert mte[2015 - syr] == 118500
@@ -561,13 +535,13 @@ def test_order_of_indexing_and_level_reforms():
561
535
  # specify two reforms that raises the MTE and stops its indexing in 2015
562
536
  reforms = [
563
537
  {
564
- 'SS_Earnings_c': {2015: 500000},
565
- 'SS_Earnings_c-indexed': {2015: False}
538
+ "SS_Earnings_c": {2015: 500000},
539
+ "SS_Earnings_c-indexed": {2015: False}
566
540
  },
567
541
  # now reverse the order of the two reform provisions
568
542
  {
569
- 'SS_Earnings_c-indexed': {2015: False},
570
- 'SS_Earnings_c': {2015: 500000}
543
+ "SS_Earnings_c-indexed": {2015: False},
544
+ "SS_Earnings_c": {2015: 500000}
571
545
  }
572
546
  ]
573
547
  # specify two Policy objects
@@ -598,12 +572,12 @@ def test_misspecified_reform_dictionary():
598
572
  """
599
573
  # specify apparently the same reform in two different ways, forgetting
600
574
  # that Python dictionaries have unique keys
601
- reform1 = {'II_em': {2019: 1000, 2020: 2000}}
575
+ reform1 = {"II_em": {2019: 1000, 2020: 2000}}
602
576
  # pylint: disable=duplicate-key
603
- reform2 = {'II_em': {2019: 1000}, 'II_em': {2020: 2000}}
577
+ reform2 = {"II_em": {2019: 1000}, "II_em": {2020: 2000}}
604
578
  # these two reform dictionaries are not the same: the second
605
- # 'II_em' key value for 2020 in reform2 OVERWRITES and REPLACES
606
- # the first 'II_em' key value for 2019 in reform2
579
+ # "II_em" key value for 2020 in reform2 OVERWRITES and REPLACES
580
+ # the first "II_em" key value for 2019 in reform2
607
581
  assert reform1 != reform2
608
582
 
609
583
 
@@ -622,114 +596,114 @@ def test_section_titles(tests_path):
622
596
  for line in md_text.splitlines():
623
597
  # This is shown as an empty case in current law policy and
624
598
  # validation.
625
- if line.startswith('## Other Parameters (not in Tax-Brain webapp'):
626
- sdict[''] = {}
627
- sdict[''][''] = 0
599
+ if line.startswith("## Other Parameters (not in Tax-Brain webapp"):
600
+ sdict[""] = {}
601
+ sdict[""][""] = 0
628
602
  continue
629
- sec2line = line.startswith('### ')
630
- sec1line = line.startswith('## ')
603
+ sec2line = line.startswith("### ")
604
+ sec1line = line.startswith("## ")
631
605
  # Create outer-layer dictionary entry for sec1.
632
606
  if sec1line:
633
- sec1 = line.replace('##', '', 1).strip()
607
+ sec1 = line.replace("##", "", 1).strip()
634
608
  sdict[sec1] = {}
635
609
  # Create inner dictionary entry for sec1-sec2.
636
610
  # Note that sec1 will have been defined from a previous loop.
637
611
  if sec2line:
638
- sec2 = line.replace('###', '', 1).strip()
612
+ sec2 = line.replace("###", "", 1).strip()
639
613
  sdict[sec1][sec2] = 0
640
614
  return sdict
641
615
  # begin main logic of test_section_titles
642
616
  # specify expected section titles ordered as on the Tax-Brain webapp
643
- cgqd_tax_same = ('Tax All Capital Gains And Dividends The Same '
644
- 'As Regular Taxable Income')
617
+ cgqd_tax_same = ("Tax All Capital Gains And Dividends The Same "
618
+ "As Regular Taxable Income")
645
619
  valid_dict = {
646
- '': { # empty section_1 implies parameter not displayed in Tax-Brain
647
- '': 0
620
+ "": { # empty section_1 implies parameter not displayed in Tax-Brain
621
+ "": 0
648
622
  },
649
- 'Parameter Indexing': {
650
- 'Offsets': 0
623
+ "Parameter Indexing": {
624
+ "Offsets": 0
651
625
  },
652
- 'Payroll Taxes': {
653
- 'Social Security FICA': 0,
654
- 'Medicare FICA': 0,
655
- 'Additional Medicare FICA': 0
626
+ "Payroll Taxes": {
627
+ "Social Security FICA": 0,
628
+ "Medicare FICA": 0,
629
+ "Additional Medicare FICA": 0
656
630
  },
657
- 'Social Security Taxability': {
658
- 'Social Security Benefit Taxability': 0,
631
+ "Social Security Taxability": {
632
+ "Social Security Benefit Taxability": 0,
659
633
  },
660
- 'Above The Line Deductions': {
661
- 'Misc. Adjustment Haircuts': 0,
662
- 'Misc. Exclusions': 0,
663
- 'Child And Elderly Care': 0
634
+ "Above The Line Deductions": {
635
+ "Misc. Adjustment Haircuts": 0,
636
+ "Misc. Exclusions": 0,
637
+ "Child And Elderly Care": 0
664
638
  },
665
- 'Personal Exemptions': {
666
- 'Personal And Dependent Exemption Amount': 0,
667
- # 'Personal Exemption Phaseout Starting Income': 0,
668
- 'Personal Exemption Phaseout Rate': 0,
669
- 'Repeal for Dependents Under Age 18': 0
639
+ "Personal Exemptions": {
640
+ "Personal And Dependent Exemption Amount": 0,
641
+ # "Personal Exemption Phaseout Starting Income": 0,
642
+ "Personal Exemption Phaseout Rate": 0,
643
+ "Repeal for Dependents Under Age 18": 0
670
644
  },
671
- 'Standard Deduction': {
672
- 'Standard Deduction Amount': 0,
673
- 'Additional Standard Deduction For Blind And Aged': 0
674
- # 'Standard Deduction For Dependents': 0
645
+ "Standard Deduction": {
646
+ "Standard Deduction Amount": 0,
647
+ "Additional Standard Deduction For Blind And Aged": 0
648
+ # "Standard Deduction For Dependents": 0
675
649
  },
676
- 'Nonrefundable Credits': {
677
- 'Misc. Credit Limits': 0,
678
- 'Child And Dependent Care': 0,
679
- 'Personal Nonrefundable Credit': 0
650
+ "Nonrefundable Credits": {
651
+ "Misc. Credit Limits": 0,
652
+ "Child And Dependent Care": 0,
653
+ "Personal Nonrefundable Credit": 0
680
654
  },
681
- 'Child/Dependent Credits': {
682
- 'Child Tax Credit': 0,
683
- 'Additional Child Tax Credit': 0,
684
- 'Other Dependent Tax Credit': 0
655
+ "Child/Dependent Credits": {
656
+ "Child Tax Credit": 0,
657
+ "Additional Child Tax Credit": 0,
658
+ "Other Dependent Tax Credit": 0
685
659
  },
686
- 'Itemized Deductions': {
687
- 'Medical Expenses': 0,
688
- 'State And Local Income And Sales Taxes': 0,
689
- 'State, Local, And Foreign Real Estate Taxes': 0,
690
- 'State And Local Taxes And Real Estate Taxes': 0,
691
- 'Interest Paid': 0,
692
- 'Charity': 0,
693
- 'Casualty': 0,
694
- 'Miscellaneous': 0,
695
- 'Itemized Deduction Limitation': 0, # Pease
696
- 'Ceiling On The Amount Of Itemized Deductions Allowed': 0 # ID_c
660
+ "Itemized Deductions": {
661
+ "Medical Expenses": 0,
662
+ "State And Local Income And Sales Taxes": 0,
663
+ "State, Local, And Foreign Real Estate Taxes": 0,
664
+ "State And Local Taxes And Real Estate Taxes": 0,
665
+ "Interest Paid": 0,
666
+ "Charity": 0,
667
+ "Casualty": 0,
668
+ "Miscellaneous": 0,
669
+ "Itemized Deduction Limitation": 0, # Pease
670
+ "Ceiling On The Amount Of Itemized Deductions Allowed": 0 # ID_c
697
671
  },
698
- 'Capital Gains And Dividends': {
699
- 'Regular - Long Term Capital Gains And Qualified Dividends': 0,
700
- 'AMT - Long Term Capital Gains And Qualified Dividends': 0,
672
+ "Capital Gains And Dividends": {
673
+ "Regular - Long Term Capital Gains And Qualified Dividends": 0,
674
+ "AMT - Long Term Capital Gains And Qualified Dividends": 0,
701
675
  cgqd_tax_same: 0
702
676
  },
703
- 'Personal Income': {
704
- 'Regular: Non-AMT': 0,
705
- 'Pass-Through': 0,
706
- 'Alternative Minimum Tax': 0
677
+ "Personal Income": {
678
+ "Regular: Non-AMT": 0,
679
+ "Pass-Through": 0,
680
+ "Alternative Minimum Tax": 0
707
681
  },
708
- 'Other Taxes': {
709
- 'Net Investment Income Tax': 0
682
+ "Other Taxes": {
683
+ "Net Investment Income Tax": 0
710
684
  },
711
- 'Refundable Credits': {
712
- 'Earned Income Tax Credit': 0,
713
- 'New Refundable Child Tax Credit': 0,
714
- 'Personal Refundable Credit': 0,
715
- 'Refundable Payroll Tax Credit': 0
685
+ "Refundable Credits": {
686
+ "Earned Income Tax Credit": 0,
687
+ "New Refundable Child Tax Credit": 0,
688
+ "Personal Refundable Credit": 0,
689
+ "Refundable Payroll Tax Credit": 0
716
690
  },
717
- 'Surtaxes': {
718
- 'New Minimum Tax': 0,
719
- 'New AGI Surtax': 0,
720
- 'Lump-Sum Tax': 0
691
+ "Surtaxes": {
692
+ "New Minimum Tax": 0,
693
+ "New AGI Surtax": 0,
694
+ "Lump-Sum Tax": 0
721
695
  },
722
- 'Universal Basic Income': {
723
- 'UBI Benefits': 0,
724
- 'UBI Taxability': 0
696
+ "Universal Basic Income": {
697
+ "UBI Benefits": 0,
698
+ "UBI Taxability": 0
725
699
  },
726
- 'Benefits': {
727
- 'Benefit Repeal': 0,
700
+ "Benefits": {
701
+ "Benefit Repeal": 0,
728
702
  }
729
703
  }
730
704
  # check validity of parameter section titles in policy_current_law.json
731
- path = os.path.join(tests_path, '..', 'policy_current_law.json')
732
- with open(path, 'r', encoding='utf-8') as clpfile:
705
+ path = os.path.join(tests_path, "..", "policy_current_law.json")
706
+ with open(path, "r", encoding="utf-8") as clpfile:
733
707
  clpdict = json.load(clpfile)
734
708
  clpdict.pop("schema", None)
735
709
  # ... make sure ever clpdict section title is in valid_dict
@@ -737,9 +711,9 @@ def test_section_titles(tests_path):
737
711
  for pname in clpdict:
738
712
  param = clpdict[pname]
739
713
  assert isinstance(param, dict)
740
- sec1title = param['section_1']
714
+ sec1title = param["section_1"]
741
715
  assert sec1title in valid_dict
742
- sec2title = param['section_2']
716
+ sec2title = param["section_2"]
743
717
  assert sec2title in valid_dict[sec1title]
744
718
  if sec1title not in clp_dict:
745
719
  clp_dict[sec1title] = {}
@@ -752,9 +726,9 @@ def test_section_titles(tests_path):
752
726
  for sec2title in secdict:
753
727
  assert sec2title in clp_dict[sec1title]
754
728
  # check validity of parameter section titles in docs/uguide.htmx skeleton
755
- path = os.path.join(tests_path, '..', '..', 'docs', 'guide',
756
- 'policy_params.md')
757
- with open(path, 'r', encoding='utf-8') as md_file:
729
+ path = os.path.join(tests_path, "..", "..", "docs", "guide",
730
+ "policy_params.md")
731
+ with open(path, "r", encoding="utf-8") as md_file:
758
732
  md_text = md_file.read()
759
733
  md_dict = generate_section_dictionary(md_text)
760
734
  # ... make sure every md_dict section title is in valid_dict
@@ -776,17 +750,17 @@ def test_description_punctuation(tests_path):
776
750
  Check that each description ends in a period.
777
751
  """
778
752
  # read JSON file into a dictionary
779
- path = os.path.join(tests_path, '..', 'policy_current_law.json')
780
- with open(path, 'r', encoding='utf-8') as jsonfile:
753
+ path = os.path.join(tests_path, "..", "policy_current_law.json")
754
+ with open(path, "r", encoding="utf-8") as jsonfile:
781
755
  dct = json.load(jsonfile)
782
756
  dct.pop("schema", None)
783
757
  all_desc_ok = True
784
758
  for param in dct.keys():
785
- if not dct[param]['description'].endswith('.'):
759
+ if not dct[param]["description"].endswith("."):
786
760
  all_desc_ok = False
787
- print('param,description=',
761
+ print("param,description=",
788
762
  str(param),
789
- dct[param]['description'])
763
+ dct[param]["description"])
790
764
  assert all_desc_ok
791
765
 
792
766
 
@@ -795,8 +769,8 @@ def test_get_index_rate():
795
769
  Test Parameters.get_index_rate.
796
770
  """
797
771
  pol = Policy()
798
- wgrates = pol.get_index_rate('SS_Earnings_c', 2017)
799
- pirates = pol.get_index_rate('II_em', 2017)
772
+ wgrates = pol.get_index_rate("SS_Earnings_c", 2017)
773
+ pirates = pol.get_index_rate("II_em", 2017)
800
774
  assert isinstance(wgrates, np.float64)
801
775
  assert wgrates == pol.wage_growth_rates(2017)
802
776
  assert pirates == pol.inflation_rates(2017)
@@ -810,11 +784,11 @@ def test_reform_with_removed_parameter(monkeypatch):
810
784
  Try to use removed parameter in a reform.
811
785
  """
812
786
  policy1 = Policy()
813
- reform1 = {'FilerCredit_c': {2020: 1000}}
787
+ reform1 = {"FilerCredit_c": {2020: 1000}}
814
788
  with pytest.raises(paramtools.ValidationError):
815
789
  policy1.implement_reform(reform1)
816
790
  policy2 = Policy()
817
- reform2 = {'FilerCredit_c-indexed': {2020: True}}
791
+ reform2 = {"FilerCredit_c-indexed": {2020: True}}
818
792
  with pytest.raises(paramtools.ValidationError):
819
793
  policy2.implement_reform(reform2)
820
794
 
@@ -831,7 +805,7 @@ def test_reform_with_out_of_range_error():
831
805
  Try to use out-of-range values versus other parameter values in a reform.
832
806
  """
833
807
  pol = Policy()
834
- reform = {'SS_thd2': {2020: [20000, 20000, 20000, 20000, 20000]}}
808
+ reform = {"SS_thd2": {2020: [20000, 20000, 20000, 20000, 20000]}}
835
809
  pol.implement_reform(reform, raise_errors=False)
836
810
  assert pol.parameter_errors
837
811
 
@@ -841,12 +815,12 @@ def test_reform_with_warning():
841
815
  Try to use warned out-of-range parameter value in reform.
842
816
  """
843
817
  exp_warnings = {
844
- 'ID_Medical_frt': [
845
- 'ID_Medical_frt[year=2020] 0.05 < min 0.075 '
818
+ "ID_Medical_frt": [
819
+ "ID_Medical_frt[year=2020] 0.05 < min 0.075 "
846
820
  ]
847
821
  }
848
822
  pol = Policy()
849
- reform = {'ID_Medical_frt': {2020: 0.05}}
823
+ reform = {"ID_Medical_frt": {2020: 0.05}}
850
824
 
851
825
  pol.implement_reform(reform, print_warnings=True)
852
826
  assert pol.warnings == exp_warnings
@@ -864,17 +838,17 @@ def test_reform_with_scalar_vector_errors():
864
838
  Test catching scalar-vector confusion.
865
839
  """
866
840
  policy1 = Policy()
867
- reform1 = {'SS_thd2': {2020: 30000}}
841
+ reform1 = {"SS_thd2": {2020: 30000}}
868
842
  with pytest.raises(paramtools.ValidationError):
869
843
  policy1.implement_reform(reform1)
870
844
 
871
845
  policy2 = Policy()
872
- reform2 = {'ID_Medical_frt': {2020: [0.08]}}
846
+ reform2 = {"ID_Medical_frt": {2020: [0.08]}}
873
847
  with pytest.raises(paramtools.ValidationError):
874
848
  policy2.implement_reform(reform2)
875
849
 
876
850
  policy3 = Policy()
877
- reform3 = {'ID_Medical_frt': [{"year": 2020, "value": [0.08]}]}
851
+ reform3 = {"ID_Medical_frt": [{"year": 2020, "value": [0.08]}]}
878
852
  with pytest.raises(paramtools.ValidationError):
879
853
  policy3.adjust(reform3)
880
854
 
@@ -893,35 +867,35 @@ def test_reform_with_scalar_vector_errors():
893
867
  def test_index_offset_reform():
894
868
  """
895
869
  Test a reform that includes both a change in parameter_indexing_CPI_offset
896
- and a change in a variable's indexed status in the same year.
870
+ and a change in a variable"s indexed status in the same year.
897
871
  """
898
872
  # create policy0 to extract inflation rates before any
899
873
  # parameter_indexing_CPI_offset
900
874
  policy0 = Policy()
901
- policy0.implement_reform({'parameter_indexing_CPI_offset': {2017: 0}})
875
+ policy0.implement_reform({"parameter_indexing_CPI_offset": {2017: 0}})
902
876
  cpiu_rates = policy0.inflation_rates()
903
877
 
904
- reform1 = {'CTC_c-indexed': {2020: True}}
878
+ reform1 = {"ODC_c-indexed": {2020: True}}
905
879
  policy1 = Policy()
906
880
  policy1.implement_reform(reform1)
907
881
  offset = -0.005
908
- reform2 = {'CTC_c-indexed': {2020: True},
909
- 'parameter_indexing_CPI_offset': {2020: offset}}
882
+ reform2 = {"ODC_c-indexed": {2020: True},
883
+ "parameter_indexing_CPI_offset": {2020: offset}}
910
884
  policy2 = Policy()
911
- policy2.implement_reform(reform2) # caused T-C crash before PR#2364
912
- # extract from policy1 and policy2 the parameter values of CTC_c
885
+ policy2.implement_reform(reform2)
886
+ # extract from policy1 and policy2 the parameter values of ODC_c
913
887
  pvalue1 = {}
914
888
  pvalue2 = {}
915
889
  for cyr in [2019, 2020, 2021]:
916
890
  policy1.set_year(cyr)
917
- pvalue1[cyr] = policy1.CTC_c[0]
891
+ pvalue1[cyr] = policy1.ODC_c[0]
918
892
  policy2.set_year(cyr)
919
- pvalue2[cyr] = policy2.CTC_c[0]
893
+ pvalue2[cyr] = policy2.ODC_c[0]
920
894
  # check that pvalue1 and pvalue2 dictionaries contain the expected values
921
895
  assert pvalue2[2019] == pvalue1[2019]
922
896
  assert pvalue2[2020] == pvalue1[2020]
923
897
  assert pvalue2[2020] == pvalue2[2019]
924
- # ... indexing of CTC_c begins shows up first in 2021 parameter values
898
+ # ... indexing of ODC_c begins shows up first in 2021 parameter values
925
899
  assert pvalue1[2021] > pvalue1[2020]
926
900
  assert pvalue2[2021] > pvalue2[2020]
927
901
  # ... calculate expected pvalue2[2021] from inflation rates and offset
@@ -937,8 +911,8 @@ def test_cpi_offset_affect_on_prior_years():
937
911
  Test that parameter_indexing_CPI_offset does not have affect
938
912
  on inflation rates in earlier years.
939
913
  """
940
- reform1 = {'parameter_indexing_CPI_offset': {2022: 0}}
941
- reform2 = {'parameter_indexing_CPI_offset': {2022: -0.005}}
914
+ reform1 = {"parameter_indexing_CPI_offset": {2022: 0}}
915
+ reform2 = {"parameter_indexing_CPI_offset": {2022: -0.005}}
942
916
  p1 = Policy()
943
917
  p2 = Policy()
944
918
  p1.implement_reform(reform1)
@@ -966,11 +940,11 @@ def test_cpi_offset_on_reverting_params():
966
940
  Test that params that revert to their pre-TCJA values
967
941
  in 2026 revert if a parameter_indexing_CPI_offset is specified.
968
942
  """
969
- reform0 = {'parameter_indexing_CPI_offset': {2020: -0.001}}
970
- reform1 = {'STD': {2017: [6350, 12700, 6350, 9350, 12700]},
971
- 'parameter_indexing_CPI_offset': {2020: -0.001}}
972
- reform2 = {'STD': {2020: [10000, 20000, 10000, 10000, 20000]},
973
- 'parameter_indexing_CPI_offset': {2020: -0.001}}
943
+ reform0 = {"parameter_indexing_CPI_offset": {2020: -0.001}}
944
+ reform1 = {"STD": {2017: [6350, 12700, 6350, 9350, 12700]},
945
+ "parameter_indexing_CPI_offset": {2020: -0.001}}
946
+ reform2 = {"STD": {2020: [10000, 20000, 10000, 10000, 20000]},
947
+ "parameter_indexing_CPI_offset": {2020: -0.001}}
974
948
 
975
949
  p0 = Policy()
976
950
  p1 = Policy()
@@ -998,11 +972,15 @@ def test_raise_errors_regression():
998
972
  """
999
973
  This tests that raise_errors prevents the error from being thrown. The
1000
974
  correct behavior is to exit the `adjust` function and store the errors.
975
+ ** From the parameters.py docstring for the adjust method:
976
+ raise_errors: Boolean
977
+ Raise errors as a ValidationError. If False, they will be stored
978
+ in the errors attribute.
1001
979
  """
1002
980
  ref = {
1003
- "II_brk7-indexed": [{"value": True}],
981
+ "II_brk7-indexed": [{"value": False}],
1004
982
  "II_brk6": [{"value": 316700, "MARS": "single", "year": 2020}],
1005
- "II_brk7": [{"value": 445400, "MARS": "single", "year": 2020}],
983
+ "II_brk7": [{"value": 320700, "MARS": "single", "year": 2020}],
1006
984
 
1007
985
  }
1008
986
  pol = Policy()
@@ -1177,14 +1155,14 @@ def test_activate_index():
1177
1155
  """
1178
1156
  pol1 = Policy()
1179
1157
  pol1.implement_reform({
1180
- "CTC_c": {2022: 2000},
1181
- "CTC_c-indexed": {2022: True}
1158
+ "ODC_c": {2022: 1000},
1159
+ "ODC_c-indexed": {2022: True}
1182
1160
  })
1183
1161
  pol2 = Policy()
1184
1162
  pol2.adjust(
1185
1163
  {
1186
- "CTC_c": [{"year": 2022, "value": 2000}],
1187
- "CTC_c-indexed": [{"year": 2022, "value": True}],
1164
+ "ODC_c": [{"year": 2022, "value": 1000}],
1165
+ "ODC_c-indexed": [{"year": 2022, "value": True}],
1188
1166
  }
1189
1167
  )
1190
1168
  cmp_policy_objs(pol1, pol2)
@@ -1193,12 +1171,12 @@ def test_activate_index():
1193
1171
  pol0.set_year(year=2021)
1194
1172
  pol2.set_state(year=[2021, 2022, 2023])
1195
1173
  exp = np.array([
1196
- pol0.CTC_c[0],
1197
- 2000,
1198
- 2000 * (1 + pol2.inflation_rates(year=2022))
1174
+ pol0.ODC_c[0],
1175
+ 1000,
1176
+ 1000 * (1 + pol2.inflation_rates(year=2022))
1199
1177
  ]).round(2)
1200
1178
 
1201
- np.testing.assert_allclose(pol2.CTC_c, exp)
1179
+ np.testing.assert_allclose(pol2.ODC_c, exp)
1202
1180
 
1203
1181
 
1204
1182
  def test_apply_cpi_offset():
@@ -1243,7 +1221,7 @@ def test_apply_cpi_offset():
1243
1221
 
1244
1222
  def test_multiple_cpi_swaps():
1245
1223
  """
1246
- Test changing a parameter's indexed status multiple times.
1224
+ Test changing a parameter"s indexed status multiple times.
1247
1225
  """
1248
1226
  pol1 = Policy()
1249
1227
  pol1.implement_reform(
@@ -1404,7 +1382,7 @@ def test_adj_cpi_offset_and_index_status():
1404
1382
  """
1405
1383
  pol1 = Policy()
1406
1384
  pol1.implement_reform({
1407
- "CTC_c-indexed": {2020: True},
1385
+ "ODC_c-indexed": {2020: True},
1408
1386
  "parameter_indexing_CPI_offset": {2020: -0.005}},
1409
1387
  )
1410
1388
  pol2 = Policy()
@@ -1412,7 +1390,7 @@ def test_adj_cpi_offset_and_index_status():
1412
1390
  {
1413
1391
  "parameter_indexing_CPI_offset":
1414
1392
  [{"year": 2020, "value": -0.005}],
1415
- "CTC_c-indexed": [{"year": 2020, "value": True}],
1393
+ "ODC_c-indexed": [{"year": 2020, "value": True}],
1416
1394
  }
1417
1395
  )
1418
1396
  cmp_policy_objs(pol1, pol2)
@@ -1429,7 +1407,7 @@ def test_adj_cpi_offset_and_index_status():
1429
1407
 
1430
1408
  pol2.set_state(year=[2021, 2022])
1431
1409
  np.testing.assert_equal(
1432
- (pol2.CTC_c[1] / pol2.CTC_c[0] - 1).round(4),
1410
+ (pol2.ODC_c[1] / pol2.ODC_c[0] - 1).round(4),
1433
1411
  round(pol0.inflation_rates(year=2021) + (-0.005), 4),
1434
1412
  )
1435
1413
 
@@ -1515,48 +1493,48 @@ def test_cpi_offset_does_not_affect_wage_indexed_params():
1515
1493
  np.testing.assert_equal(act_before_2025, exp_before_2025)
1516
1494
 
1517
1495
 
1518
- def test_ext_plus_ctc1_reform(tests_path):
1496
+ def test_ext_plus_odc1_reform(tests_path):
1519
1497
  """
1520
- Test ext.json plus ctc1 compound reform relative to ext.json baseline.
1498
+ Test ext.json plus odc1 compound reform relative to ext.json baseline.
1521
1499
  """
1522
1500
  # specify baseline policy, bas, as the extend-TCJA reform
1523
1501
  bas = Policy()
1524
- filename = os.path.join(tests_path, '..', 'reforms', 'ext.json')
1525
- with open(filename, 'r', encoding='utf-8') as rfile:
1502
+ filename = os.path.join(tests_path, "..", "reforms", "ext.json")
1503
+ with open(filename, "r", encoding="utf-8") as rfile:
1526
1504
  ext_text = rfile.read()
1527
1505
  bas.implement_reform(Policy.read_json_reform(ext_text))
1528
1506
  assert not bas.parameter_errors
1529
- # specify reform policy, ref, as extend-TCJA plus liberalization of CTC
1507
+ # specify reform policy, ref, as extend-TCJA plus liberalization of ODC
1530
1508
  ref = Policy()
1531
1509
  ref.implement_reform(Policy.read_json_reform(ext_text))
1532
- ctc1_reform = {
1533
- # one possible child-tax-credit revision to the extend-TCJA reform
1534
- 'CTC_c': {
1535
- 2026: 2500.00,
1536
- 2027: 2500.00,
1537
- 2028: 2500.00,
1538
- 2029: 2000.00,
1510
+ odc1_reform = {
1511
+ # one possible other-dependent-credit revision to extend-TCJA reform
1512
+ "ODC_c": {
1513
+ 2026: 1000.00,
1514
+ 2027: 1000.00,
1515
+ 2028: 1000.00,
1516
+ 2029: 1000.00,
1539
1517
  },
1540
- 'CTC_c-indexed': {2029: True},
1518
+ "ODC_c-indexed": {2029: True},
1541
1519
  }
1542
- ref.implement_reform(ctc1_reform)
1520
+ ref.implement_reform(odc1_reform)
1543
1521
  assert not ref.parameter_errors
1544
1522
  # check bas and ref parameter values against expected parameter values
1545
- exp_ctc_c_bas = {
1546
- 2025: 2000,
1547
- 2026: 2000,
1548
- 2027: 2000,
1549
- 2028: 2000,
1550
- 2029: 2000,
1551
- 2030: 2000,
1523
+ exp_odc_c_bas = {
1524
+ 2025: 500,
1525
+ 2026: 500,
1526
+ 2027: 500,
1527
+ 2028: 500,
1528
+ 2029: 500,
1529
+ 2030: 500,
1552
1530
  }
1553
- exp_ctc_c_ref = {
1554
- 2025: 2000,
1555
- 2026: 2500,
1556
- 2027: 2500,
1557
- 2028: 2500,
1558
- 2029: 2000,
1559
- 2030: 2044.80,
1531
+ exp_odc_c_ref = {
1532
+ 2025: 500,
1533
+ 2026: 1000,
1534
+ 2027: 1000,
1535
+ 2028: 1000,
1536
+ 2029: 1000,
1537
+ 2030: 1022.4,
1560
1538
  }
1561
1539
  exp_actc_c = {
1562
1540
  2025: 1700,
@@ -1568,57 +1546,57 @@ def test_ext_plus_ctc1_reform(tests_path):
1568
1546
  }
1569
1547
  for year in range(2025, 2031):
1570
1548
  bas.set_year(year)
1571
- assert np.allclose([bas.CTC_c], [exp_ctc_c_bas[year]])
1549
+ assert np.allclose([bas.ODC_c], [exp_odc_c_bas[year]])
1572
1550
  assert np.allclose([bas.ACTC_c], [exp_actc_c[year]])
1573
1551
  ref.set_year(year)
1574
- assert np.allclose([ref.CTC_c], [exp_ctc_c_ref[year]])
1552
+ assert np.allclose([ref.ODC_c], [exp_odc_c_ref[year]])
1575
1553
  assert np.allclose([ref.ACTC_c], [exp_actc_c[year]])
1576
1554
 
1577
1555
 
1578
- def test_ext_plus_ctc2_reform(tests_path):
1556
+ def test_ext_plus_odc2_reform(tests_path):
1579
1557
  """
1580
- Test ext.json plus ctc2 compound reform relative to ext.json baseline.
1558
+ Test ext.json plus odc2 compound reform relative to ext.json baseline.
1581
1559
  """
1582
1560
  # specify baseline policy, bas, as the extend-TCJA reform
1583
1561
  bas = Policy()
1584
- filename = os.path.join(tests_path, '..', 'reforms', 'ext.json')
1585
- with open(filename, 'r', encoding='utf-8') as rfile:
1562
+ filename = os.path.join(tests_path, "..", "reforms", "ext.json")
1563
+ with open(filename, "r", encoding="utf-8") as rfile:
1586
1564
  ext_text = rfile.read()
1587
1565
  bas.implement_reform(Policy.read_json_reform(ext_text))
1588
1566
  assert not bas.parameter_errors
1589
- # specify reform policy, ref, as extend-TCJA plus liberalization of CTC
1567
+ # specify reform policy, ref, as extend-TCJA plus liberalization of ODC
1590
1568
  ref = Policy()
1591
1569
  ref.implement_reform(Policy.read_json_reform(ext_text))
1592
- ctc2_reform = {
1593
- # one possible child-tax-credit revision to the extend-TCJA reform
1594
- 'CTC_c': {
1595
- 2026: 2500.00,
1596
- 2027: 2500.00,
1597
- 2028: 2500.00,
1598
- 2029: 2000.00,
1570
+ odc2_reform = {
1571
+ # one possible other-dependent-credit revision to extend-TCJA reform
1572
+ "ODC_c": {
1573
+ 2026: 600.00,
1574
+ 2027: 600.00,
1575
+ 2028: 600.00,
1576
+ 2029: 800.00,
1599
1577
  },
1600
- 'CTC_c-indexed': {2029: True},
1601
- 'ACTC_c': {2029: 1750},
1602
- 'ACTC_c-indexed': {2029: False},
1578
+ "ODC_c-indexed": {2029: True},
1579
+ "ACTC_c": {2029: 1750},
1580
+ "ACTC_c-indexed": {2029: False},
1603
1581
  }
1604
- ref.implement_reform(ctc2_reform)
1582
+ ref.implement_reform(odc2_reform)
1605
1583
  assert not ref.parameter_errors
1606
1584
  # check bas and ref parameter values against expected parameter values
1607
- exp_ctc_c_bas = {
1608
- 2025: 2000,
1609
- 2026: 2000,
1610
- 2027: 2000,
1611
- 2028: 2000,
1612
- 2029: 2000,
1613
- 2030: 2000,
1585
+ exp_odc_c_bas = {
1586
+ 2025: 500,
1587
+ 2026: 500,
1588
+ 2027: 500,
1589
+ 2028: 500,
1590
+ 2029: 500,
1591
+ 2030: 500,
1614
1592
  }
1615
- exp_ctc_c_ref = {
1616
- 2025: 2000,
1617
- 2026: 2500,
1618
- 2027: 2500,
1619
- 2028: 2500,
1620
- 2029: 2000,
1621
- 2030: 2044.80,
1593
+ exp_odc_c_ref = {
1594
+ 2025: 500,
1595
+ 2026: 600,
1596
+ 2027: 600,
1597
+ 2028: 600,
1598
+ 2029: 800,
1599
+ 2030: 817.92,
1622
1600
  }
1623
1601
  exp_actc_c_bas = {
1624
1602
  2025: 1700,
@@ -1638,8 +1616,8 @@ def test_ext_plus_ctc2_reform(tests_path):
1638
1616
  }
1639
1617
  for year in range(2025, 2031):
1640
1618
  bas.set_year(year)
1641
- assert np.allclose([bas.CTC_c], [exp_ctc_c_bas[year]])
1619
+ assert np.allclose([bas.ODC_c], [exp_odc_c_bas[year]])
1642
1620
  assert np.allclose([bas.ACTC_c], [exp_actc_c_bas[year]])
1643
1621
  ref.set_year(year)
1644
- assert np.allclose([ref.CTC_c], [exp_ctc_c_ref[year]])
1622
+ assert np.allclose([ref.ODC_c], [exp_odc_c_ref[year]])
1645
1623
  assert np.allclose([ref.ACTC_c], [exp_actc_c_ref[year]])