From 63002aa144ab44c9022b8022f57dbc98403607e2 Mon Sep 17 00:00:00 2001 From: Nikhil Woodruff Date: Mon, 17 Feb 2025 12:55:44 +0000 Subject: [PATCH 01/13] Target SALT and medical expense deduction tax expenditure values Fixes #163 --- policyengine_us_data/utils/loss.py | 62 ++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/policyengine_us_data/utils/loss.py b/policyengine_us_data/utils/loss.py index a01b16a4..65b1ce25 100644 --- a/policyengine_us_data/utils/loss.py +++ b/policyengine_us_data/utils/loss.py @@ -2,6 +2,7 @@ from .soi import pe_to_soi, get_soi import numpy as np from policyengine_us_data.storage import STORAGE_FOLDER +from policyengine_core.reforms import Reform def fmt(x): @@ -26,6 +27,7 @@ def build_loss_matrix(dataset: type, time_period): taxable = df["total_income_tax"].values > 0 soi_subset = get_soi(time_period) targets_array = [] + """ agi_level_targeted_variables = [ "adjusted_gross_income", "count", @@ -126,12 +128,15 @@ def build_loss_matrix(dataset: type, time_period): if label not in loss_matrix.columns: loss_matrix[label] = mask * values targets_array.append(row["Value"]) + """ # Convert tax-unit level df to household-level df from policyengine_us import Microsimulation sim = Microsimulation(dataset=dataset) + sim.default_calculation_period = time_period + """ hh_id = sim.calculate("household_id", map_to="person") tax_unit_hh_id = sim.map_result( hh_id, "person", "tax_unit", how="value_from_first_person" @@ -339,6 +344,14 @@ def build_loss_matrix(dataset: type, time_period): in_state_under_5, "person", "household" ) targets_array.append(row["population_under_5"]) + + """ + + # SALT tax expenditure targeting + + _add_tax_expenditure_targets( + dataset, time_period, sim, loss_matrix, targets_array + ) if any(loss_matrix.isna().sum() > 0): raise ValueError("Some targets are missing from the loss matrix") @@ -347,3 +360,52 @@ def build_loss_matrix(dataset: type, time_period): raise ValueError("Some targets are missing from the targets array") return loss_matrix, np.array(targets_array) + + +def _add_tax_expenditure_targets( + dataset, + time_period, + baseline_simulation, + loss_matrix: pd.DataFrame, + targets_array: list, +): + from policyengine_us import Microsimulation + + # SALT deduction first + + repeal_salt = Reform.from_dict( + { + "gov.irs.deductions.itemized.salt_and_real_estate.cap.JOINT": { + "2024-01-01.2100-12-31": 0 + }, + "gov.irs.deductions.itemized.salt_and_real_estate.cap.SINGLE": { + "2024-01-01.2100-12-31": 0 + }, + "gov.irs.deductions.itemized.salt_and_real_estate.cap.SEPARATE": { + "2024-01-01.2100-12-31": 0 + }, + "gov.irs.deductions.itemized.salt_and_real_estate.cap.SURVIVING_SPOUSE": { + "2024-01-01.2100-12-31": 0 + }, + "gov.irs.deductions.itemized.salt_and_real_estate.cap.HEAD_OF_HOUSEHOLD": { + "2024-01-01.2100-12-31": 0 + }, + }, + country_id="us", + ) + + reform_simulation = Microsimulation(dataset=dataset, reform=repeal_salt) + reform_simulation.default_calculation_period = time_period + + income_tax_b = baseline_simulation.calculate( + "income_tax", map_to="household" + ).values + income_tax_r = reform_simulation.calculate( + "income_tax", map_to="household" + ).values + salt_te_values = income_tax_r - income_tax_b + + salt_target = 20e9 + + loss_matrix["jct/salt_tax_expenditure"] = salt_te_values + targets_array.append(salt_target) From d8be30488d856504a389bf04a74202beaf0e762a Mon Sep 17 00:00:00 2001 From: Nikhil Woodruff Date: Mon, 17 Feb 2025 13:09:32 +0000 Subject: [PATCH 02/13] Add SALT TE targeting --- policyengine_us_data/utils/loss.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/policyengine_us_data/utils/loss.py b/policyengine_us_data/utils/loss.py index 65b1ce25..1d3aca3b 100644 --- a/policyengine_us_data/utils/loss.py +++ b/policyengine_us_data/utils/loss.py @@ -27,7 +27,6 @@ def build_loss_matrix(dataset: type, time_period): taxable = df["total_income_tax"].values > 0 soi_subset = get_soi(time_period) targets_array = [] - """ agi_level_targeted_variables = [ "adjusted_gross_income", "count", @@ -128,7 +127,6 @@ def build_loss_matrix(dataset: type, time_period): if label not in loss_matrix.columns: loss_matrix[label] = mask * values targets_array.append(row["Value"]) - """ # Convert tax-unit level df to household-level df @@ -136,7 +134,6 @@ def build_loss_matrix(dataset: type, time_period): sim = Microsimulation(dataset=dataset) sim.default_calculation_period = time_period - """ hh_id = sim.calculate("household_id", map_to="person") tax_unit_hh_id = sim.map_result( hh_id, "person", "tax_unit", how="value_from_first_person" @@ -344,8 +341,6 @@ def build_loss_matrix(dataset: type, time_period): in_state_under_5, "person", "household" ) targets_array.append(row["population_under_5"]) - - """ # SALT tax expenditure targeting From 411d13be10cbd067ffdb95646b4ecbe64c2f4bfd Mon Sep 17 00:00:00 2001 From: Nikhil Woodruff Date: Mon, 17 Feb 2025 13:11:50 +0000 Subject: [PATCH 03/13] Add test --- .../tests/test_datasets/test_enhanced_cps.py | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/policyengine_us_data/tests/test_datasets/test_enhanced_cps.py b/policyengine_us_data/tests/test_datasets/test_enhanced_cps.py index 64f85dcb..4f72a935 100644 --- a/policyengine_us_data/tests/test_datasets/test_enhanced_cps.py +++ b/policyengine_us_data/tests/test_datasets/test_enhanced_cps.py @@ -37,3 +37,45 @@ def test_ecps_has_mortgage_interest(): assert sim.calculate("deductible_mortgage_interest").sum() > 1 assert sim.calculate("interest_expense").sum() > 1 + + +def test_ecps_replicates_jct_salt_te(): + from policyengine_us import Microsimulation + from policyengine_core.reforms import Reform + from policyengine_core.data import Dataset + from policyengine_us_data.datasets import EnhancedCPS_2024 + + reform = Reform.from_dict( + { + "gov.irs.deductions.itemized.salt_and_real_estate.cap.JOINT": { + "2024-01-01.2100-12-31": 0 + }, + "gov.irs.deductions.itemized.salt_and_real_estate.cap.SINGLE": { + "2024-01-01.2100-12-31": 0 + }, + "gov.irs.deductions.itemized.salt_and_real_estate.cap.SEPARATE": { + "2024-01-01.2100-12-31": 0 + }, + "gov.irs.deductions.itemized.salt_and_real_estate.cap.SURVIVING_SPOUSE": { + "2024-01-01.2100-12-31": 0 + }, + "gov.irs.deductions.itemized.salt_and_real_estate.cap.HEAD_OF_HOUSEHOLD": { + "2024-01-01.2100-12-31": 0 + }, + }, + country_id="us", + ) + + baseline = Microsimulation(dataset=EnhancedCPS_2024) + reformed = Microsimulation(reform=reform, dataset=EnhancedCPS_2024) + + income_tax_b = baseline.calculate( + "income_tax", period=2024, map_to="household" + ) + income_tax_r = reformed.calculate( + "income_tax", period=2024, map_to="household" + ) + tax_change = income_tax_r - income_tax_b + federal_tax_expenditure = tax_change.sum() / 1e9 + + assert abs(federal_tax_expenditure - 20e9) < 5e9 From f900888991e168fa98cb1e0f9a6cb2fb7e47a4fc Mon Sep 17 00:00:00 2001 From: Nikhil Woodruff Date: Mon, 17 Feb 2025 15:38:55 +0000 Subject: [PATCH 04/13] Adjust test conditions! --- policyengine_us_data/tests/test_datasets/test_enhanced_cps.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/policyengine_us_data/tests/test_datasets/test_enhanced_cps.py b/policyengine_us_data/tests/test_datasets/test_enhanced_cps.py index 4f72a935..0d13db74 100644 --- a/policyengine_us_data/tests/test_datasets/test_enhanced_cps.py +++ b/policyengine_us_data/tests/test_datasets/test_enhanced_cps.py @@ -78,4 +78,4 @@ def test_ecps_replicates_jct_salt_te(): tax_change = income_tax_r - income_tax_b federal_tax_expenditure = tax_change.sum() / 1e9 - assert abs(federal_tax_expenditure - 20e9) < 5e9 + assert abs(federal_tax_expenditure - 20) < 5 From 4b6615dc909fd6ad8169cd9643a9eeb0f559b650 Mon Sep 17 00:00:00 2001 From: Nikhil Woodruff <35577657+nikhilwoodruff@users.noreply.github.com> Date: Mon, 17 Feb 2025 16:03:21 +0000 Subject: [PATCH 05/13] Update policyengine_us_data/utils/loss.py Co-authored-by: Max Ghenis --- policyengine_us_data/utils/loss.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/policyengine_us_data/utils/loss.py b/policyengine_us_data/utils/loss.py index 1d3aca3b..2ae3e38d 100644 --- a/policyengine_us_data/utils/loss.py +++ b/policyengine_us_data/utils/loss.py @@ -400,7 +400,8 @@ def _add_tax_expenditure_targets( ).values salt_te_values = income_tax_r - income_tax_b - salt_target = 20e9 + # https://www.jct.gov/publications/2024/jcx-48-24/ page 33 (2024) + salt_target = 21.7e9 loss_matrix["jct/salt_tax_expenditure"] = salt_te_values targets_array.append(salt_target) From 890a474d026fbdf27cf1544bafa2541d61ef3e2d Mon Sep 17 00:00:00 2001 From: PavelMakarchuk Date: Mon, 17 Feb 2025 22:01:57 +0100 Subject: [PATCH 06/13] test fix --- policyengine_us_data/tests/test_datasets/test_enhanced_cps.py | 1 - 1 file changed, 1 deletion(-) diff --git a/policyengine_us_data/tests/test_datasets/test_enhanced_cps.py b/policyengine_us_data/tests/test_datasets/test_enhanced_cps.py index d8ee2226..b834bb84 100644 --- a/policyengine_us_data/tests/test_datasets/test_enhanced_cps.py +++ b/policyengine_us_data/tests/test_datasets/test_enhanced_cps.py @@ -78,4 +78,3 @@ def test_ecps_replicates_jct_salt_te(): federal_tax_expenditure = tax_change.sum() / 1e9 assert abs(federal_tax_expenditure - 20) < 5 - assert sim.calculate("deductible_interest_expense").sum() > 1 From 6a20ef7820bd63746b5c91d6392ba2527fa05461 Mon Sep 17 00:00:00 2001 From: PavelMakarchuk Date: Mon, 17 Feb 2025 22:26:09 +0100 Subject: [PATCH 07/13] add other itemized deductions targets --- policyengine_us_data/utils/loss.py | 73 ++++++++++++++---------------- 1 file changed, 35 insertions(+), 38 deletions(-) diff --git a/policyengine_us_data/utils/loss.py b/policyengine_us_data/utils/loss.py index 2ae3e38d..113c572a 100644 --- a/policyengine_us_data/utils/loss.py +++ b/policyengine_us_data/utils/loss.py @@ -254,7 +254,7 @@ def build_loss_matrix(dataset: type, time_period): "alimony_income": 13e9, "alimony_expense": 13e9, # Rough estimate, not CPS derived - "real_estate_taxes": 400e9, # Rough estimate between 350bn and 600bn total property tax collections + "real_estate_taxes": 500e9, # Rough estimate between 350bn and 600bn total property tax collections "rent": 735e9, # ACS total uprated by CPI } @@ -366,42 +366,39 @@ def _add_tax_expenditure_targets( ): from policyengine_us import Microsimulation - # SALT deduction first - - repeal_salt = Reform.from_dict( - { - "gov.irs.deductions.itemized.salt_and_real_estate.cap.JOINT": { - "2024-01-01.2100-12-31": 0 - }, - "gov.irs.deductions.itemized.salt_and_real_estate.cap.SINGLE": { - "2024-01-01.2100-12-31": 0 - }, - "gov.irs.deductions.itemized.salt_and_real_estate.cap.SEPARATE": { - "2024-01-01.2100-12-31": 0 - }, - "gov.irs.deductions.itemized.salt_and_real_estate.cap.SURVIVING_SPOUSE": { - "2024-01-01.2100-12-31": 0 - }, - "gov.irs.deductions.itemized.salt_and_real_estate.cap.HEAD_OF_HOUSEHOLD": { - "2024-01-01.2100-12-31": 0 - }, - }, - country_id="us", - ) - - reform_simulation = Microsimulation(dataset=dataset, reform=repeal_salt) - reform_simulation.default_calculation_period = time_period + income_tax_b = baseline_simulation.calculate("income_tax", map_to="household").values - income_tax_b = baseline_simulation.calculate( - "income_tax", map_to="household" - ).values - income_tax_r = reform_simulation.calculate( - "income_tax", map_to="household" - ).values - salt_te_values = income_tax_r - income_tax_b - - # https://www.jct.gov/publications/2024/jcx-48-24/ page 33 (2024) - salt_target = 21.7e9 + # Dictionary of itemized deductions and their target values + # (in billions for 2024, per the 2024 JCT Tax Expenditures report) + # https://www.jct.gov/publications/2024/jcx-48-24/ + ITEMIZED_DEDUCTIONS = { + "salt_deduction": 21.247e9, + "medical_expense_deduction": 11.4e9, + "charitable_deduction": 65.301e9, + "interest_deduction": 24.8e9, + } - loss_matrix["jct/salt_tax_expenditure"] = salt_te_values - targets_array.append(salt_target) + def make_repeal_class(deduction_var): + # Create a custom Reform subclass that neutralizes the given deduction. + class RepealDeduction(Reform): + def apply(self): + self.neutralize_variable(deduction_var) + return RepealDeduction + + for deduction, target in ITEMIZED_DEDUCTIONS.items(): + # Generate the custom repeal class for the current deduction. + RepealDeduction = make_repeal_class(deduction) + + # Run the microsimulation using the repeal reform. + simulation = Microsimulation(dataset=dataset, reform=RepealDeduction) + simulation.default_calculation_period = time_period + + # Calculate the baseline and reform income tax values. + income_tax_r = simulation.calculate("income_tax", map_to="household").values + + # Compute the tax expenditure (TE) values. + te_values = income_tax_r - income_tax_b + + # Record the TE difference and the corresponding target value. + loss_matrix[f"jct/{deduction}_expenditure"] = te_values + targets_array.append(target) From 84942fb135b18e0b5502483eedd32001acc8bd21 Mon Sep 17 00:00:00 2001 From: PavelMakarchuk Date: Mon, 17 Feb 2025 22:26:21 +0100 Subject: [PATCH 08/13] lint --- policyengine_us_data/utils/loss.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/policyengine_us_data/utils/loss.py b/policyengine_us_data/utils/loss.py index 113c572a..a45bb778 100644 --- a/policyengine_us_data/utils/loss.py +++ b/policyengine_us_data/utils/loss.py @@ -366,9 +366,11 @@ def _add_tax_expenditure_targets( ): from policyengine_us import Microsimulation - income_tax_b = baseline_simulation.calculate("income_tax", map_to="household").values + income_tax_b = baseline_simulation.calculate( + "income_tax", map_to="household" + ).values - # Dictionary of itemized deductions and their target values + # Dictionary of itemized deductions and their target values # (in billions for 2024, per the 2024 JCT Tax Expenditures report) # https://www.jct.gov/publications/2024/jcx-48-24/ ITEMIZED_DEDUCTIONS = { @@ -383,18 +385,21 @@ def make_repeal_class(deduction_var): class RepealDeduction(Reform): def apply(self): self.neutralize_variable(deduction_var) + return RepealDeduction for deduction, target in ITEMIZED_DEDUCTIONS.items(): # Generate the custom repeal class for the current deduction. RepealDeduction = make_repeal_class(deduction) - + # Run the microsimulation using the repeal reform. simulation = Microsimulation(dataset=dataset, reform=RepealDeduction) simulation.default_calculation_period = time_period # Calculate the baseline and reform income tax values. - income_tax_r = simulation.calculate("income_tax", map_to="household").values + income_tax_r = simulation.calculate( + "income_tax", map_to="household" + ).values # Compute the tax expenditure (TE) values. te_values = income_tax_r - income_tax_b From 12739c8f1ab9b334cd3138bc91b621071d5fe167 Mon Sep 17 00:00:00 2001 From: PavelMakarchuk Date: Mon, 17 Feb 2025 22:40:35 +0100 Subject: [PATCH 09/13] lint --- policyengine_us_data/datasets/cps/cps.py | 1 - policyengine_us_data/utils/loss.py | 1 - 2 files changed, 2 deletions(-) diff --git a/policyengine_us_data/datasets/cps/cps.py b/policyengine_us_data/datasets/cps/cps.py index 59b932a8..83305ae5 100644 --- a/policyengine_us_data/datasets/cps/cps.py +++ b/policyengine_us_data/datasets/cps/cps.py @@ -242,7 +242,6 @@ def add_personal_variables(cps: h5py.File, person: DataFrame) -> None: ] cps["is_disabled"] = (person[DISABILITY_FLAGS] == 1).any(axis=1) - def children_per_parent(col: str) -> pd.DataFrame: """Calculate number of children in the household using parental pointers. diff --git a/policyengine_us_data/utils/loss.py b/policyengine_us_data/utils/loss.py index 775a8f25..3eacf024 100644 --- a/policyengine_us_data/utils/loss.py +++ b/policyengine_us_data/utils/loss.py @@ -342,7 +342,6 @@ def build_loss_matrix(dataset: type, time_period): ) targets_array.append(row["population_under_5"]) - age = sim.calculate("age").values infants = (age >= 0) & (age < 1) label = "census/infants" From 8224eb55bf3fe118b3e397e0a59df85676e79b92 Mon Sep 17 00:00:00 2001 From: PavelMakarchuk Date: Mon, 17 Feb 2025 22:59:02 +0100 Subject: [PATCH 10/13] added test --- .../tests/test_datasets/test_enhanced_cps.py | 59 +++++++++---------- 1 file changed, 29 insertions(+), 30 deletions(-) diff --git a/policyengine_us_data/tests/test_datasets/test_enhanced_cps.py b/policyengine_us_data/tests/test_datasets/test_enhanced_cps.py index b834bb84..2acdc51b 100644 --- a/policyengine_us_data/tests/test_datasets/test_enhanced_cps.py +++ b/policyengine_us_data/tests/test_datasets/test_enhanced_cps.py @@ -38,43 +38,42 @@ def test_ecps_has_mortgage_interest(): assert sim.calculate("deductible_mortgage_interest").sum() > 1 -def test_ecps_replicates_jct_salt_te(): +def test_ecps_replicates_jct_tax_expenditures(): from policyengine_us import Microsimulation from policyengine_core.reforms import Reform - from policyengine_core.data import Dataset from policyengine_us_data.datasets import EnhancedCPS_2024 - reform = Reform.from_dict( - { - "gov.irs.deductions.itemized.salt_and_real_estate.cap.JOINT": { - "2024-01-01.2100-12-31": 0 - }, - "gov.irs.deductions.itemized.salt_and_real_estate.cap.SINGLE": { - "2024-01-01.2100-12-31": 0 - }, - "gov.irs.deductions.itemized.salt_and_real_estate.cap.SEPARATE": { - "2024-01-01.2100-12-31": 0 - }, - "gov.irs.deductions.itemized.salt_and_real_estate.cap.SURVIVING_SPOUSE": { - "2024-01-01.2100-12-31": 0 - }, - "gov.irs.deductions.itemized.salt_and_real_estate.cap.HEAD_OF_HOUSEHOLD": { - "2024-01-01.2100-12-31": 0 - }, - }, - country_id="us", - ) + # JCT tax expenditure targets + EXPENDITURE_TARGETS = { + "salt_deduction": 21.247e9, + "medical_expense_deduction": 11.4e9, + "charitable_deduction": 65.301e9, + "interest_deduction": 24.8e9, + } baseline = Microsimulation(dataset=EnhancedCPS_2024) - reformed = Microsimulation(reform=reform, dataset=EnhancedCPS_2024) - income_tax_b = baseline.calculate( "income_tax", period=2024, map_to="household" ) - income_tax_r = reformed.calculate( - "income_tax", period=2024, map_to="household" - ) - tax_change = income_tax_r - income_tax_b - federal_tax_expenditure = tax_change.sum() / 1e9 - assert abs(federal_tax_expenditure - 20) < 5 + for deduction, target in EXPENDITURE_TARGETS.items(): + # Create reform that neutralizes the deduction + class RepealDeduction(Reform): + def apply(self): + self.neutralize_variable(deduction) + + # Run reform simulation + reformed = Microsimulation( + reform=RepealDeduction, dataset=EnhancedCPS_2024 + ) + income_tax_r = reformed.calculate( + "income_tax", period=2024, map_to="household" + ) + + # Calculate tax expenditure + tax_expenditure = (income_tax_r - income_tax_b).sum() + + # Assert within 5bn of target + assert ( + abs(tax_expenditure - target) < 5e9 + ), f"{deduction} tax expenditure {tax_expenditure/1e9:.1f}bn differs from target {target/1e9:.1f}bn by more than 5bn" From 49f10a3ef5eb9943a08e9244f1f09e23181f9447 Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Mon, 17 Feb 2025 18:55:33 -0500 Subject: [PATCH 11/13] bump policyengine-us --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index fe6b2104..cf712384 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -17,7 +17,7 @@ authors = [ license = {file = "LICENSE"} requires-python = ">=3.10, <3.13.0" dependencies = [ - "policyengine_us", + "policyengine_us>=1.197.0", "policyengine_core>=3.14.1", "requests", "tqdm", From 0cbbfb88074af48c16e596b224f0d7b3c0b64a1b Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Mon, 17 Feb 2025 18:57:11 -0500 Subject: [PATCH 12/13] change to relative tolerance --- .../tests/test_datasets/test_enhanced_cps.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/policyengine_us_data/tests/test_datasets/test_enhanced_cps.py b/policyengine_us_data/tests/test_datasets/test_enhanced_cps.py index 2acdc51b..e6dca88c 100644 --- a/policyengine_us_data/tests/test_datasets/test_enhanced_cps.py +++ b/policyengine_us_data/tests/test_datasets/test_enhanced_cps.py @@ -72,8 +72,9 @@ def apply(self): # Calculate tax expenditure tax_expenditure = (income_tax_r - income_tax_b).sum() + pct_error = abs((tax_expenditure - target) / target) + TOLERANCE = 0.15 - # Assert within 5bn of target assert ( - abs(tax_expenditure - target) < 5e9 - ), f"{deduction} tax expenditure {tax_expenditure/1e9:.1f}bn differs from target {target/1e9:.1f}bn by more than 5bn" + pct_error < TOLERANCE + ), f"{deduction} tax expenditure {tax_expenditure/1e9:.1f}bn differs from target {target/1e9:.1f}bn by {pct_error:.2%}" From b279d5afbf37ab6ff20a4d3b0139f7204dfe0d91 Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Mon, 17 Feb 2025 19:00:04 -0500 Subject: [PATCH 13/13] print deviations regardless --- .../tests/test_datasets/test_enhanced_cps.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/policyengine_us_data/tests/test_datasets/test_enhanced_cps.py b/policyengine_us_data/tests/test_datasets/test_enhanced_cps.py index e6dca88c..93b4580b 100644 --- a/policyengine_us_data/tests/test_datasets/test_enhanced_cps.py +++ b/policyengine_us_data/tests/test_datasets/test_enhanced_cps.py @@ -75,6 +75,7 @@ def apply(self): pct_error = abs((tax_expenditure - target) / target) TOLERANCE = 0.15 - assert ( - pct_error < TOLERANCE - ), f"{deduction} tax expenditure {tax_expenditure/1e9:.1f}bn differs from target {target/1e9:.1f}bn by {pct_error:.2%}" + print( + f"{deduction} tax expenditure {tax_expenditure/1e9:.1f}bn differs from target {target/1e9:.1f}bn by {pct_error:.2%}" + ) + assert pct_error < TOLERANCE, deduction