A reform simulation's baseline reads the reform's default for people the situation gives no value
Maintainer thường phản hồi trong vòng 2 ngày
Đánh giá
- Độ khó
- 4/5
- Thời gian dự kiến
- 3-5 ngày
- Mức phù hợp với người mới
- 35/100
Hướng nghiên cứu
Start with Simulation.__init__ and _bind_to_tax_benefit_system, then trace SimulationBuilder's add_variable_value, expand_axes, and finalize_variables_init paths. Read tests/core/test_reform_baseline_system.py, especially test_an_input_default_the_reform_changes_is_the_baselines_in_the_baseline; reproduce the partial-input and neutralized-input cases from the issue. Done means the baseline matches a simulation built directly from the same situation under the baseline system, including defaults and inputs ignored by the reform.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
Problem
Simulation(situation=..., reform=...) builds the situation under the reform's tax-benefit system, then makes its baseline as a branch of that simulation and gives the branch the baseline system. When the situation gives a variable for some people and not others (or sets it along axes), SimulationBuilder fills the other entries with that variable's default from the system it was given, the reform's, and stores the whole array as an input (add_variable_value and expand_axes start from variable.default_array(...); finalize_variables_init calls holder.set_input with the full array). The baseline branch inherits those inputs, so it reads the reform's default for people the situation never gave a value.
Reproduced on master b909d5a60, from the repository root with uv run --frozen --extra dev python:
import sys; sys.path.insert(0, ".")
from policyengine_core.country_template import Simulation
from tests.core.test_reform_baseline_system import change_salary_default # salary default 0 -> 1000
P = "2022-01"
sit = {"persons": {"a": {"salary": {P: 3000.0}}, "b": {}}, "households": {"h": {"parents": ["a", "b"]}}}
s = Simulation(situation=sit, reform=change_salary_default)
print(s.baseline.calculate("salary", P)) # [3000. 1000.]
print(Simulation(situation=sit).calculate("salary", P)) # [3000. 0.]
With axes ("axes": [[{"name": "salary", "count": 2, "min": 0, "max": 5000, "period": P}]] over two people with no salary), the baseline gives [0, 1000, 5000, 1000]; the same situation built under the baseline system gives [0, 0, 5000, 0].
The same inheritance loses an input the reform neutralizes. The reform's system ignores a situation's income_tax (it warns that the variable is neutralized), so the baseline branch has no input either and calculates it:
from tests.core.test_reform_baseline_system import neutralize_income_tax
sit = {"persons": {"a": {"salary": {P: 3000.0}, "income_tax": {P: 7.0}}}, "households": {"h": {"parents": ["a"]}}}
print(Simulation(situation=sit, reform=neutralize_income_tax).baseline.calculate("income_tax", P)) # [450.00003]
print(Simulation(situation=sit).calculate("income_tax", P)) # [7.]
Simulation._bind_to_tax_benefit_system re-points the baseline's populations and holders at the baseline system's entities and variables, but the arrays it inherited were built by the reform's.
tests/core/test_reform_baseline_system.py::test_an_input_default_the_reform_changes_is_the_baselines_in_the_baseline notes the limitation in a comment and avoids it by giving no one a salary.
Expected
A reform simulation's baseline is what the builder makes from the situation under the baseline system: people the situation gives no value take the baseline system's default, and inputs the reform's system ignores are the baseline's.
Notes
- A stored input is all-or-nothing today:
Holder.set_input,_user_input_keys,StoreHistoryandto_input_dataframerecord and export whole arrays, andset_input_divide_by_period/set_input_dispatch_by_periodcombine a larger period's array with the sub-period inputs already stored. So the default given to one person at one period also changes what other periods' inputs are divided into. - policyengine-us reaches this through core's
Simulation.__init__. policyengine-uk builds its baseline as a separateSimulationfrom the situation, so it is not affected. - Related: #611 (the builder replaces a simulation's population) touches the same files.
- Ngôn ngữ chính
- Python
- Star
- 22
- Fork
- 30
- Merge trung bình
- 2 ngày 19 giờ
- Pull request đã merge (30 ngày)
- 25
Chuẩn bị môi trường
- Không có Dockerfile hay tệp Docker Compose
- Có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của PolicyEngine/policyengine-core
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 76/100
PolicyEngine/policyengine-core#605 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 2 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
PolicyEngine/policyengine-core#549 ·
Maintainer thường phản hồi trong vòng 2 ngày
-
`restore_simulation` silently drops memberless group entitiesCó thể đã có người làm @Adelagric đã nhận 33 ngày trước. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
PolicyEngine/policyengine-core#547 ·
Maintainer thường phản hồi trong vòng 2 ngày
-
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 57/100
PolicyEngine/policyengine-core#614 ·
Maintainer thường phản hồi trong vòng 2 ngày
-
Độ khó 5/5 Hơn một tuần Mức phù hợp với người mới 35/100
PolicyEngine/policyengine-core#609 ·
Maintainer thường phản hồi trong vòng 2 ngày
Tất cả issue của PolicyEngine/policyengine-core
Issue tương tự
-
vis.image() reports "Unsupported number of image channels: 224" for an HxWxC imageCó thể đã có người làm @piyush182004 đã nhận hôm nay. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 62/100
fossasia/visdom#1997 · 3 bình luận ·
Maintainer thường phản hồi trong vòng 6 ngày
-
Byse new domainĐang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 62/100
Gujal00/ResolveURL#1525 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Serialisation fails with pydantic 2.14: wrap serialisers pass SerializationInfo as index_keyCó thể đã có người làm @hugohills-regnosys đã nhận hôm nay. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 82/100
finos/rune-python-runtime#45 ·
-
[Bug]: LangGraph Store sync put bypasses namespace validationCó thể đã có người làm @ktz03 đã nhận hôm nay. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
volcengine/OpenViking#6050 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
bug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
hummingbot/condor#283 ·
Maintainer thường phản hồi trong vòng 1 ngày