Skip to content

Comments

Fix intra-decile income change double-counting#239

Merged
anth-volk merged 9 commits into0.xfrom
fix/intra-decile-double-counting
Feb 24, 2026
Merged

Fix intra-decile income change double-counting#239
anth-volk merged 9 commits into0.xfrom
fix/intra-decile-double-counting

Conversation

@anth-volk
Copy link
Contributor

@anth-volk anth-volk commented Feb 24, 2026

Fixes #238
Fixes #240

Summary

  • Extracts a shared _compute_income_change(baseline_values, reform_values) helper that correctly computes (reform - baseline) / max(baseline, 1)
  • Replaces the buggy formula in both intra_decile_impact and intra_wealth_decile_impact that double-counted income changes by adding absolute_change to an already-changed reform_income
  • Fixes the same bug in decile.py (calculate_income_specific_decile_winners_losers, currently dead code)
  • Adds 12 regression tests with fixtures extracted to tests/fixtures/test_intra_decile.py
  • Installs both yaml-changelog and towncrier in the versioning workflow so it works for both 0.x (yaml-changelog) and main (towncrier) branches

Ports the intra-decile fix from policyengine-api#3283 to the 0.x maintenance branch.

Test plan

  • pytest tests/test_intra_decile.py — all 12 tests pass
  • CI passes on 0.x branch

🤖 Generated with Claude Code

anth-volk and others added 9 commits February 24, 2026 19:39
…anges

The intra_decile_impact and intra_wealth_decile_impact functions computed
capped_reform_income as max(reform, 1) + absolute_change, which double-counted
the change since reform already includes the change relative to baseline.
Extracted a shared compute_income_change helper that correctly computes
absolute_change / max(baseline, 1). Added 12 regression tests.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
calculate_income_specific_decile_winners_losers had the identical
capped_reform_income = max(reform, 1) + absolute_change bug. Currently
unreachable but fixing for consistency.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…name tests

- Prefix compute_income_change with underscore (internal helper)
- Move mock factory and constants to tests/fixtures/test_intra_decile.py
- Rename all tests to test__given_X__Y naming convention

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The 0.x versioning.yaml was also triggering on main pushes, which is
redundant since main has its own copy. Removes main from the trigger
branches to avoid conflicts.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The main branch Makefile uses towncrier for changelog generation but the
workflow only installed yaml-changelog, causing 'towncrier: not found'.
Install both so the workflow works for both 0.x (yaml-changelog) and
main (towncrier).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@anth-volk anth-volk marked this pull request as ready for review February 24, 2026 20:09
@anth-volk anth-volk merged commit e012d94 into 0.x Feb 24, 2026
3 checks passed
@anth-volk anth-volk deleted the fix/intra-decile-double-counting branch February 24, 2026 20:12
anth-volk added a commit to PolicyEngine/policyengine-api-v2 that referenced this pull request Feb 24, 2026
Picks up the fix for intra-decile income change double-counting
(PolicyEngine/policyengine.py#239).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant