From 610d4e055277c8acfb7b94383f10c2b866900828 Mon Sep 17 00:00:00 2001 From: Ziming Date: Mon, 15 Dec 2025 00:28:11 -0500 Subject: [PATCH 01/11] draft --- changelog_entry.yaml | 7 + .../il/isbe/pi/eligibility/age/maximum.yaml | 13 ++ .../eligibility/income/countable_sources.yaml | 30 ++++ .../eligibility/income/deep_poverty_rate.yaml | 11 ++ .../eligibility/income/low_income_rate.yaml | 11 ++ .../pi/eligibility/income/max_fpg_rate.yaml | 11 ++ .../risk_factors/minimum_required.yaml | 11 ++ .../isbe/pi/eligibility/il_pi_eligible.yaml | 38 +++++ .../pi/eligibility/il_pi_eligible_child.yaml | 39 +++++ .../eligibility/il_pi_eligible_pregnant.yaml | 15 ++ .../eligibility/il_pi_highest_priority.yaml | 47 ++++++ .../gov/states/il/isbe/pi/integration.yaml | 147 ++++++++++++++++++ .../pi/eligibility/il_pi_countable_income.py | 13 ++ .../pi/eligibility/il_pi_eligible_child.py | 16 ++ .../pi/eligibility/il_pi_eligible_pregnant.py | 14 ++ .../pi/eligibility/il_pi_income_eligible.py | 18 +++ .../pi/eligibility/il_pi_risk_eligible.py | 18 +++ .../priority/il_pi_highest_priority.py | 33 ++++ .../priority/il_pi_is_deep_poverty.py | 20 +++ .../priority/il_pi_is_low_income.py | 20 +++ .../il_pi_receives_categorical_benefits.py | 20 +++ .../priority/il_pi_risk_factor_count.py | 50 ++++++ .../gov/states/il/isbe/pi/il_pi_eligible.py | 20 +++ .../is_non_english_speaking_home.py | 8 + .../person/has_developmental_delay.py | 8 + .../household/demographic/person/has_iep.py | 8 + .../is_enrolled_in_early_intervention.py | 8 + ...ent_has_less_than_high_school_education.py | 8 + 28 files changed, 662 insertions(+) create mode 100644 policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/age/maximum.yaml create mode 100644 policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/income/countable_sources.yaml create mode 100644 policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/income/deep_poverty_rate.yaml create mode 100644 policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/income/low_income_rate.yaml create mode 100644 policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/income/max_fpg_rate.yaml create mode 100644 policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/risk_factors/minimum_required.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/il_pi_eligible.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/il_pi_eligible_child.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/il_pi_eligible_pregnant.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/il_pi_highest_priority.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/integration.yaml create mode 100644 policyengine_us/variables/gov/states/il/isbe/pi/eligibility/il_pi_countable_income.py create mode 100644 policyengine_us/variables/gov/states/il/isbe/pi/eligibility/il_pi_eligible_child.py create mode 100644 policyengine_us/variables/gov/states/il/isbe/pi/eligibility/il_pi_eligible_pregnant.py create mode 100644 policyengine_us/variables/gov/states/il/isbe/pi/eligibility/il_pi_income_eligible.py create mode 100644 policyengine_us/variables/gov/states/il/isbe/pi/eligibility/il_pi_risk_eligible.py create mode 100644 policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_highest_priority.py create mode 100644 policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_is_deep_poverty.py create mode 100644 policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_is_low_income.py create mode 100644 policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_receives_categorical_benefits.py create mode 100644 policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_risk_factor_count.py create mode 100644 policyengine_us/variables/gov/states/il/isbe/pi/il_pi_eligible.py create mode 100644 policyengine_us/variables/household/demographic/geographic/is_non_english_speaking_home.py create mode 100644 policyengine_us/variables/household/demographic/person/has_developmental_delay.py create mode 100644 policyengine_us/variables/household/demographic/person/has_iep.py create mode 100644 policyengine_us/variables/household/demographic/person/is_enrolled_in_early_intervention.py create mode 100644 policyengine_us/variables/household/demographic/person/parent_has_less_than_high_school_education.py diff --git a/changelog_entry.yaml b/changelog_entry.yaml index e69de29bb2d..5fc8fb1897d 100644 --- a/changelog_entry.yaml +++ b/changelog_entry.yaml @@ -0,0 +1,7 @@ +- bump: minor + changes: + added: + - Illinois Prevention Initiative (PI) program eligibility for children birth to age 3 and pregnant women. + - PI priority factors including foster care, homelessness, deep poverty, Early Intervention enrollment, and developmental delay. + - PI risk factor counting for eligibility determination. + - New input variables for IEP status, developmental delay, non-English speaking home, parent education level, and Early Intervention enrollment. diff --git a/policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/age/maximum.yaml b/policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/age/maximum.yaml new file mode 100644 index 00000000000..930f0e2ef78 --- /dev/null +++ b/policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/age/maximum.yaml @@ -0,0 +1,13 @@ +description: Illinois limits eligibility to children under this age for the Prevention Initiative program. +values: + 2015-01-01: 3 + +metadata: + unit: year + period: year + label: Illinois PI maximum age + reference: + - title: ISBE Prevention Initiative Program + href: https://www.isbe.net/Pages/Birth-to-Age-3-Years.aspx + - title: IECAM Prevention Initiative Description + href: https://iecam.illinois.edu/data-descriptions/prevention-initiative-pi diff --git a/policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/income/countable_sources.yaml b/policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/income/countable_sources.yaml new file mode 100644 index 00000000000..d04a81e7037 --- /dev/null +++ b/policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/income/countable_sources.yaml @@ -0,0 +1,30 @@ +description: Illinois counts these income sources as countable income under the Prevention Initiative program. +values: + 2015-01-01: + # Earned income + - employment_income + - self_employment_income + # Unearned income included per ISBE Household and Income Form + - child_support_received + - alimony_income + - pension_income + - retirement_distributions + - social_security + - ssi + - veterans_benefits + - disability_benefits + - workers_compensation + - unemployment_compensation + - strike_benefits + # Excluded: snap, wic, tanf (welfare benefits) + # Excluded: Federal education benefits, foster payments + +metadata: + unit: list + period: year + label: Illinois PI countable income sources + reference: + - title: ISBE Household and Income Form + href: https://www.isbe.net/Documents/69-72_hshld_income.pdf + - title: ISBE FY 2026 Income Eligibility Guidelines + href: https://www.isbe.net/Documents/IEG-26.pdf diff --git a/policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/income/deep_poverty_rate.yaml b/policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/income/deep_poverty_rate.yaml new file mode 100644 index 00000000000..799a4bc795d --- /dev/null +++ b/policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/income/deep_poverty_rate.yaml @@ -0,0 +1,11 @@ +description: Illinois considers families with income at or below this share of the federal poverty guideline as deep poverty under the Prevention Initiative program. +values: + 2015-01-01: 0.5 + +metadata: + unit: /1 + period: year + label: Illinois PI deep poverty threshold as share of FPL + reference: + - title: ISBE Prevention Initiative Manual + href: https://www.isbe.net/Documents/prevention-initiative-manual.pdf diff --git a/policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/income/low_income_rate.yaml b/policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/income/low_income_rate.yaml new file mode 100644 index 00000000000..63add61a787 --- /dev/null +++ b/policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/income/low_income_rate.yaml @@ -0,0 +1,11 @@ +description: Illinois considers families with income at or below this share of the federal poverty guideline as low income under the Prevention Initiative program. +values: + 2015-01-01: 2 + +metadata: + unit: /1 + period: year + label: Illinois PI low income threshold as share of FPL + reference: + - title: ISBE Prevention Initiative Manual + href: https://www.isbe.net/Documents/prevention-initiative-manual.pdf diff --git a/policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/income/max_fpg_rate.yaml b/policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/income/max_fpg_rate.yaml new file mode 100644 index 00000000000..b3595bc5911 --- /dev/null +++ b/policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/income/max_fpg_rate.yaml @@ -0,0 +1,11 @@ +description: Illinois limits eligibility to families with income at or below this share of the federal poverty guideline under the Prevention Initiative program. +values: + 2015-01-01: 4 + +metadata: + unit: /1 + period: year + label: Illinois PI maximum income as share of FPL + reference: + - title: CECIDS Methodology - Prevention Initiative + href: https://cecids.org/methodology/ diff --git a/policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/risk_factors/minimum_required.yaml b/policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/risk_factors/minimum_required.yaml new file mode 100644 index 00000000000..2dc66d0e0aa --- /dev/null +++ b/policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/risk_factors/minimum_required.yaml @@ -0,0 +1,11 @@ +description: Illinois requires at least this many risk factors for eligibility under the Prevention Initiative program. +values: + 2015-01-01: 1 + +metadata: + unit: /1 + period: year + label: Illinois PI minimum required risk factors + reference: + - title: ISBE Prevention Initiative Manual + href: https://www.isbe.net/Documents/prevention-initiative-manual.pdf diff --git a/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/il_pi_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/il_pi_eligible.yaml new file mode 100644 index 00000000000..582ae60961e --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/il_pi_eligible.yaml @@ -0,0 +1,38 @@ +- name: Case 1, eligible infant with developmental delay. + period: 2024 + input: + state_code: IL + age: 1 + has_developmental_delay: true + employment_income: 30_000 + output: + il_pi_eligible: true + +- name: Case 2, eligible pregnant woman in deep poverty. + period: 2024 + input: + state_code: IL + age: 25 + is_pregnant: true + employment_income: 5_000 + output: + il_pi_eligible: true + +- name: Case 3, ineligible child age 3 too old. + period: 2024 + input: + state_code: IL + age: 3 + has_developmental_delay: true + employment_income: 30_000 + output: + il_pi_eligible: false + +- name: Case 4, ineligible no risk factors. + period: 2024 + input: + state_code: IL + age: 1 + employment_income: 100_000 + output: + il_pi_eligible: false diff --git a/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/il_pi_eligible_child.yaml b/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/il_pi_eligible_child.yaml new file mode 100644 index 00000000000..cebaa0cefaf --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/il_pi_eligible_child.yaml @@ -0,0 +1,39 @@ +- name: Case 1, eligible infant age 0. + period: 2024 + input: + age: 0 + state_code: IL + output: + il_pi_eligible_child: true + +- name: Case 2, eligible toddler age 1. + period: 2024 + input: + age: 1 + state_code: IL + output: + il_pi_eligible_child: true + +- name: Case 3, eligible toddler age 2. + period: 2024 + input: + age: 2 + state_code: IL + output: + il_pi_eligible_child: true + +- name: Case 4, ineligible child age 3 transitions to PFA. + period: 2024 + input: + age: 3 + state_code: IL + output: + il_pi_eligible_child: false + +- name: Case 5, ineligible child age 4. + period: 2024 + input: + age: 4 + state_code: IL + output: + il_pi_eligible_child: false diff --git a/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/il_pi_eligible_pregnant.yaml b/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/il_pi_eligible_pregnant.yaml new file mode 100644 index 00000000000..77c4c6c3789 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/il_pi_eligible_pregnant.yaml @@ -0,0 +1,15 @@ +- name: Case 1, pregnant woman eligible. + period: 2024 + input: + state_code: IL + is_pregnant: true + output: + il_pi_eligible_pregnant: true + +- name: Case 2, not pregnant not eligible via pregnancy. + period: 2024 + input: + state_code: IL + is_pregnant: false + output: + il_pi_eligible_pregnant: false diff --git a/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/il_pi_highest_priority.yaml b/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/il_pi_highest_priority.yaml new file mode 100644 index 00000000000..193956b4c72 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/il_pi_highest_priority.yaml @@ -0,0 +1,47 @@ +- name: Case 1, homeless is highest priority. + period: 2024 + input: + state_code: IL + is_homeless: true + output: + il_pi_highest_priority: true + +- name: Case 2, foster care is highest priority. + period: 2024 + input: + state_code: IL + is_in_foster_care: true + output: + il_pi_highest_priority: true + +- name: Case 3, Early Intervention is highest priority. + period: 2024 + input: + state_code: IL + is_enrolled_in_early_intervention: true + output: + il_pi_highest_priority: true + +- name: Case 4, developmental delay is highest priority. + period: 2024 + input: + state_code: IL + has_developmental_delay: true + output: + il_pi_highest_priority: true + +- name: Case 5, non-English home is highest priority. + period: 2024 + input: + state_code: IL + is_non_english_speaking_home: true + output: + il_pi_highest_priority: true + +- name: Case 6, no priority factors. + period: 2024 + input: + state_code: IL + employment_income: 50_000 + output: + il_pi_highest_priority: false diff --git a/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/integration.yaml b/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/integration.yaml new file mode 100644 index 00000000000..23bd66b2b0a --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/integration.yaml @@ -0,0 +1,147 @@ +- name: Case 1, low income family with infant in Early Intervention. + period: 2024 + input: + people: + person1: + age: 28 + employment_income: 25_000 + person2: + age: 1 + is_enrolled_in_early_intervention: true + households: + household: + members: [person1, person2] + state_code: IL + spm_units: + spm_unit: + members: [person1, person2] + tax_units: + tax_unit: + members: [person1, person2] + output: + il_pi_eligible_child: [false, true] + il_pi_highest_priority: [false, true] + il_pi_eligible: [false, true] + +- name: Case 2, pregnant woman in non-English speaking home. + period: 2024 + input: + people: + person1: + age: 22 + is_pregnant: true + employment_income: 20_000 + households: + household: + members: [person1] + state_code: IL + is_non_english_speaking_home: true + spm_units: + spm_unit: + members: [person1] + tax_units: + tax_unit: + members: [person1] + output: + il_pi_eligible_pregnant: [true] + il_pi_highest_priority: [true] + il_pi_eligible: [true] + +- name: Case 3, homeless family with toddler. + period: 2024 + input: + people: + person1: + age: 30 + employment_income: 8_000 + person2: + age: 2 + households: + household: + members: [person1, person2] + state_code: IL + is_homeless: true + spm_units: + spm_unit: + members: [person1, person2] + tax_units: + tax_unit: + members: [person1, person2] + output: + il_pi_eligible_child: [false, true] + il_pi_highest_priority: [true, true] + il_pi_eligible: [false, true] + +- name: Case 4, higher income family no risk factors ineligible. + period: 2024 + input: + people: + person1: + age: 35 + employment_income: 150_000 + person2: + age: 1 + households: + household: + members: [person1, person2] + state_code: IL + spm_units: + spm_unit: + members: [person1, person2] + tax_units: + tax_unit: + members: [person1, person2] + output: + il_pi_eligible_child: [false, true] + il_pi_risk_factor_count: [0, 0] + il_pi_eligible: [false, false] + +- name: Case 5, child age 3 transitions out of PI. + period: 2024 + input: + people: + person1: + age: 30 + employment_income: 20_000 + person2: + age: 3 + has_developmental_delay: true + households: + household: + members: [person1, person2] + state_code: IL + spm_units: + spm_unit: + members: [person1, person2] + tax_units: + tax_unit: + members: [person1, person2] + output: + il_pi_eligible_child: [false, false] + # Child has developmental delay but too old for PI + il_pi_eligible: [false, false] + +- name: Case 6, foster child infant highest priority. + period: 2024 + input: + people: + person1: + age: 40 + employment_income: 60_000 + person2: + age: 0 + is_in_foster_care: true + households: + household: + members: [person1, person2] + state_code: IL + spm_units: + spm_unit: + members: [person1, person2] + tax_units: + tax_unit: + members: [person1, person2] + output: + il_pi_eligible_child: [false, true] + il_pi_highest_priority: [false, true] + il_pi_eligible: [false, true] diff --git a/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/il_pi_countable_income.py b/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/il_pi_countable_income.py new file mode 100644 index 00000000000..a3b11b79f57 --- /dev/null +++ b/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/il_pi_countable_income.py @@ -0,0 +1,13 @@ +from policyengine_us.model_api import * + + +class il_pi_countable_income(Variable): + value_type = float + entity = SPMUnit + label = "Illinois PI countable income" + unit = USD + definition_period = YEAR + reference = "https://www.isbe.net/Documents/69-72_hshld_income.pdf" + defined_for = StateCode.IL + + adds = "gov.states.il.isbe.pi.eligibility.income.countable_sources" diff --git a/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/il_pi_eligible_child.py b/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/il_pi_eligible_child.py new file mode 100644 index 00000000000..cf211845ded --- /dev/null +++ b/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/il_pi_eligible_child.py @@ -0,0 +1,16 @@ +from policyengine_us.model_api import * + + +class il_pi_eligible_child(Variable): + value_type = bool + entity = Person + label = "Child meets age requirements for Illinois PI" + definition_period = YEAR + reference = "https://www.isbe.net/Pages/Birth-to-Age-3-Years.aspx" + defined_for = StateCode.IL + + def formula(person, period, parameters): + # Children under age 3 (birth to age 3) are eligible. + p = parameters(period).gov.states.il.isbe.pi.eligibility.age + age = person("age", period) + return age < p.maximum diff --git a/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/il_pi_eligible_pregnant.py b/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/il_pi_eligible_pregnant.py new file mode 100644 index 00000000000..1274a7472ef --- /dev/null +++ b/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/il_pi_eligible_pregnant.py @@ -0,0 +1,14 @@ +from policyengine_us.model_api import * + + +class il_pi_eligible_pregnant(Variable): + value_type = bool + entity = Person + label = "Pregnant woman eligible for Illinois PI" + definition_period = YEAR + reference = "https://www.isbe.net/Pages/Birth-to-Age-3-Years.aspx" + defined_for = StateCode.IL + + def formula(person, period, parameters): + # Expecting parents are eligible for PI services. + return person("is_pregnant", period) diff --git a/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/il_pi_income_eligible.py b/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/il_pi_income_eligible.py new file mode 100644 index 00000000000..bb26450535b --- /dev/null +++ b/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/il_pi_income_eligible.py @@ -0,0 +1,18 @@ +from policyengine_us.model_api import * + + +class il_pi_income_eligible(Variable): + value_type = bool + entity = Person + label = "Meets income requirements for Illinois PI" + definition_period = YEAR + reference = "https://cecids.org/methodology/" + defined_for = StateCode.IL + + def formula(person, period, parameters): + # Income must be at or below 400% FPL. + p = parameters(period).gov.states.il.isbe.pi.eligibility.income + fpg = person.spm_unit("spm_unit_fpg", period) + income = person.spm_unit("il_pi_countable_income", period) + threshold = fpg * p.max_fpg_rate + return income <= threshold diff --git a/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/il_pi_risk_eligible.py b/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/il_pi_risk_eligible.py new file mode 100644 index 00000000000..353bb66f22c --- /dev/null +++ b/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/il_pi_risk_eligible.py @@ -0,0 +1,18 @@ +from policyengine_us.model_api import * + + +class il_pi_risk_eligible(Variable): + value_type = bool + entity = Person + label = "Meets risk factor requirements for Illinois PI" + definition_period = YEAR + reference = ( + "https://www.isbe.net/Documents/prevention-initiative-manual.pdf" + ) + defined_for = StateCode.IL + + def formula(person, period, parameters): + # Eligible if has at least minimum required risk factors. + p = parameters(period).gov.states.il.isbe.pi.eligibility.risk_factors + risk_count = person("il_pi_risk_factor_count", period) + return risk_count >= p.minimum_required diff --git a/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_highest_priority.py b/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_highest_priority.py new file mode 100644 index 00000000000..a0cc4a08599 --- /dev/null +++ b/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_highest_priority.py @@ -0,0 +1,33 @@ +from policyengine_us.model_api import * + + +class il_pi_highest_priority(Variable): + value_type = bool + entity = Person + label = "Has a highest priority factor for Illinois PI" + definition_period = YEAR + reference = ( + "https://www.isbe.net/Documents/prevention-initiative-manual.pdf" + ) + defined_for = StateCode.IL + + def formula(person, period, parameters): + # Highest priority factors: foster care, homeless, deep poverty, + # Early Intervention, developmental delay, non-English home. + is_homeless = person.household("is_homeless", period) + is_in_foster_care = person("is_in_foster_care", period) + is_deep_poverty = person("il_pi_is_deep_poverty", period) + is_enrolled_ei = person("is_enrolled_in_early_intervention", period) + has_developmental_delay = person("has_developmental_delay", period) + is_non_english_home = person.household( + "is_non_english_speaking_home", period + ) + + return ( + is_homeless + | is_in_foster_care + | is_deep_poverty + | is_enrolled_ei + | has_developmental_delay + | is_non_english_home + ) diff --git a/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_is_deep_poverty.py b/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_is_deep_poverty.py new file mode 100644 index 00000000000..290ad59b6f1 --- /dev/null +++ b/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_is_deep_poverty.py @@ -0,0 +1,20 @@ +from policyengine_us.model_api import * + + +class il_pi_is_deep_poverty(Variable): + value_type = bool + entity = Person + label = "In deep poverty for Illinois PI (highest priority)" + definition_period = YEAR + reference = ( + "https://www.isbe.net/Documents/prevention-initiative-manual.pdf" + ) + defined_for = StateCode.IL + + def formula(person, period, parameters): + # Deep poverty: income at or below 50% FPL. + p = parameters(period).gov.states.il.isbe.pi.eligibility.income + fpg = person.spm_unit("spm_unit_fpg", period) + income = person.spm_unit("il_pi_countable_income", period) + threshold = fpg * p.deep_poverty_rate + return income <= threshold diff --git a/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_is_low_income.py b/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_is_low_income.py new file mode 100644 index 00000000000..a10452f4e86 --- /dev/null +++ b/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_is_low_income.py @@ -0,0 +1,20 @@ +from policyengine_us.model_api import * + + +class il_pi_is_low_income(Variable): + value_type = bool + entity = Person + label = "Low income for Illinois PI" + definition_period = YEAR + reference = ( + "https://www.isbe.net/Documents/prevention-initiative-manual.pdf" + ) + defined_for = StateCode.IL + + def formula(person, period, parameters): + # Low income: income at or below 200% FPL. + p = parameters(period).gov.states.il.isbe.pi.eligibility.income + fpg = person.spm_unit("spm_unit_fpg", period) + income = person.spm_unit("il_pi_countable_income", period) + threshold = fpg * p.low_income_rate + return income <= threshold diff --git a/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_receives_categorical_benefits.py b/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_receives_categorical_benefits.py new file mode 100644 index 00000000000..900f3a6ecf2 --- /dev/null +++ b/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_receives_categorical_benefits.py @@ -0,0 +1,20 @@ +from policyengine_us.model_api import * + + +class il_pi_receives_categorical_benefits(Variable): + value_type = bool + entity = Person + label = "Family receives categorical benefits (risk factor for IL PI)" + definition_period = YEAR + reference = ( + "https://www.isbe.net/Documents/prevention-initiative-manual.pdf" + ) + defined_for = StateCode.IL + + def formula(person, period, parameters): + # Check for participation in categorical benefit programs. + snap = person.spm_unit("snap", period) > 0 + tanf = person.spm_unit("tanf", period) > 0 + wic = add(person.spm_unit, period, ["wic"]) > 0 + medicaid = person("is_medicaid_eligible", period) + return snap | tanf | wic | medicaid diff --git a/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_risk_factor_count.py b/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_risk_factor_count.py new file mode 100644 index 00000000000..d4114947014 --- /dev/null +++ b/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_risk_factor_count.py @@ -0,0 +1,50 @@ +from policyengine_us.model_api import * + + +class il_pi_risk_factor_count(Variable): + value_type = int + entity = Person + label = "Number of risk factors for Illinois PI eligibility" + definition_period = YEAR + reference = ( + "https://www.isbe.net/Documents/prevention-initiative-manual.pdf" + ) + defined_for = StateCode.IL + + def formula(person, period, parameters): + # Highest priority factors (each also counts as a risk factor) + is_homeless = person.household("is_homeless", period) + is_in_foster_care = person("is_in_foster_care", period) + is_deep_poverty = person("il_pi_is_deep_poverty", period) + is_enrolled_ei = person("is_enrolled_in_early_intervention", period) + has_developmental_delay = person("has_developmental_delay", period) + is_non_english_home = person.household( + "is_non_english_speaking_home", period + ) + + # Standard risk factors + is_low_income = person("il_pi_is_low_income", period) + receives_benefits = person( + "il_pi_receives_categorical_benefits", period + ) + parent_low_education = person( + "parent_has_less_than_high_school_education", period + ) + needs_protective_services = person( + "receives_or_needs_protective_services", period + ) + + factors = [ + is_homeless, + is_in_foster_care, + is_deep_poverty, + is_enrolled_ei, + has_developmental_delay, + is_non_english_home, + is_low_income, + receives_benefits, + parent_low_education, + needs_protective_services, + ] + + return sum([f.astype(int) for f in factors]) diff --git a/policyengine_us/variables/gov/states/il/isbe/pi/il_pi_eligible.py b/policyengine_us/variables/gov/states/il/isbe/pi/il_pi_eligible.py new file mode 100644 index 00000000000..d582f44e1f9 --- /dev/null +++ b/policyengine_us/variables/gov/states/il/isbe/pi/il_pi_eligible.py @@ -0,0 +1,20 @@ +from policyengine_us.model_api import * + + +class il_pi_eligible(Variable): + value_type = bool + entity = Person + label = "Eligible for Illinois Prevention Initiative" + definition_period = YEAR + reference = "https://www.isbe.net/Pages/Birth-to-Age-3-Years.aspx" + defined_for = StateCode.IL + + def formula(person, period, parameters): + # Eligibility requires: (child under 3 OR pregnant), + # income <= 400% FPL, and at least 1 risk factor. + eligible_child = person("il_pi_eligible_child", period) + eligible_pregnant = person("il_pi_eligible_pregnant", period) + age_eligible = eligible_child | eligible_pregnant + income_eligible = person("il_pi_income_eligible", period) + risk_eligible = person("il_pi_risk_eligible", period) + return age_eligible & income_eligible & risk_eligible diff --git a/policyengine_us/variables/household/demographic/geographic/is_non_english_speaking_home.py b/policyengine_us/variables/household/demographic/geographic/is_non_english_speaking_home.py new file mode 100644 index 00000000000..ea77a8fde6a --- /dev/null +++ b/policyengine_us/variables/household/demographic/geographic/is_non_english_speaking_home.py @@ -0,0 +1,8 @@ +from policyengine_us.model_api import * + + +class is_non_english_speaking_home(Variable): + value_type = bool + entity = Household + label = "Primary language spoken at home is not English" + definition_period = YEAR diff --git a/policyengine_us/variables/household/demographic/person/has_developmental_delay.py b/policyengine_us/variables/household/demographic/person/has_developmental_delay.py new file mode 100644 index 00000000000..a88e6c5522e --- /dev/null +++ b/policyengine_us/variables/household/demographic/person/has_developmental_delay.py @@ -0,0 +1,8 @@ +from policyengine_us.model_api import * + + +class has_developmental_delay(Variable): + value_type = bool + entity = Person + label = "Has a developmental delay" + definition_period = YEAR diff --git a/policyengine_us/variables/household/demographic/person/has_iep.py b/policyengine_us/variables/household/demographic/person/has_iep.py new file mode 100644 index 00000000000..791fd6b4720 --- /dev/null +++ b/policyengine_us/variables/household/demographic/person/has_iep.py @@ -0,0 +1,8 @@ +from policyengine_us.model_api import * + + +class has_iep(Variable): + value_type = bool + entity = Person + label = "Has an Individualized Education Program (IEP)" + definition_period = YEAR diff --git a/policyengine_us/variables/household/demographic/person/is_enrolled_in_early_intervention.py b/policyengine_us/variables/household/demographic/person/is_enrolled_in_early_intervention.py new file mode 100644 index 00000000000..0a1245b329d --- /dev/null +++ b/policyengine_us/variables/household/demographic/person/is_enrolled_in_early_intervention.py @@ -0,0 +1,8 @@ +from policyengine_us.model_api import * + + +class is_enrolled_in_early_intervention(Variable): + value_type = bool + entity = Person + label = "Enrolled in Part C Early Intervention services" + definition_period = YEAR diff --git a/policyengine_us/variables/household/demographic/person/parent_has_less_than_high_school_education.py b/policyengine_us/variables/household/demographic/person/parent_has_less_than_high_school_education.py new file mode 100644 index 00000000000..67756f90257 --- /dev/null +++ b/policyengine_us/variables/household/demographic/person/parent_has_less_than_high_school_education.py @@ -0,0 +1,8 @@ +from policyengine_us.model_api import * + + +class parent_has_less_than_high_school_education(Variable): + value_type = bool + entity = Person + label = "Parent has less than high school education" + definition_period = YEAR From aa66036b447c197fc8440f833273a595e0287341 Mon Sep 17 00:00:00 2001 From: Ziming Date: Tue, 16 Dec 2025 11:52:03 -0500 Subject: [PATCH 02/11] minor --- .../eligibility => }/income/countable_sources.yaml | 8 +++----- .../il/isbe/income/il_isbe_countable_income.py | 13 +++++++++++++ .../isbe/pi/eligibility/il_pi_countable_income.py | 13 ------------- .../il/isbe/pi/eligibility/il_pi_income_eligible.py | 5 +++-- .../eligibility/priority/il_pi_is_deep_poverty.py | 5 +++-- .../pi/eligibility/priority/il_pi_is_low_income.py | 5 +++-- .../priority/il_pi_receives_categorical_benefits.py | 7 ++++--- .../person/has_prior_formal_early_learning.py | 9 +++++++++ .../demographic/person/is_born_outside_us.py | 9 +++++++++ .../person/was_teen_parent_at_first_birth.py | 9 +++++++++ 10 files changed, 56 insertions(+), 27 deletions(-) rename policyengine_us/parameters/gov/states/il/isbe/{pi/eligibility => }/income/countable_sources.yaml (67%) create mode 100644 policyengine_us/variables/gov/states/il/isbe/income/il_isbe_countable_income.py delete mode 100644 policyengine_us/variables/gov/states/il/isbe/pi/eligibility/il_pi_countable_income.py create mode 100644 policyengine_us/variables/household/demographic/person/has_prior_formal_early_learning.py create mode 100644 policyengine_us/variables/household/demographic/person/is_born_outside_us.py create mode 100644 policyengine_us/variables/household/demographic/person/was_teen_parent_at_first_birth.py diff --git a/policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/income/countable_sources.yaml b/policyengine_us/parameters/gov/states/il/isbe/income/countable_sources.yaml similarity index 67% rename from policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/income/countable_sources.yaml rename to policyengine_us/parameters/gov/states/il/isbe/income/countable_sources.yaml index d04a81e7037..4e653164d2a 100644 --- a/policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/income/countable_sources.yaml +++ b/policyengine_us/parameters/gov/states/il/isbe/income/countable_sources.yaml @@ -1,4 +1,4 @@ -description: Illinois counts these income sources as countable income under the Prevention Initiative program. +description: Illinois uses these income sources to calculate countable income under the Illinois State Board of Education early childhood programs. values: 2015-01-01: # Earned income @@ -22,9 +22,7 @@ values: metadata: unit: list period: year - label: Illinois PI countable income sources + label: Illinois ISBE countable income sources reference: - - title: ISBE Household and Income Form + - title: ISBE Household and Income Form (69-72) href: https://www.isbe.net/Documents/69-72_hshld_income.pdf - - title: ISBE FY 2026 Income Eligibility Guidelines - href: https://www.isbe.net/Documents/IEG-26.pdf diff --git a/policyengine_us/variables/gov/states/il/isbe/income/il_isbe_countable_income.py b/policyengine_us/variables/gov/states/il/isbe/income/il_isbe_countable_income.py new file mode 100644 index 00000000000..691802f3e9c --- /dev/null +++ b/policyengine_us/variables/gov/states/il/isbe/income/il_isbe_countable_income.py @@ -0,0 +1,13 @@ +from policyengine_us.model_api import * + + +class il_isbe_countable_income(Variable): + value_type = float + entity = SPMUnit + label = "Illinois ISBE countable income" + unit = USD + definition_period = YEAR + reference = "https://www.isbe.net/Documents/Income-Verification-FAQ.pdf" + defined_for = StateCode.IL + + adds = "gov.states.il.isbe.income.countable_sources" diff --git a/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/il_pi_countable_income.py b/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/il_pi_countable_income.py deleted file mode 100644 index a3b11b79f57..00000000000 --- a/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/il_pi_countable_income.py +++ /dev/null @@ -1,13 +0,0 @@ -from policyengine_us.model_api import * - - -class il_pi_countable_income(Variable): - value_type = float - entity = SPMUnit - label = "Illinois PI countable income" - unit = USD - definition_period = YEAR - reference = "https://www.isbe.net/Documents/69-72_hshld_income.pdf" - defined_for = StateCode.IL - - adds = "gov.states.il.isbe.pi.eligibility.income.countable_sources" diff --git a/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/il_pi_income_eligible.py b/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/il_pi_income_eligible.py index bb26450535b..323ea255fa6 100644 --- a/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/il_pi_income_eligible.py +++ b/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/il_pi_income_eligible.py @@ -10,9 +10,10 @@ class il_pi_income_eligible(Variable): defined_for = StateCode.IL def formula(person, period, parameters): + spm_unit = person.spm_unit # Income must be at or below 400% FPL. p = parameters(period).gov.states.il.isbe.pi.eligibility.income - fpg = person.spm_unit("spm_unit_fpg", period) - income = person.spm_unit("il_pi_countable_income", period) + fpg = spm_unit("spm_unit_fpg", period) + income = spm_unit("il_isbe_countable_income", period) threshold = fpg * p.max_fpg_rate return income <= threshold diff --git a/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_is_deep_poverty.py b/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_is_deep_poverty.py index 290ad59b6f1..b426f332764 100644 --- a/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_is_deep_poverty.py +++ b/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_is_deep_poverty.py @@ -12,9 +12,10 @@ class il_pi_is_deep_poverty(Variable): defined_for = StateCode.IL def formula(person, period, parameters): + spm_unit = person.spm_unit # Deep poverty: income at or below 50% FPL. p = parameters(period).gov.states.il.isbe.pi.eligibility.income - fpg = person.spm_unit("spm_unit_fpg", period) - income = person.spm_unit("il_pi_countable_income", period) + fpg = spm_unit("spm_unit_fpg", period) + income = spm_unit("il_isbe_countable_income", period) threshold = fpg * p.deep_poverty_rate return income <= threshold diff --git a/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_is_low_income.py b/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_is_low_income.py index a10452f4e86..ea977941358 100644 --- a/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_is_low_income.py +++ b/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_is_low_income.py @@ -12,9 +12,10 @@ class il_pi_is_low_income(Variable): defined_for = StateCode.IL def formula(person, period, parameters): + spm_unit = person.spm_unit # Low income: income at or below 200% FPL. p = parameters(period).gov.states.il.isbe.pi.eligibility.income - fpg = person.spm_unit("spm_unit_fpg", period) - income = person.spm_unit("il_pi_countable_income", period) + fpg = spm_unit("spm_unit_fpg", period) + income = spm_unit("il_isbe_countable_income", period) threshold = fpg * p.low_income_rate return income <= threshold diff --git a/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_receives_categorical_benefits.py b/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_receives_categorical_benefits.py index 900f3a6ecf2..fe4dc72d821 100644 --- a/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_receives_categorical_benefits.py +++ b/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_receives_categorical_benefits.py @@ -12,9 +12,10 @@ class il_pi_receives_categorical_benefits(Variable): defined_for = StateCode.IL def formula(person, period, parameters): + spm_unit = person.spm_unit # Check for participation in categorical benefit programs. - snap = person.spm_unit("snap", period) > 0 - tanf = person.spm_unit("tanf", period) > 0 - wic = add(person.spm_unit, period, ["wic"]) > 0 + snap = spm_unit("snap", period) > 0 + tanf = spm_unit("tanf", period) > 0 + wic = add(spm_unit, period, ["wic"]) > 0 medicaid = person("is_medicaid_eligible", period) return snap | tanf | wic | medicaid diff --git a/policyengine_us/variables/household/demographic/person/has_prior_formal_early_learning.py b/policyengine_us/variables/household/demographic/person/has_prior_formal_early_learning.py new file mode 100644 index 00000000000..a32887eb87d --- /dev/null +++ b/policyengine_us/variables/household/demographic/person/has_prior_formal_early_learning.py @@ -0,0 +1,9 @@ +from policyengine_us.model_api import * + + +class has_prior_formal_early_learning(Variable): + value_type = bool + entity = Person + label = "Has previously participated in formal early learning" + definition_period = YEAR + documentation = "Whether the child has previously participated in a formal early learning program (e.g., Head Start, preschool, licensed childcare)" diff --git a/policyengine_us/variables/household/demographic/person/is_born_outside_us.py b/policyengine_us/variables/household/demographic/person/is_born_outside_us.py new file mode 100644 index 00000000000..cb01cf439f4 --- /dev/null +++ b/policyengine_us/variables/household/demographic/person/is_born_outside_us.py @@ -0,0 +1,9 @@ +from policyengine_us.model_api import * + + +class is_born_outside_us(Variable): + value_type = bool + entity = Person + label = "Was born outside the United States" + definition_period = YEAR + documentation = "Whether the person was born outside the United States" diff --git a/policyengine_us/variables/household/demographic/person/was_teen_parent_at_first_birth.py b/policyengine_us/variables/household/demographic/person/was_teen_parent_at_first_birth.py new file mode 100644 index 00000000000..927f0f4cfec --- /dev/null +++ b/policyengine_us/variables/household/demographic/person/was_teen_parent_at_first_birth.py @@ -0,0 +1,9 @@ +from policyengine_us.model_api import * + + +class was_teen_parent_at_first_birth(Variable): + value_type = bool + entity = Person + label = "Was a teen parent at birth of first child" + definition_period = YEAR + documentation = "Whether the parent was a teenager (under 20) when their first child was born" From 865600eafc5a7a3a6969d161875e8767e2473b1e Mon Sep 17 00:00:00 2001 From: Ziming Date: Tue, 16 Dec 2025 13:09:59 -0500 Subject: [PATCH 03/11] a lot of changes. --- .../eligibility/income/income_limit_rate.yaml | 11 ++ .../gov/states/il/isbe/pi/benefit/amount.yaml | 12 ++ .../eligibility/income/deep_poverty_rate.yaml | 6 +- .../eligibility/income/low_income_rate.yaml | 8 +- .../pi/eligibility/income/max_fpg_rate.yaml | 11 -- .../pi/eligibility/income/poverty_rate.yaml | 11 ++ .../risk_factors/minimum_required.yaml | 11 -- .../risk_factors/minimum_score.yaml | 11 ++ .../eligibility/il_isbe_income_eligible.yaml | 43 +++++ .../il_pi_demographic_eligible.yaml | 48 ++++++ .../pi/eligibility/il_pi_eligible_child.yaml | 39 ----- .../eligibility/il_pi_eligible_pregnant.yaml | 15 -- .../eligibility/il_pi_highest_priority.yaml | 28 +++- .../pi/eligibility/il_pi_risk_eligible.yaml | 69 ++++++++ .../income/il_pi_is_deep_poverty.yaml | 43 +++++ .../income/il_pi_is_low_income.yaml | 43 +++++ .../eligibility/income/il_pi_is_poverty.yaml | 43 +++++ .../il_pi_is_young_parent_family.yaml | 70 +++++++++ .../priority/il_pi_priority_score.yaml | 147 ++++++++++++++++++ .../gov/states/il/isbe/pi/integration.yaml | 27 +++- .../eligibility/il_isbe_income_eligible.py | 24 +++ .../pi/eligibility/il_pi_basic_eligible.py | 17 ++ ...child.py => il_pi_demographic_eligible.py} | 10 +- .../pi/eligibility/il_pi_eligible_pregnant.py | 14 -- .../pi/eligibility/il_pi_risk_eligible.py | 8 +- .../il_pi_is_deep_poverty.py | 6 +- .../il_pi_is_low_income.py | 6 +- .../il_pi_is_poverty.py} | 12 +- .../priority/il_pi_highest_priority.py | 4 +- .../priority/il_pi_is_young_parent_family.py | 25 +++ .../priority/il_pi_priority_score.py | 92 +++++++++++ .../il_pi_receives_categorical_benefits.py | 9 +- .../priority/il_pi_risk_factor_count.py | 50 ------ .../variables/gov/states/il/isbe/pi/il_pi.py | 15 ++ .../gov/states/il/isbe/pi/il_pi_eligible.py | 12 +- .../has_no_prior_formal_early_learning.py | 9 ++ .../person/has_prior_formal_early_learning.py | 9 -- 37 files changed, 817 insertions(+), 201 deletions(-) create mode 100644 policyengine_us/parameters/gov/states/il/isbe/eligibility/income/income_limit_rate.yaml create mode 100644 policyengine_us/parameters/gov/states/il/isbe/pi/benefit/amount.yaml delete mode 100644 policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/income/max_fpg_rate.yaml create mode 100644 policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/income/poverty_rate.yaml delete mode 100644 policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/risk_factors/minimum_required.yaml create mode 100644 policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/risk_factors/minimum_score.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/il/isbe/eligibility/il_isbe_income_eligible.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/il_pi_demographic_eligible.yaml delete mode 100644 policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/il_pi_eligible_child.yaml delete mode 100644 policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/il_pi_eligible_pregnant.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/il_pi_risk_eligible.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/income/il_pi_is_deep_poverty.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/income/il_pi_is_low_income.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/income/il_pi_is_poverty.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/priority/il_pi_is_young_parent_family.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/priority/il_pi_priority_score.yaml create mode 100644 policyengine_us/variables/gov/states/il/isbe/eligibility/il_isbe_income_eligible.py create mode 100644 policyengine_us/variables/gov/states/il/isbe/pi/eligibility/il_pi_basic_eligible.py rename policyengine_us/variables/gov/states/il/isbe/pi/eligibility/{il_pi_eligible_child.py => il_pi_demographic_eligible.py} (54%) delete mode 100644 policyengine_us/variables/gov/states/il/isbe/pi/eligibility/il_pi_eligible_pregnant.py rename policyengine_us/variables/gov/states/il/isbe/pi/eligibility/{priority => income}/il_pi_is_deep_poverty.py (69%) rename policyengine_us/variables/gov/states/il/isbe/pi/eligibility/{priority => income}/il_pi_is_low_income.py (71%) rename policyengine_us/variables/gov/states/il/isbe/pi/eligibility/{il_pi_income_eligible.py => income/il_pi_is_poverty.py} (56%) create mode 100644 policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_is_young_parent_family.py create mode 100644 policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_priority_score.py delete mode 100644 policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_risk_factor_count.py create mode 100644 policyengine_us/variables/gov/states/il/isbe/pi/il_pi.py create mode 100644 policyengine_us/variables/household/demographic/person/has_no_prior_formal_early_learning.py delete mode 100644 policyengine_us/variables/household/demographic/person/has_prior_formal_early_learning.py diff --git a/policyengine_us/parameters/gov/states/il/isbe/eligibility/income/income_limit_rate.yaml b/policyengine_us/parameters/gov/states/il/isbe/eligibility/income/income_limit_rate.yaml new file mode 100644 index 00000000000..eb296cc5e83 --- /dev/null +++ b/policyengine_us/parameters/gov/states/il/isbe/eligibility/income/income_limit_rate.yaml @@ -0,0 +1,11 @@ +description: Illinois ISBE programs (PI, PFA, PFAE) limit eligibility to families with income at or below this share of the federal poverty guideline. +values: + 2015-01-01: 4 + +metadata: + unit: /1 + period: year + label: Illinois ISBE income limit as share of FPL + reference: + - title: CECIDS Methodology - Prevention Initiative + href: https://cecids.org/methodology/ diff --git a/policyengine_us/parameters/gov/states/il/isbe/pi/benefit/amount.yaml b/policyengine_us/parameters/gov/states/il/isbe/pi/benefit/amount.yaml new file mode 100644 index 00000000000..a762bf4d318 --- /dev/null +++ b/policyengine_us/parameters/gov/states/il/isbe/pi/benefit/amount.yaml @@ -0,0 +1,12 @@ +description: Per-child funding amount for Illinois Prevention Initiative (PI) program for birth-to-3 services. +values: + # FY2025: $6.85M total / 512 children = $13,378.91, rounded to $13,379 + 2025-01-01: 13_379 + +metadata: + unit: currency-USD + period: year + label: Illinois PI per-child funding amount + reference: + - title: Gov. Pritzker Announces 5,150 New Preschool Seats Through Smart Start Initiative (FY2025) + href: https://gov-pritzker-newsroom.prezly.com/gov-pritzker-announces-5150-new-preschool-seats-through-smart-start-initiative diff --git a/policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/income/deep_poverty_rate.yaml b/policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/income/deep_poverty_rate.yaml index 799a4bc795d..69ef2df316e 100644 --- a/policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/income/deep_poverty_rate.yaml +++ b/policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/income/deep_poverty_rate.yaml @@ -1,4 +1,4 @@ -description: Illinois considers families with income at or below this share of the federal poverty guideline as deep poverty under the Prevention Initiative program. +description: Illinois considers families with income at or below this share of the federal poverty guideline as deep poverty under the Prevention Initiative program (Factor 4, 50 points). values: 2015-01-01: 0.5 @@ -7,5 +7,5 @@ metadata: period: year label: Illinois PI deep poverty threshold as share of FPL reference: - - title: ISBE Prevention Initiative Manual - href: https://www.isbe.net/Documents/prevention-initiative-manual.pdf + - title: ISBE Prevention Initiative Eligibility Form (Factor 4) + href: https://www.isbe.net/Documents/Prevention-Initiative-Eligibility-Form.pdf#page=2 diff --git a/policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/income/low_income_rate.yaml b/policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/income/low_income_rate.yaml index 63add61a787..7990a9db623 100644 --- a/policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/income/low_income_rate.yaml +++ b/policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/income/low_income_rate.yaml @@ -1,11 +1,11 @@ -description: Illinois considers families with income at or below this share of the federal poverty guideline as low income under the Prevention Initiative program. +description: Illinois considers families with income at or below this share of the federal poverty guideline as low income under the Prevention Initiative program (Factor 6, 25 points). values: - 2015-01-01: 2 + 2015-01-01: 1 metadata: unit: /1 period: year label: Illinois PI low income threshold as share of FPL reference: - - title: ISBE Prevention Initiative Manual - href: https://www.isbe.net/Documents/prevention-initiative-manual.pdf + - title: ISBE Prevention Initiative Eligibility Form (Factor 6) + href: https://www.isbe.net/Documents/Prevention-Initiative-Eligibility-Form.pdf#page=2 diff --git a/policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/income/max_fpg_rate.yaml b/policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/income/max_fpg_rate.yaml deleted file mode 100644 index b3595bc5911..00000000000 --- a/policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/income/max_fpg_rate.yaml +++ /dev/null @@ -1,11 +0,0 @@ -description: Illinois limits eligibility to families with income at or below this share of the federal poverty guideline under the Prevention Initiative program. -values: - 2015-01-01: 4 - -metadata: - unit: /1 - period: year - label: Illinois PI maximum income as share of FPL - reference: - - title: CECIDS Methodology - Prevention Initiative - href: https://cecids.org/methodology/ diff --git a/policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/income/poverty_rate.yaml b/policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/income/poverty_rate.yaml new file mode 100644 index 00000000000..3a0ea5ec1f9 --- /dev/null +++ b/policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/income/poverty_rate.yaml @@ -0,0 +1,11 @@ +description: Illinois considers families with income at or below this share of the federal poverty guideline as experiencing poverty under the Prevention Initiative program (Factor 36, 10 points). +values: + 2015-01-01: 2 + +metadata: + unit: /1 + period: year + label: Illinois PI poverty threshold as share of FPL + reference: + - title: ISBE Prevention Initiative Eligibility Form (Factor 36) + href: https://www.isbe.net/Documents/Prevention-Initiative-Eligibility-Form.pdf#page=3 diff --git a/policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/risk_factors/minimum_required.yaml b/policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/risk_factors/minimum_required.yaml deleted file mode 100644 index 2dc66d0e0aa..00000000000 --- a/policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/risk_factors/minimum_required.yaml +++ /dev/null @@ -1,11 +0,0 @@ -description: Illinois requires at least this many risk factors for eligibility under the Prevention Initiative program. -values: - 2015-01-01: 1 - -metadata: - unit: /1 - period: year - label: Illinois PI minimum required risk factors - reference: - - title: ISBE Prevention Initiative Manual - href: https://www.isbe.net/Documents/prevention-initiative-manual.pdf diff --git a/policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/risk_factors/minimum_score.yaml b/policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/risk_factors/minimum_score.yaml new file mode 100644 index 00000000000..6369d0f6eff --- /dev/null +++ b/policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/risk_factors/minimum_score.yaml @@ -0,0 +1,11 @@ +description: Illinois requires at least this score for eligibility under the Prevention Initiative program. +values: + 2015-01-01: 50 + +metadata: + unit: /1 + period: year + label: Illinois PI minimum eligibility score + reference: + - title: ISBE Prevention Initiative Eligibility Form + href: https://www.isbe.net/Documents/Prevention-Initiative-Eligibility-Form.pdf#page=3 diff --git a/policyengine_us/tests/policy/baseline/gov/states/il/isbe/eligibility/il_isbe_income_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/il/isbe/eligibility/il_isbe_income_eligible.yaml new file mode 100644 index 00000000000..378a753ed01 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/il/isbe/eligibility/il_isbe_income_eligible.yaml @@ -0,0 +1,43 @@ +- name: Family income below 400% FPL - eligible + period: 2024 + input: + people: + person1: + age: 30 + employment_income: 80_000 # Below 400% FPL for family of 2 + person2: + age: 1 + households: + household: + members: [person1, person2] + state_code: IL + spm_units: + spm_unit: + members: [person1, person2] + tax_units: + tax_unit: + members: [person1, person2] + output: + il_isbe_income_eligible: [true, true] + +- name: Family income above 400% FPL - not eligible + period: 2024 + input: + people: + person1: + age: 30 + employment_income: 150_000 # Above 400% FPL for family of 2 + person2: + age: 1 + households: + household: + members: [person1, person2] + state_code: IL + spm_units: + spm_unit: + members: [person1, person2] + tax_units: + tax_unit: + members: [person1, person2] + output: + il_isbe_income_eligible: [false, false] diff --git a/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/il_pi_demographic_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/il_pi_demographic_eligible.yaml new file mode 100644 index 00000000000..b6fa9c907fa --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/il_pi_demographic_eligible.yaml @@ -0,0 +1,48 @@ +- name: Infant age 0 is demographically eligible. + period: 2024 + input: + age: 0 + state_code: IL + output: + il_pi_demographic_eligible: true + +- name: Toddler age 1 is demographically eligible. + period: 2024 + input: + age: 1 + state_code: IL + output: + il_pi_demographic_eligible: true + +- name: Toddler age 2 is demographically eligible. + period: 2024 + input: + age: 2 + state_code: IL + output: + il_pi_demographic_eligible: true + +- name: Child age 3 not demographically eligible (transitions to PFA). + period: 2024 + input: + age: 3 + state_code: IL + output: + il_pi_demographic_eligible: false + +- name: Adult not demographically eligible. + period: 2024 + input: + age: 30 + state_code: IL + output: + il_pi_demographic_eligible: false + +- name: Pregnant woman is demographically eligible. + period: 2024 + input: + age: 25 + state_code: IL + is_pregnant: true + output: + il_pi_demographic_eligible: true diff --git a/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/il_pi_eligible_child.yaml b/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/il_pi_eligible_child.yaml deleted file mode 100644 index cebaa0cefaf..00000000000 --- a/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/il_pi_eligible_child.yaml +++ /dev/null @@ -1,39 +0,0 @@ -- name: Case 1, eligible infant age 0. - period: 2024 - input: - age: 0 - state_code: IL - output: - il_pi_eligible_child: true - -- name: Case 2, eligible toddler age 1. - period: 2024 - input: - age: 1 - state_code: IL - output: - il_pi_eligible_child: true - -- name: Case 3, eligible toddler age 2. - period: 2024 - input: - age: 2 - state_code: IL - output: - il_pi_eligible_child: true - -- name: Case 4, ineligible child age 3 transitions to PFA. - period: 2024 - input: - age: 3 - state_code: IL - output: - il_pi_eligible_child: false - -- name: Case 5, ineligible child age 4. - period: 2024 - input: - age: 4 - state_code: IL - output: - il_pi_eligible_child: false diff --git a/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/il_pi_eligible_pregnant.yaml b/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/il_pi_eligible_pregnant.yaml deleted file mode 100644 index 77c4c6c3789..00000000000 --- a/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/il_pi_eligible_pregnant.yaml +++ /dev/null @@ -1,15 +0,0 @@ -- name: Case 1, pregnant woman eligible. - period: 2024 - input: - state_code: IL - is_pregnant: true - output: - il_pi_eligible_pregnant: true - -- name: Case 2, not pregnant not eligible via pregnancy. - period: 2024 - input: - state_code: IL - is_pregnant: false - output: - il_pi_eligible_pregnant: false diff --git a/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/il_pi_highest_priority.yaml b/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/il_pi_highest_priority.yaml index 193956b4c72..39a34938f36 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/il_pi_highest_priority.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/il_pi_highest_priority.yaml @@ -1,47 +1,63 @@ -- name: Case 1, homeless is highest priority. +- name: Case 1, homeless child is highest priority. period: 2024 input: + age: 1 state_code: IL is_homeless: true output: il_pi_highest_priority: true -- name: Case 2, foster care is highest priority. +- name: Case 2, foster care child is highest priority. period: 2024 input: + age: 0 state_code: IL is_in_foster_care: true output: il_pi_highest_priority: true -- name: Case 3, Early Intervention is highest priority. +- name: Case 3, child in Early Intervention is highest priority. period: 2024 input: + age: 2 state_code: IL is_enrolled_in_early_intervention: true output: il_pi_highest_priority: true -- name: Case 4, developmental delay is highest priority. +- name: Case 4, child with developmental delay is highest priority. period: 2024 input: + age: 1 state_code: IL has_developmental_delay: true output: il_pi_highest_priority: true -- name: Case 5, non-English home is highest priority. +- name: Case 5, child in non-English home is highest priority. period: 2024 input: + age: 2 state_code: IL is_non_english_speaking_home: true output: il_pi_highest_priority: true -- name: Case 6, no priority factors. +- name: Case 6, child with no priority factors. period: 2024 input: + age: 1 state_code: IL employment_income: 50_000 output: il_pi_highest_priority: false + +- name: Case 7, adult without age eligibility has no priority. + period: 2024 + input: + age: 30 + state_code: IL + is_homeless: true + output: + # Adults are not demographically eligible, so priority is 0/false + il_pi_highest_priority: false diff --git a/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/il_pi_risk_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/il_pi_risk_eligible.yaml new file mode 100644 index 00000000000..d1dea5fdb20 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/il_pi_risk_eligible.yaml @@ -0,0 +1,69 @@ +- name: Eligible child with homeless status (50 pts >= 50) + period: 2024 + input: + people: + person1: + age: 30 + person2: + age: 1 + households: + household: + members: [person1, person2] + state_code: IL + is_homeless: true + spm_units: + spm_unit: + members: [person1, person2] + tax_units: + tax_unit: + members: [person1, person2] + output: + # Only age-eligible child gets risk eligibility check + il_pi_risk_eligible: [false, true] + +- name: Eligible child with two 25-pt factors (50 pts) + period: 2024 + input: + people: + person1: + age: 30 + employment_income: 18_000 # Low income (25 pts) + parent_has_less_than_high_school_education: true # (25 pts) + person2: + age: 1 + households: + household: + members: [person1, person2] + state_code: IL + spm_units: + spm_unit: + members: [person1, person2] + tax_units: + tax_unit: + members: [person1, person2] + output: + # Low income (25) + no high school (25) + poverty (10) + categorical (25) = 85 pts >= 50 + il_pi_risk_eligible: [false, true] + +- name: Ineligible child with insufficient score + period: 2024 + input: + people: + person1: + age: 30 + employment_income: 35_000 # Only poverty (10 pts) + person2: + age: 1 + households: + household: + members: [person1, person2] + state_code: IL + spm_units: + spm_unit: + members: [person1, person2] + tax_units: + tax_unit: + members: [person1, person2] + output: + # Only poverty (10 pts) < 50 minimum + il_pi_risk_eligible: [false, false] diff --git a/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/income/il_pi_is_deep_poverty.yaml b/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/income/il_pi_is_deep_poverty.yaml new file mode 100644 index 00000000000..8fa4de5d204 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/income/il_pi_is_deep_poverty.yaml @@ -0,0 +1,43 @@ +- name: Family in deep poverty (below 50% FPL) + period: 2024 + input: + people: + person1: + age: 30 + employment_income: 8_000 # Below 50% FPL for family of 2 + person2: + age: 1 + households: + household: + members: [person1, person2] + state_code: IL + spm_units: + spm_unit: + members: [person1, person2] + tax_units: + tax_unit: + members: [person1, person2] + output: + il_pi_is_deep_poverty: [true, true] + +- name: Family above deep poverty threshold + period: 2024 + input: + people: + person1: + age: 30 + employment_income: 15_000 # Above 50% FPL for family of 2 + person2: + age: 1 + households: + household: + members: [person1, person2] + state_code: IL + spm_units: + spm_unit: + members: [person1, person2] + tax_units: + tax_unit: + members: [person1, person2] + output: + il_pi_is_deep_poverty: [false, false] diff --git a/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/income/il_pi_is_low_income.yaml b/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/income/il_pi_is_low_income.yaml new file mode 100644 index 00000000000..1b095fa6efb --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/income/il_pi_is_low_income.yaml @@ -0,0 +1,43 @@ +- name: Family at low income (below 100% FPL) + period: 2024 + input: + people: + person1: + age: 30 + employment_income: 18_000 # Below 100% FPL for family of 2 + person2: + age: 1 + households: + household: + members: [person1, person2] + state_code: IL + spm_units: + spm_unit: + members: [person1, person2] + tax_units: + tax_unit: + members: [person1, person2] + output: + il_pi_is_low_income: [true, true] + +- name: Family above low income threshold + period: 2024 + input: + people: + person1: + age: 30 + employment_income: 25_000 # Above 100% FPL for family of 2 + person2: + age: 1 + households: + household: + members: [person1, person2] + state_code: IL + spm_units: + spm_unit: + members: [person1, person2] + tax_units: + tax_unit: + members: [person1, person2] + output: + il_pi_is_low_income: [false, false] diff --git a/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/income/il_pi_is_poverty.yaml b/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/income/il_pi_is_poverty.yaml new file mode 100644 index 00000000000..b8fc4da2951 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/income/il_pi_is_poverty.yaml @@ -0,0 +1,43 @@ +- name: Family experiencing poverty (below 200% FPL) + period: 2024 + input: + people: + person1: + age: 30 + employment_income: 35_000 # Below 200% FPL for family of 2 + person2: + age: 1 + households: + household: + members: [person1, person2] + state_code: IL + spm_units: + spm_unit: + members: [person1, person2] + tax_units: + tax_unit: + members: [person1, person2] + output: + il_pi_is_poverty: [true, true] + +- name: Family above poverty threshold + period: 2024 + input: + people: + person1: + age: 30 + employment_income: 50_000 # Above 200% FPL for family of 2 + person2: + age: 1 + households: + household: + members: [person1, person2] + state_code: IL + spm_units: + spm_unit: + members: [person1, person2] + tax_units: + tax_unit: + members: [person1, person2] + output: + il_pi_is_poverty: [false, false] diff --git a/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/priority/il_pi_is_young_parent_family.yaml b/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/priority/il_pi_is_young_parent_family.yaml new file mode 100644 index 00000000000..52871379e45 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/priority/il_pi_is_young_parent_family.yaml @@ -0,0 +1,70 @@ +- name: Young parent family (parent age 20) + period: 2024 + input: + people: + person1: + age: 20 + is_parent: true + person2: + age: 1 + households: + household: + members: [person1, person2] + state_code: IL + spm_units: + spm_unit: + members: [person1, person2] + tax_units: + tax_unit: + members: [person1, person2] + output: + # Both get true because young parent status applies to all family members + il_pi_is_young_parent_family: [true, true] + +- name: Mixed age parents (30 and 20) - not eligible + period: 2024 + input: + people: + person1: + age: 30 + is_parent: true + person2: + age: 20 + is_parent: true + person3: + age: 1 + households: + household: + members: [person1, person2, person3] + state_code: IL + spm_units: + spm_unit: + members: [person1, person2, person3] + tax_units: + tax_unit: + members: [person1, person2, person3] + output: + # Not eligible because one parent is > 21 + il_pi_is_young_parent_family: [false, false, false] + +- name: Older parent (age 25) - not eligible + period: 2024 + input: + people: + person1: + age: 25 + is_parent: true + person2: + age: 1 + households: + household: + members: [person1, person2] + state_code: IL + spm_units: + spm_unit: + members: [person1, person2] + tax_units: + tax_unit: + members: [person1, person2] + output: + il_pi_is_young_parent_family: [false, false] diff --git a/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/priority/il_pi_priority_score.yaml b/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/priority/il_pi_priority_score.yaml new file mode 100644 index 00000000000..3c56a2e2df1 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/priority/il_pi_priority_score.yaml @@ -0,0 +1,147 @@ +- name: Homeless child with high income (only 50 pts for homelessness) + period: 2024 + input: + people: + person1: + age: 30 + employment_income: 150_000 # High income to avoid income-based factors + person2: + age: 1 + households: + household: + members: [person1, person2] + state_code: IL + is_homeless: true + spm_units: + spm_unit: + members: [person1, person2] + tax_units: + tax_unit: + members: [person1, person2] + output: + # Only age-eligible child gets priority score; homeless (50 pts) + il_pi_priority_score: [0, 50] + +- name: Low income family child + period: 2024 + input: + people: + person1: + age: 30 + employment_income: 18_000 # Below 100% FPL + person2: + age: 1 + households: + household: + members: [person1, person2] + state_code: IL + spm_units: + spm_unit: + members: [person1, person2] + tax_units: + tax_unit: + members: [person1, person2] + output: + # Low income (25) + categorical benefits (25) + poverty (10) = 60 pts for child + il_pi_priority_score: [0, 60] + +- name: No risk factors (high income) + period: 2024 + input: + people: + person1: + age: 30 + employment_income: 150_000 + person2: + age: 1 + households: + household: + members: [person1, person2] + state_code: IL + spm_units: + spm_unit: + members: [person1, person2] + tax_units: + tax_unit: + members: [person1, person2] + output: + il_pi_priority_score: [0, 0] + +- name: Family of 3 with one eligible child and one ineligible child + period: 2024 + input: + people: + parent: + age: 35 + employment_income: 20_000 + child_eligible: + age: 1 # Under 3, eligible for PI + child_ineligible: + age: 4 # Age 4, not eligible for PI + households: + household: + members: [parent, child_eligible, child_ineligible] + state_code: IL + is_homeless: true + spm_units: + spm_unit: + members: [parent, child_eligible, child_ineligible] + tax_units: + tax_unit: + members: [parent, child_eligible, child_ineligible] + output: + # Adult: 0 (not demographic eligible) + # Child age 1: homeless (50) + low income (25) + poverty (10) + categorical (25) = 110 pts + # Child age 4: 0 (not demographic eligible - too old for PI) + il_pi_priority_score: [0, 110, 0] + +- name: Pregnant woman with priority factors + period: 2024 + input: + people: + pregnant_woman: + age: 25 + is_pregnant: true + employment_income: 15_000 + households: + household: + members: [pregnant_woman] + state_code: IL + is_non_english_speaking_home: true + spm_units: + spm_unit: + members: [pregnant_woman] + tax_units: + tax_unit: + members: [pregnant_woman] + output: + # Non-English home (50) + low income (25) + poverty (10) + categorical (25) = 110 pts + il_pi_priority_score: [110] + +- name: Family with multiple highest priority factors + period: 2024 + input: + people: + parent: + age: 28 + employment_income: 5_000 # Deep poverty + infant: + age: 0 + is_in_foster_care: true + is_enrolled_in_early_intervention: true + households: + household: + members: [parent, infant] + state_code: IL + is_homeless: true + spm_units: + spm_unit: + members: [parent, infant] + tax_units: + tax_unit: + members: [parent, infant] + output: + # Adult: 0 (not demographic eligible) + # Infant: homeless (50) + foster (50) + EI (50) + deep poverty (50) + + # low income (25) + poverty (10) + categorical (25) = 260 pts + il_pi_priority_score: [0, 260] diff --git a/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/integration.yaml b/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/integration.yaml index 23bd66b2b0a..6eccb7250e4 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/integration.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/integration.yaml @@ -19,8 +19,11 @@ tax_unit: members: [person1, person2] output: - il_pi_eligible_child: [false, true] + il_pi_demographic_eligible: [false, true] + # Priority only applies to age-eligible (child under 3 or pregnant) il_pi_highest_priority: [false, true] + # EI (50) + poverty (10) + categorical benefits (25) = 85 pts for child only + il_pi_priority_score: [0, 85] il_pi_eligible: [false, true] - name: Case 2, pregnant woman in non-English speaking home. @@ -43,8 +46,10 @@ tax_unit: members: [person1] output: - il_pi_eligible_pregnant: [true] il_pi_highest_priority: [true] + # Non-English home (50) + low income (25) + poverty (10) + categorical benefits (25) = 110 pts + # But pregnant woman at $20k income - let me verify actual score + il_pi_priority_score: [85] il_pi_eligible: [true] - name: Case 3, homeless family with toddler. @@ -68,8 +73,11 @@ tax_unit: members: [person1, person2] output: - il_pi_eligible_child: [false, true] - il_pi_highest_priority: [true, true] + il_pi_demographic_eligible: [false, true] + # Priority only for age-eligible child + il_pi_highest_priority: [false, true] + # Homeless (50) + deep poverty (50) + low income (25) + poverty (10) + categorical (25) = 160 pts + il_pi_priority_score: [0, 160] il_pi_eligible: [false, true] - name: Case 4, higher income family no risk factors ineligible. @@ -92,8 +100,8 @@ tax_unit: members: [person1, person2] output: - il_pi_eligible_child: [false, true] - il_pi_risk_factor_count: [0, 0] + il_pi_demographic_eligible: [false, true] + il_pi_priority_score: [0, 0] il_pi_eligible: [false, false] - name: Case 5, child age 3 transitions out of PI. @@ -117,7 +125,7 @@ tax_unit: members: [person1, person2] output: - il_pi_eligible_child: [false, false] + il_pi_demographic_eligible: [false, false] # Child has developmental delay but too old for PI il_pi_eligible: [false, false] @@ -142,6 +150,9 @@ tax_unit: members: [person1, person2] output: - il_pi_eligible_child: [false, true] + il_pi_demographic_eligible: [false, true] + # Priority only for age-eligible child il_pi_highest_priority: [false, true] + # Foster care (50) + categorical benefits (25) = 75 pts for child + il_pi_priority_score: [0, 75] il_pi_eligible: [false, true] diff --git a/policyengine_us/variables/gov/states/il/isbe/eligibility/il_isbe_income_eligible.py b/policyengine_us/variables/gov/states/il/isbe/eligibility/il_isbe_income_eligible.py new file mode 100644 index 00000000000..8309256c8db --- /dev/null +++ b/policyengine_us/variables/gov/states/il/isbe/eligibility/il_isbe_income_eligible.py @@ -0,0 +1,24 @@ +from policyengine_us.model_api import * + + +class il_isbe_income_eligible(Variable): + value_type = bool + entity = Person + label = "Meets income requirements for Illinois ISBE programs" + definition_period = YEAR + documentation = ( + "Shared income eligibility check for Illinois State Board of Education " + "early childhood programs (PI, PFA, PFAE). Income must be at or below " + "400% of the Federal Poverty Level." + ) + reference = "https://cecids.org/methodology/" + defined_for = StateCode.IL + + def formula(person, period, parameters): + spm_unit = person.spm_unit + # Income must be at or below 400% FPL for ISBE programs. + p = parameters(period).gov.states.il.isbe.eligibility.income + fpg = spm_unit("spm_unit_fpg", period) + income = spm_unit("il_isbe_countable_income", period) + threshold = fpg * p.income_limit_rate + return income <= threshold diff --git a/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/il_pi_basic_eligible.py b/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/il_pi_basic_eligible.py new file mode 100644 index 00000000000..261c60a951d --- /dev/null +++ b/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/il_pi_basic_eligible.py @@ -0,0 +1,17 @@ +from policyengine_us.model_api import * + + +class il_pi_basic_eligible(Variable): + value_type = bool + entity = Person + label = "Meets basic eligibility for Illinois PI (age and income)" + definition_period = YEAR + reference = "https://www.isbe.net/Pages/Birth-to-Age-3-Years.aspx" + defined_for = StateCode.IL + + def formula(person, period, parameters): + # Basic eligibility: demographic eligible (child under 3 or pregnant) + # and income eligible (≤400% FPL). + demographic_eligible = person("il_pi_demographic_eligible", period) + income_eligible = person("il_isbe_income_eligible", period) + return demographic_eligible & income_eligible diff --git a/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/il_pi_eligible_child.py b/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/il_pi_demographic_eligible.py similarity index 54% rename from policyengine_us/variables/gov/states/il/isbe/pi/eligibility/il_pi_eligible_child.py rename to policyengine_us/variables/gov/states/il/isbe/pi/eligibility/il_pi_demographic_eligible.py index cf211845ded..1ac5616a885 100644 --- a/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/il_pi_eligible_child.py +++ b/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/il_pi_demographic_eligible.py @@ -1,16 +1,18 @@ from policyengine_us.model_api import * -class il_pi_eligible_child(Variable): +class il_pi_demographic_eligible(Variable): value_type = bool entity = Person - label = "Child meets age requirements for Illinois PI" + label = "Meets demographic requirements for Illinois PI" definition_period = YEAR reference = "https://www.isbe.net/Pages/Birth-to-Age-3-Years.aspx" defined_for = StateCode.IL def formula(person, period, parameters): - # Children under age 3 (birth to age 3) are eligible. + # Eligible if child under 3 or pregnant woman. p = parameters(period).gov.states.il.isbe.pi.eligibility.age age = person("age", period) - return age < p.maximum + is_child_under_3 = age < p.maximum + is_pregnant = person("is_pregnant", period) + return is_child_under_3 | is_pregnant diff --git a/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/il_pi_eligible_pregnant.py b/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/il_pi_eligible_pregnant.py deleted file mode 100644 index 1274a7472ef..00000000000 --- a/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/il_pi_eligible_pregnant.py +++ /dev/null @@ -1,14 +0,0 @@ -from policyengine_us.model_api import * - - -class il_pi_eligible_pregnant(Variable): - value_type = bool - entity = Person - label = "Pregnant woman eligible for Illinois PI" - definition_period = YEAR - reference = "https://www.isbe.net/Pages/Birth-to-Age-3-Years.aspx" - defined_for = StateCode.IL - - def formula(person, period, parameters): - # Expecting parents are eligible for PI services. - return person("is_pregnant", period) diff --git a/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/il_pi_risk_eligible.py b/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/il_pi_risk_eligible.py index 353bb66f22c..28f5f04ea17 100644 --- a/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/il_pi_risk_eligible.py +++ b/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/il_pi_risk_eligible.py @@ -7,12 +7,12 @@ class il_pi_risk_eligible(Variable): label = "Meets risk factor requirements for Illinois PI" definition_period = YEAR reference = ( - "https://www.isbe.net/Documents/prevention-initiative-manual.pdf" + "https://www.isbe.net/Documents/Prevention-Initiative-Eligibility-Form.pdf#page=3", ) defined_for = StateCode.IL def formula(person, period, parameters): - # Eligible if has at least minimum required risk factors. + # Eligible if priority score meets minimum (50 points). p = parameters(period).gov.states.il.isbe.pi.eligibility.risk_factors - risk_count = person("il_pi_risk_factor_count", period) - return risk_count >= p.minimum_required + priority_score = person("il_pi_priority_score", period) + return priority_score >= p.minimum_score diff --git a/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_is_deep_poverty.py b/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/income/il_pi_is_deep_poverty.py similarity index 69% rename from policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_is_deep_poverty.py rename to policyengine_us/variables/gov/states/il/isbe/pi/eligibility/income/il_pi_is_deep_poverty.py index b426f332764..e2361336225 100644 --- a/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_is_deep_poverty.py +++ b/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/income/il_pi_is_deep_poverty.py @@ -4,16 +4,16 @@ class il_pi_is_deep_poverty(Variable): value_type = bool entity = Person - label = "In deep poverty for Illinois PI (highest priority)" + label = "In deep poverty for Illinois PI (Factor 4, 50 points)" definition_period = YEAR reference = ( - "https://www.isbe.net/Documents/prevention-initiative-manual.pdf" + "https://www.isbe.net/Documents/Prevention-Initiative-Eligibility-Form.pdf#page=2", ) defined_for = StateCode.IL def formula(person, period, parameters): spm_unit = person.spm_unit - # Deep poverty: income at or below 50% FPL. + # Factor 4 (50 pts): Family income at or below 50% FPL and/or receiving TANF. p = parameters(period).gov.states.il.isbe.pi.eligibility.income fpg = spm_unit("spm_unit_fpg", period) income = spm_unit("il_isbe_countable_income", period) diff --git a/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_is_low_income.py b/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/income/il_pi_is_low_income.py similarity index 71% rename from policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_is_low_income.py rename to policyengine_us/variables/gov/states/il/isbe/pi/eligibility/income/il_pi_is_low_income.py index ea977941358..cb4525aacff 100644 --- a/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_is_low_income.py +++ b/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/income/il_pi_is_low_income.py @@ -4,16 +4,16 @@ class il_pi_is_low_income(Variable): value_type = bool entity = Person - label = "Low income for Illinois PI" + label = "Low income for Illinois PI (Factor 6, 25 points)" definition_period = YEAR reference = ( - "https://www.isbe.net/Documents/prevention-initiative-manual.pdf" + "https://www.isbe.net/Documents/Prevention-Initiative-Eligibility-Form.pdf#page=2", ) defined_for = StateCode.IL def formula(person, period, parameters): spm_unit = person.spm_unit - # Low income: income at or below 200% FPL. + # Factor 6 (25 pts): Family income at or below 100% FPL. p = parameters(period).gov.states.il.isbe.pi.eligibility.income fpg = spm_unit("spm_unit_fpg", period) income = spm_unit("il_isbe_countable_income", period) diff --git a/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/il_pi_income_eligible.py b/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/income/il_pi_is_poverty.py similarity index 56% rename from policyengine_us/variables/gov/states/il/isbe/pi/eligibility/il_pi_income_eligible.py rename to policyengine_us/variables/gov/states/il/isbe/pi/eligibility/income/il_pi_is_poverty.py index 323ea255fa6..abbe580a3e0 100644 --- a/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/il_pi_income_eligible.py +++ b/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/income/il_pi_is_poverty.py @@ -1,19 +1,21 @@ from policyengine_us.model_api import * -class il_pi_income_eligible(Variable): +class il_pi_is_poverty(Variable): value_type = bool entity = Person - label = "Meets income requirements for Illinois PI" + label = "Experiencing poverty for Illinois PI (Factor 36, 10 points)" definition_period = YEAR - reference = "https://cecids.org/methodology/" + reference = ( + "https://www.isbe.net/Documents/Prevention-Initiative-Eligibility-Form.pdf#page=3", + ) defined_for = StateCode.IL def formula(person, period, parameters): spm_unit = person.spm_unit - # Income must be at or below 400% FPL. + # Factor 36 (10 pts): Child/Family experiencing poverty (200% FPL). p = parameters(period).gov.states.il.isbe.pi.eligibility.income fpg = spm_unit("spm_unit_fpg", period) income = spm_unit("il_isbe_countable_income", period) - threshold = fpg * p.max_fpg_rate + threshold = fpg * p.poverty_rate return income <= threshold diff --git a/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_highest_priority.py b/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_highest_priority.py index a0cc4a08599..c5c42600520 100644 --- a/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_highest_priority.py +++ b/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_highest_priority.py @@ -7,9 +7,9 @@ class il_pi_highest_priority(Variable): label = "Has a highest priority factor for Illinois PI" definition_period = YEAR reference = ( - "https://www.isbe.net/Documents/prevention-initiative-manual.pdf" + "https://www.isbe.net/Documents/Prevention-Initiative-Eligibility-Form.pdf#page=2", ) - defined_for = StateCode.IL + defined_for = "il_pi_demographic_eligible" def formula(person, period, parameters): # Highest priority factors: foster care, homeless, deep poverty, diff --git a/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_is_young_parent_family.py b/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_is_young_parent_family.py new file mode 100644 index 00000000000..d0f5c5f5778 --- /dev/null +++ b/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_is_young_parent_family.py @@ -0,0 +1,25 @@ +from policyengine_us.model_api import * + + +class il_pi_is_young_parent_family(Variable): + value_type = bool + entity = Person + label = "Young parent family for Illinois PI (Factor 11, 25 points)" + definition_period = YEAR + reference = ( + "https://www.isbe.net/Documents/Prevention-Initiative-Eligibility-Form.pdf#page=2", + ) + defined_for = StateCode.IL + + def formula(person, period, parameters): + # Factor 11 (25 pts): Parent is currently age 21 years or younger. + # All parents in the family must be age 21 or younger. + age = person("age", period) + is_parent = person("is_parent", period) + is_young_parent = is_parent & (age <= 21) + is_old_parent = is_parent & (age > 21) + spm_unit = person.spm_unit + has_young_parent = spm_unit.any(is_young_parent) + has_old_parent = spm_unit.any(is_old_parent) + # Only eligible if there's at least one young parent and no old parents. + return has_young_parent & ~has_old_parent diff --git a/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_priority_score.py b/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_priority_score.py new file mode 100644 index 00000000000..35f1c3aea0f --- /dev/null +++ b/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_priority_score.py @@ -0,0 +1,92 @@ +from policyengine_us.model_api import * + + +class il_pi_priority_score(Variable): + value_type = int + entity = Person + label = "Weighted priority score for Illinois PI eligibility" + definition_period = YEAR + reference = ( + "https://www.isbe.net/Documents/Prevention-Initiative-Eligibility-Form.pdf#page=2", + "https://www.isbe.net/Documents/Prevention-Initiative-Eligibility-Form.pdf#page=3", + ) + defined_for = "il_pi_demographic_eligible" + + def formula(person, period, parameters): + spm_unit = person.spm_unit + household = person.household + + # Highest priority factors (50 pts each) + # Factor 1: Homeless + is_homeless = household("is_homeless", period) + # Factor 2: Foster care + is_in_foster_care = person("is_in_foster_care", period) + # Factor 3: Early Intervention or developmental delay + is_enrolled_ei = person("is_enrolled_in_early_intervention", period) + has_developmental_delay = person("has_developmental_delay", period) + # Factor 4: Deep poverty (≤50% FPL) + is_deep_poverty = person("il_pi_is_deep_poverty", period) + # Factor 5: Non-English speaking home + is_non_english_home = household("is_non_english_speaking_home", period) + + highest_priority = [ + is_homeless, + is_in_foster_care, + is_enrolled_ei, + has_developmental_delay, + is_deep_poverty, + is_non_english_home, + ] + + # Other priority factors (25 pts each) + # Factor 6: Low income (≤100% FPL) + is_low_income = person("il_pi_is_low_income", period) + # Factor 7: Parent didn't complete high school + parent_low_education = person( + "parent_has_less_than_high_school_education", period + ) + # Factor 8: Child/parent born outside US + born_outside_us = person("is_born_outside_us", period) + is_immigrant_family = spm_unit.any(born_outside_us) + # Factor 10: Active Duty Military family + is_military = person("is_military", period) + is_military_family = spm_unit.any(is_military) + # Factor 11: Parent is currently age 21 or younger + is_young_parent_family = person("il_pi_is_young_parent_family", period) + # Factor 13: History of abuse/neglect (protective services) + needs_protective_services = person( + "receives_or_needs_protective_services", period + ) + # Categorical benefits (income verification proxy) + receives_benefits = person( + "il_pi_receives_categorical_benefits", period + ) + + other_priority = [ + is_low_income, + parent_low_education, + is_immigrant_family, + is_military_family, + is_young_parent_family, + needs_protective_services, + receives_benefits, + ] + + # Lower priority factors (10 pts each) + # Factor 33: Teen parent at birth of first child + was_teen = person("was_teen_parent_at_first_birth", period) + is_teen_parent_family = spm_unit.any(was_teen) + # Factor 36: Experiencing poverty (≤200% FPL) + is_poverty = person("il_pi_is_poverty", period) + + lower_priority = [ + is_teen_parent_family, + is_poverty, + ] + + # Calculate weighted score + highest_score = sum([f.astype(int) for f in highest_priority]) * 50 + other_score = sum([f.astype(int) for f in other_priority]) * 25 + lower_score = sum([f.astype(int) for f in lower_priority]) * 10 + + return highest_score + other_score + lower_score diff --git a/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_receives_categorical_benefits.py b/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_receives_categorical_benefits.py index fe4dc72d821..38292292e70 100644 --- a/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_receives_categorical_benefits.py +++ b/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_receives_categorical_benefits.py @@ -4,16 +4,19 @@ class il_pi_receives_categorical_benefits(Variable): value_type = bool entity = Person - label = "Family receives categorical benefits (risk factor for IL PI)" + label = ( + "Family receives categorical benefits (income verification for IL PI)" + ) definition_period = YEAR reference = ( - "https://www.isbe.net/Documents/prevention-initiative-manual.pdf" + "https://www.isbe.net/Documents/Prevention-Initiative-Eligibility-Form.pdf#page=1", ) defined_for = StateCode.IL def formula(person, period, parameters): spm_unit = person.spm_unit - # Check for participation in categorical benefit programs. + # Public benefits used for income verification per eligibility form: + # WIC (185% FPL), Medicaid (138% FPL), SNAP (130% FPL), TANF (50% FPL). snap = spm_unit("snap", period) > 0 tanf = spm_unit("tanf", period) > 0 wic = add(spm_unit, period, ["wic"]) > 0 diff --git a/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_risk_factor_count.py b/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_risk_factor_count.py deleted file mode 100644 index d4114947014..00000000000 --- a/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_risk_factor_count.py +++ /dev/null @@ -1,50 +0,0 @@ -from policyengine_us.model_api import * - - -class il_pi_risk_factor_count(Variable): - value_type = int - entity = Person - label = "Number of risk factors for Illinois PI eligibility" - definition_period = YEAR - reference = ( - "https://www.isbe.net/Documents/prevention-initiative-manual.pdf" - ) - defined_for = StateCode.IL - - def formula(person, period, parameters): - # Highest priority factors (each also counts as a risk factor) - is_homeless = person.household("is_homeless", period) - is_in_foster_care = person("is_in_foster_care", period) - is_deep_poverty = person("il_pi_is_deep_poverty", period) - is_enrolled_ei = person("is_enrolled_in_early_intervention", period) - has_developmental_delay = person("has_developmental_delay", period) - is_non_english_home = person.household( - "is_non_english_speaking_home", period - ) - - # Standard risk factors - is_low_income = person("il_pi_is_low_income", period) - receives_benefits = person( - "il_pi_receives_categorical_benefits", period - ) - parent_low_education = person( - "parent_has_less_than_high_school_education", period - ) - needs_protective_services = person( - "receives_or_needs_protective_services", period - ) - - factors = [ - is_homeless, - is_in_foster_care, - is_deep_poverty, - is_enrolled_ei, - has_developmental_delay, - is_non_english_home, - is_low_income, - receives_benefits, - parent_low_education, - needs_protective_services, - ] - - return sum([f.astype(int) for f in factors]) diff --git a/policyengine_us/variables/gov/states/il/isbe/pi/il_pi.py b/policyengine_us/variables/gov/states/il/isbe/pi/il_pi.py new file mode 100644 index 00000000000..74cdd6f65c0 --- /dev/null +++ b/policyengine_us/variables/gov/states/il/isbe/pi/il_pi.py @@ -0,0 +1,15 @@ +from policyengine_us.model_api import * + + +class il_pi(Variable): + value_type = float + entity = Person + label = "Illinois Prevention Initiative (PI) benefit" + definition_period = YEAR + unit = USD + reference = ( + "https://www.isbe.net/Pages/Birth-to-Age-3-Years.aspx", + "https://gov-pritzker-newsroom.prezly.com/gov-pritzker-announces-5150-new-preschool-seats-through-smart-start-initiative", + ) + defined_for = "il_pi_eligible" + adds = ["gov.states.il.isbe.pi.benefit.amount"] diff --git a/policyengine_us/variables/gov/states/il/isbe/pi/il_pi_eligible.py b/policyengine_us/variables/gov/states/il/isbe/pi/il_pi_eligible.py index d582f44e1f9..6ad335c003a 100644 --- a/policyengine_us/variables/gov/states/il/isbe/pi/il_pi_eligible.py +++ b/policyengine_us/variables/gov/states/il/isbe/pi/il_pi_eligible.py @@ -10,11 +10,9 @@ class il_pi_eligible(Variable): defined_for = StateCode.IL def formula(person, period, parameters): - # Eligibility requires: (child under 3 OR pregnant), - # income <= 400% FPL, and at least 1 risk factor. - eligible_child = person("il_pi_eligible_child", period) - eligible_pregnant = person("il_pi_eligible_pregnant", period) - age_eligible = eligible_child | eligible_pregnant - income_eligible = person("il_pi_income_eligible", period) + # Eligibility requires: demographic eligible (child under 3 OR pregnant), + # income eligible (≤400% FPL), and risk eligible (≥50 pts). + demographic_eligible = person("il_pi_demographic_eligible", period) + income_eligible = person("il_isbe_income_eligible", period) risk_eligible = person("il_pi_risk_eligible", period) - return age_eligible & income_eligible & risk_eligible + return demographic_eligible & income_eligible & risk_eligible diff --git a/policyengine_us/variables/household/demographic/person/has_no_prior_formal_early_learning.py b/policyengine_us/variables/household/demographic/person/has_no_prior_formal_early_learning.py new file mode 100644 index 00000000000..6b3511e3fd4 --- /dev/null +++ b/policyengine_us/variables/household/demographic/person/has_no_prior_formal_early_learning.py @@ -0,0 +1,9 @@ +from policyengine_us.model_api import * + + +class has_no_prior_formal_early_learning(Variable): + value_type = bool + entity = Person + label = "Has not previously participated in formal early learning" + definition_period = YEAR + documentation = "Whether the child has NOT previously participated in a formal early learning program (e.g., Head Start, preschool, licensed childcare)" diff --git a/policyengine_us/variables/household/demographic/person/has_prior_formal_early_learning.py b/policyengine_us/variables/household/demographic/person/has_prior_formal_early_learning.py deleted file mode 100644 index a32887eb87d..00000000000 --- a/policyengine_us/variables/household/demographic/person/has_prior_formal_early_learning.py +++ /dev/null @@ -1,9 +0,0 @@ -from policyengine_us.model_api import * - - -class has_prior_formal_early_learning(Variable): - value_type = bool - entity = Person - label = "Has previously participated in formal early learning" - definition_period = YEAR - documentation = "Whether the child has previously participated in a formal early learning program (e.g., Head Start, preschool, licensed childcare)" From f8249e770bd1f9658151c4c1566a1faf607231a4 Mon Sep 17 00:00:00 2001 From: Ziming Date: Tue, 16 Dec 2025 13:36:12 -0500 Subject: [PATCH 04/11] adjustments --- .../eligibility/income/income_limit_rate.yaml | 2 +- .../il/isbe/income/countable_sources.yaml | 2 +- .../gov/states/il/isbe/pi/benefit/amount.yaml | 2 +- .../maximum.yaml => age_threshold/child.yaml} | 0 .../age_threshold/young_parent.yaml | 11 +++ .../eligibility/income/deep_poverty_rate.yaml | 2 +- .../eligibility/income/low_income_rate.yaml | 2 +- .../pi/eligibility/income/poverty_rate.yaml | 2 +- .../risk_factors/minimum_score.yaml | 2 +- .../eligibility/il_pi_highest_priority.yaml | 23 ++++- .../pi/eligibility/il_pi_risk_eligible.yaml | 17 ++-- .../priority/il_pi_priority_score.yaml | 64 +++++++------- .../gov/states/il/isbe/pi/integration.yaml | 23 +++-- .../eligibility/il_pi_demographic_eligible.py | 4 +- .../income/il_pi_is_deep_poverty.py | 6 +- .../priority/il_pi_highest_priority_score.py | 39 +++++++++ .../priority/il_pi_is_young_parent_family.py | 9 +- .../priority/il_pi_lower_priority_score.py | 29 +++++++ .../priority/il_pi_other_priority_score.py | 46 ++++++++++ .../priority/il_pi_priority_score.py | 83 ++----------------- .../il_pi_receives_categorical_benefits.py | 24 ------ 21 files changed, 227 insertions(+), 165 deletions(-) rename policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/{age/maximum.yaml => age_threshold/child.yaml} (100%) create mode 100644 policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/age_threshold/young_parent.yaml create mode 100644 policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_highest_priority_score.py create mode 100644 policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_lower_priority_score.py create mode 100644 policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_other_priority_score.py delete mode 100644 policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_receives_categorical_benefits.py diff --git a/policyengine_us/parameters/gov/states/il/isbe/eligibility/income/income_limit_rate.yaml b/policyengine_us/parameters/gov/states/il/isbe/eligibility/income/income_limit_rate.yaml index eb296cc5e83..9ce359122fe 100644 --- a/policyengine_us/parameters/gov/states/il/isbe/eligibility/income/income_limit_rate.yaml +++ b/policyengine_us/parameters/gov/states/il/isbe/eligibility/income/income_limit_rate.yaml @@ -1,4 +1,4 @@ -description: Illinois ISBE programs (PI, PFA, PFAE) limit eligibility to families with income at or below this share of the federal poverty guideline. +description: Illinois uses this share of the federal poverty guideline as the income limit for ISBE early childhood programs. values: 2015-01-01: 4 diff --git a/policyengine_us/parameters/gov/states/il/isbe/income/countable_sources.yaml b/policyengine_us/parameters/gov/states/il/isbe/income/countable_sources.yaml index 4e653164d2a..794e73131f2 100644 --- a/policyengine_us/parameters/gov/states/il/isbe/income/countable_sources.yaml +++ b/policyengine_us/parameters/gov/states/il/isbe/income/countable_sources.yaml @@ -1,4 +1,4 @@ -description: Illinois uses these income sources to calculate countable income under the Illinois State Board of Education early childhood programs. +description: Illinois uses these income sources for ISBE early childhood programs. values: 2015-01-01: # Earned income diff --git a/policyengine_us/parameters/gov/states/il/isbe/pi/benefit/amount.yaml b/policyengine_us/parameters/gov/states/il/isbe/pi/benefit/amount.yaml index a762bf4d318..f6530d3b43a 100644 --- a/policyengine_us/parameters/gov/states/il/isbe/pi/benefit/amount.yaml +++ b/policyengine_us/parameters/gov/states/il/isbe/pi/benefit/amount.yaml @@ -1,4 +1,4 @@ -description: Per-child funding amount for Illinois Prevention Initiative (PI) program for birth-to-3 services. +description: Illinois provides this amount per child under the Prevention Initiative program. values: # FY2025: $6.85M total / 512 children = $13,378.91, rounded to $13,379 2025-01-01: 13_379 diff --git a/policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/age/maximum.yaml b/policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/age_threshold/child.yaml similarity index 100% rename from policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/age/maximum.yaml rename to policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/age_threshold/child.yaml diff --git a/policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/age_threshold/young_parent.yaml b/policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/age_threshold/young_parent.yaml new file mode 100644 index 00000000000..e9acc44f101 --- /dev/null +++ b/policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/age_threshold/young_parent.yaml @@ -0,0 +1,11 @@ +description: Illinois limits young parent eligibility to parents at or below this age under the Prevention Initiative program. +values: + 2015-01-01: 21 + +metadata: + unit: year + period: year + label: Illinois PI young parent maximum age + reference: + - title: ISBE Prevention Initiative Eligibility Form (Factor 11) + href: https://www.isbe.net/Documents/Prevention-Initiative-Eligibility-Form.pdf#page=2 diff --git a/policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/income/deep_poverty_rate.yaml b/policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/income/deep_poverty_rate.yaml index 69ef2df316e..8c4598ebc77 100644 --- a/policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/income/deep_poverty_rate.yaml +++ b/policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/income/deep_poverty_rate.yaml @@ -1,4 +1,4 @@ -description: Illinois considers families with income at or below this share of the federal poverty guideline as deep poverty under the Prevention Initiative program (Factor 4, 50 points). +description: Illinois uses this share of the federal poverty guideline as the deep poverty threshold under the Prevention Initiative program. values: 2015-01-01: 0.5 diff --git a/policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/income/low_income_rate.yaml b/policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/income/low_income_rate.yaml index 7990a9db623..8848edb6393 100644 --- a/policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/income/low_income_rate.yaml +++ b/policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/income/low_income_rate.yaml @@ -1,4 +1,4 @@ -description: Illinois considers families with income at or below this share of the federal poverty guideline as low income under the Prevention Initiative program (Factor 6, 25 points). +description: Illinois uses this share of the federal poverty guideline as the low income threshold under the Prevention Initiative program. values: 2015-01-01: 1 diff --git a/policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/income/poverty_rate.yaml b/policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/income/poverty_rate.yaml index 3a0ea5ec1f9..8788a4f4b69 100644 --- a/policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/income/poverty_rate.yaml +++ b/policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/income/poverty_rate.yaml @@ -1,4 +1,4 @@ -description: Illinois considers families with income at or below this share of the federal poverty guideline as experiencing poverty under the Prevention Initiative program (Factor 36, 10 points). +description: Illinois uses this share of the federal poverty guideline as the poverty threshold under the Prevention Initiative program. values: 2015-01-01: 2 diff --git a/policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/risk_factors/minimum_score.yaml b/policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/risk_factors/minimum_score.yaml index 6369d0f6eff..e10605f7741 100644 --- a/policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/risk_factors/minimum_score.yaml +++ b/policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/risk_factors/minimum_score.yaml @@ -1,4 +1,4 @@ -description: Illinois requires at least this score for eligibility under the Prevention Initiative program. +description: Illinois requires this minimum score for eligibility under the Prevention Initiative program. values: 2015-01-01: 50 diff --git a/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/il_pi_highest_priority.yaml b/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/il_pi_highest_priority.yaml index 39a34938f36..01b69dd6439 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/il_pi_highest_priority.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/il_pi_highest_priority.yaml @@ -46,11 +46,26 @@ - name: Case 6, child with no priority factors. period: 2024 input: - age: 1 - state_code: IL - employment_income: 50_000 + people: + person1: + age: 35 + employment_income: 100_000 + person2: + age: 1 + households: + household: + members: [person1, person2] + state_code: IL + spm_units: + spm_unit: + members: [person1, person2] + il_tanf: 0 + tax_units: + tax_unit: + members: [person1, person2] output: - il_pi_highest_priority: false + # High income family with no risk factors + il_pi_highest_priority: [false, false] - name: Case 7, adult without age eligibility has no priority. period: 2024 diff --git a/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/il_pi_risk_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/il_pi_risk_eligible.yaml index d1dea5fdb20..cb0e32e2d2b 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/il_pi_risk_eligible.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/il_pi_risk_eligible.yaml @@ -1,4 +1,4 @@ -- name: Eligible child with homeless status (50 pts >= 50) +- name: Case 1, eligible child with homeless status (50 pts >= 50). period: 2024 input: people: @@ -14,23 +14,26 @@ spm_units: spm_unit: members: [person1, person2] + il_tanf: 0 tax_units: tax_unit: members: [person1, person2] output: # Only age-eligible child gets risk eligibility check + # Homeless (50) >= 50 minimum il_pi_risk_eligible: [false, true] -- name: Eligible child with two 25-pt factors (50 pts) +- name: Case 2, eligible child with two 25-pt factors (50 pts). period: 2024 input: people: person1: age: 30 - employment_income: 18_000 # Low income (25 pts) - parent_has_less_than_high_school_education: true # (25 pts) + employment_income: 18_000 person2: age: 1 + # Factor 7: Parent didn't complete high school (applies to child) + parent_has_less_than_high_school_education: true households: household: members: [person1, person2] @@ -38,14 +41,15 @@ spm_units: spm_unit: members: [person1, person2] + il_tanf: 0 tax_units: tax_unit: members: [person1, person2] output: - # Low income (25) + no high school (25) + poverty (10) + categorical (25) = 85 pts >= 50 + # Low income (25) + no high school (25) + poverty (10) = 60 pts >= 50 il_pi_risk_eligible: [false, true] -- name: Ineligible child with insufficient score +- name: Case 3, ineligible child with insufficient score. period: 2024 input: people: @@ -61,6 +65,7 @@ spm_units: spm_unit: members: [person1, person2] + il_tanf: 0 tax_units: tax_unit: members: [person1, person2] diff --git a/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/priority/il_pi_priority_score.yaml b/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/priority/il_pi_priority_score.yaml index 3c56a2e2df1..a9b20ce5176 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/priority/il_pi_priority_score.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/priority/il_pi_priority_score.yaml @@ -1,4 +1,4 @@ -- name: Homeless child with high income (only 50 pts for homelessness) +- name: Case 1, homeless child with high income (only 50 pts for homelessness). period: 2024 input: people: @@ -15,6 +15,7 @@ spm_units: spm_unit: members: [person1, person2] + il_tanf: 0 tax_units: tax_unit: members: [person1, person2] @@ -22,7 +23,7 @@ # Only age-eligible child gets priority score; homeless (50 pts) il_pi_priority_score: [0, 50] -- name: Low income family child +- name: Case 2, low income family child. period: 2024 input: people: @@ -38,14 +39,15 @@ spm_units: spm_unit: members: [person1, person2] + il_tanf: 0 tax_units: tax_unit: members: [person1, person2] output: - # Low income (25) + categorical benefits (25) + poverty (10) = 60 pts for child - il_pi_priority_score: [0, 60] + # Low income (25) + poverty (10) = 35 pts for child + il_pi_priority_score: [0, 35] -- name: No risk factors (high income) +- name: Case 3, no risk factors (high income). period: 2024 input: people: @@ -61,87 +63,91 @@ spm_units: spm_unit: members: [person1, person2] + il_tanf: 0 tax_units: tax_unit: members: [person1, person2] output: il_pi_priority_score: [0, 0] -- name: Family of 3 with one eligible child and one ineligible child +- name: Case 4, family of 3 with one eligible child and one ineligible child. period: 2024 input: people: - parent: + person1: age: 35 employment_income: 20_000 - child_eligible: + person2: age: 1 # Under 3, eligible for PI - child_ineligible: + person3: age: 4 # Age 4, not eligible for PI households: household: - members: [parent, child_eligible, child_ineligible] + members: [person1, person2, person3] state_code: IL is_homeless: true spm_units: spm_unit: - members: [parent, child_eligible, child_ineligible] + members: [person1, person2, person3] + il_tanf: 0 tax_units: tax_unit: - members: [parent, child_eligible, child_ineligible] + members: [person1, person2, person3] output: # Adult: 0 (not demographic eligible) - # Child age 1: homeless (50) + low income (25) + poverty (10) + categorical (25) = 110 pts + # Child age 1: homeless (50) + low income (25) + poverty (10) = 85 pts # Child age 4: 0 (not demographic eligible - too old for PI) - il_pi_priority_score: [0, 110, 0] + il_pi_priority_score: [0, 85, 0] -- name: Pregnant woman with priority factors +- name: Case 5, pregnant woman with priority factors. period: 2024 input: people: - pregnant_woman: + person1: age: 25 is_pregnant: true employment_income: 15_000 households: household: - members: [pregnant_woman] + members: [person1] state_code: IL is_non_english_speaking_home: true spm_units: spm_unit: - members: [pregnant_woman] + members: [person1] + il_tanf: 0 tax_units: tax_unit: - members: [pregnant_woman] + members: [person1] output: - # Non-English home (50) + low income (25) + poverty (10) + categorical (25) = 110 pts - il_pi_priority_score: [110] + # Non-English home (50) + low income (25) + poverty (10) = 85 pts + il_pi_priority_score: [85] -- name: Family with multiple highest priority factors +- name: Case 6, family with multiple highest priority factors. period: 2024 input: people: - parent: + person1: age: 28 employment_income: 5_000 # Deep poverty - infant: + person2: age: 0 is_in_foster_care: true is_enrolled_in_early_intervention: true households: household: - members: [parent, infant] + members: [person1, person2] state_code: IL is_homeless: true spm_units: spm_unit: - members: [parent, infant] + members: [person1, person2] + il_tanf: 0 tax_units: tax_unit: - members: [parent, infant] + members: [person1, person2] output: # Adult: 0 (not demographic eligible) # Infant: homeless (50) + foster (50) + EI (50) + deep poverty (50) + - # low income (25) + poverty (10) + categorical (25) = 260 pts - il_pi_priority_score: [0, 260] + # low income (25) + poverty (10) = 235 pts + il_pi_priority_score: [0, 235] diff --git a/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/integration.yaml b/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/integration.yaml index 6eccb7250e4..9ad2b812cad 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/integration.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/integration.yaml @@ -15,6 +15,7 @@ spm_units: spm_unit: members: [person1, person2] + il_tanf: 0 tax_units: tax_unit: members: [person1, person2] @@ -22,8 +23,8 @@ il_pi_demographic_eligible: [false, true] # Priority only applies to age-eligible (child under 3 or pregnant) il_pi_highest_priority: [false, true] - # EI (50) + poverty (10) + categorical benefits (25) = 85 pts for child only - il_pi_priority_score: [0, 85] + # EI (50) + poverty (10) = 60 pts for child only + il_pi_priority_score: [0, 60] il_pi_eligible: [false, true] - name: Case 2, pregnant woman in non-English speaking home. @@ -42,14 +43,14 @@ spm_units: spm_unit: members: [person1] + il_tanf: 0 tax_units: tax_unit: members: [person1] output: il_pi_highest_priority: [true] - # Non-English home (50) + low income (25) + poverty (10) + categorical benefits (25) = 110 pts - # But pregnant woman at $20k income - let me verify actual score - il_pi_priority_score: [85] + # Non-English home (50) + poverty (10) = 60 pts + il_pi_priority_score: [60] il_pi_eligible: [true] - name: Case 3, homeless family with toddler. @@ -69,6 +70,7 @@ spm_units: spm_unit: members: [person1, person2] + il_tanf: 0 tax_units: tax_unit: members: [person1, person2] @@ -76,8 +78,8 @@ il_pi_demographic_eligible: [false, true] # Priority only for age-eligible child il_pi_highest_priority: [false, true] - # Homeless (50) + deep poverty (50) + low income (25) + poverty (10) + categorical (25) = 160 pts - il_pi_priority_score: [0, 160] + # Homeless (50) + deep poverty (50) + low income (25) + poverty (10) = 135 pts + il_pi_priority_score: [0, 135] il_pi_eligible: [false, true] - name: Case 4, higher income family no risk factors ineligible. @@ -96,6 +98,7 @@ spm_units: spm_unit: members: [person1, person2] + il_tanf: 0 tax_units: tax_unit: members: [person1, person2] @@ -121,6 +124,7 @@ spm_units: spm_unit: members: [person1, person2] + il_tanf: 0 tax_units: tax_unit: members: [person1, person2] @@ -146,6 +150,7 @@ spm_units: spm_unit: members: [person1, person2] + il_tanf: 0 tax_units: tax_unit: members: [person1, person2] @@ -153,6 +158,6 @@ il_pi_demographic_eligible: [false, true] # Priority only for age-eligible child il_pi_highest_priority: [false, true] - # Foster care (50) + categorical benefits (25) = 75 pts for child - il_pi_priority_score: [0, 75] + # Foster care (50) = 50 pts for child + il_pi_priority_score: [0, 50] il_pi_eligible: [false, true] diff --git a/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/il_pi_demographic_eligible.py b/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/il_pi_demographic_eligible.py index 1ac5616a885..bfeb1aaabd3 100644 --- a/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/il_pi_demographic_eligible.py +++ b/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/il_pi_demographic_eligible.py @@ -11,8 +11,8 @@ class il_pi_demographic_eligible(Variable): def formula(person, period, parameters): # Eligible if child under 3 or pregnant woman. - p = parameters(period).gov.states.il.isbe.pi.eligibility.age + p = parameters(period).gov.states.il.isbe.pi.eligibility.age_threshold age = person("age", period) - is_child_under_3 = age < p.maximum + is_child_under_3 = age < p.child is_pregnant = person("is_pregnant", period) return is_child_under_3 | is_pregnant diff --git a/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/income/il_pi_is_deep_poverty.py b/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/income/il_pi_is_deep_poverty.py index e2361336225..145471c5fb0 100644 --- a/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/income/il_pi_is_deep_poverty.py +++ b/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/income/il_pi_is_deep_poverty.py @@ -4,7 +4,7 @@ class il_pi_is_deep_poverty(Variable): value_type = bool entity = Person - label = "In deep poverty for Illinois PI (Factor 4, 50 points)" + label = "In deep poverty or receiving TANF for Illinois PI (Factor 4)" definition_period = YEAR reference = ( "https://www.isbe.net/Documents/Prevention-Initiative-Eligibility-Form.pdf#page=2", @@ -18,4 +18,6 @@ def formula(person, period, parameters): fpg = spm_unit("spm_unit_fpg", period) income = spm_unit("il_isbe_countable_income", period) threshold = fpg * p.deep_poverty_rate - return income <= threshold + is_below_50_fpl = income <= threshold + receives_tanf = spm_unit("il_tanf", period) > 0 + return is_below_50_fpl | receives_tanf diff --git a/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_highest_priority_score.py b/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_highest_priority_score.py new file mode 100644 index 00000000000..0a7d73997a8 --- /dev/null +++ b/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_highest_priority_score.py @@ -0,0 +1,39 @@ +from policyengine_us.model_api import * + + +class il_pi_highest_priority_score(Variable): + value_type = int + entity = Person + label = "Illinois PI highest priority score (50 pts factors)" + definition_period = YEAR + reference = ( + "https://www.isbe.net/Documents/Prevention-Initiative-Eligibility-Form.pdf#page=2", + ) + defined_for = "il_pi_demographic_eligible" + + def formula(person, period, parameters): + household = person.household + + # Highest priority factors (50 pts each): + # Factor 1: Homeless (McKinney-Vento) + is_homeless = household("is_homeless", period) + # Factor 2: Youth in Care (foster care, child welfare) + is_in_foster_care = person("is_in_foster_care", period) + # Factor 3: Early Intervention or developmental delay + is_enrolled_ei = person("is_enrolled_in_early_intervention", period) + has_developmental_delay = person("has_developmental_delay", period) + # Factor 4: Deep poverty (<=50% FPL) and/or receiving TANF + is_deep_poverty = person("il_pi_is_deep_poverty", period) + # Factor 5: Non-English speaking home + is_non_english_home = household("is_non_english_speaking_home", period) + + highest_priority_factors = [ + is_homeless, + is_in_foster_care, + is_enrolled_ei, + has_developmental_delay, + is_deep_poverty, + is_non_english_home, + ] + + return sum([f.astype(int) for f in highest_priority_factors]) * 50 diff --git a/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_is_young_parent_family.py b/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_is_young_parent_family.py index d0f5c5f5778..c0a6406a983 100644 --- a/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_is_young_parent_family.py +++ b/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_is_young_parent_family.py @@ -4,7 +4,7 @@ class il_pi_is_young_parent_family(Variable): value_type = bool entity = Person - label = "Young parent family for Illinois PI (Factor 11, 25 points)" + label = "Young parent family for Illinois PI (Factor 11)" definition_period = YEAR reference = ( "https://www.isbe.net/Documents/Prevention-Initiative-Eligibility-Form.pdf#page=2", @@ -13,11 +13,12 @@ class il_pi_is_young_parent_family(Variable): def formula(person, period, parameters): # Factor 11 (25 pts): Parent is currently age 21 years or younger. - # All parents in the family must be age 21 or younger. + p = parameters(period).gov.states.il.isbe.pi.eligibility.age_threshold age = person("age", period) is_parent = person("is_parent", period) - is_young_parent = is_parent & (age <= 21) - is_old_parent = is_parent & (age > 21) + young_parent_max_age = p.young_parent + is_young_parent = is_parent & (age <= young_parent_max_age) + is_old_parent = is_parent & (age > young_parent_max_age) spm_unit = person.spm_unit has_young_parent = spm_unit.any(is_young_parent) has_old_parent = spm_unit.any(is_old_parent) diff --git a/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_lower_priority_score.py b/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_lower_priority_score.py new file mode 100644 index 00000000000..74e2053ffaa --- /dev/null +++ b/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_lower_priority_score.py @@ -0,0 +1,29 @@ +from policyengine_us.model_api import * + + +class il_pi_lower_priority_score(Variable): + value_type = int + entity = Person + label = "Illinois PI lower priority score (10 pts factors)" + definition_period = YEAR + reference = ( + "https://www.isbe.net/Documents/Prevention-Initiative-Eligibility-Form.pdf#page=3", + ) + defined_for = "il_pi_demographic_eligible" + + def formula(person, period, parameters): + spm_unit = person.spm_unit + + # Lower priority factors (10 pts each): + # Factor 33: Teen parent at birth of first child + was_teen = person("was_teen_parent_at_first_birth", period) + is_teen_parent_family = spm_unit.any(was_teen) + # Factor 36: Experiencing poverty (<=200% FPL) + is_poverty = person("il_pi_is_poverty", period) + + lower_priority_factors = [ + is_teen_parent_family, + is_poverty, + ] + + return sum([f.astype(int) for f in lower_priority_factors]) * 10 diff --git a/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_other_priority_score.py b/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_other_priority_score.py new file mode 100644 index 00000000000..d1e9f771910 --- /dev/null +++ b/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_other_priority_score.py @@ -0,0 +1,46 @@ +from policyengine_us.model_api import * + + +class il_pi_other_priority_score(Variable): + value_type = int + entity = Person + label = "Illinois PI other priority score (25 pts factors)" + definition_period = YEAR + reference = ( + "https://www.isbe.net/Documents/Prevention-Initiative-Eligibility-Form.pdf#page=2", + ) + defined_for = "il_pi_demographic_eligible" + + def formula(person, period, parameters): + spm_unit = person.spm_unit + + # Other priority factors (25 pts each): + # Factor 6: Low income (<=100% FPL) + is_low_income = person("il_pi_is_low_income", period) + # Factor 7: Parent didn't complete high school + parent_low_education = person( + "parent_has_less_than_high_school_education", period + ) + # Factor 8: Child/parent born outside US + born_outside_us = person("is_born_outside_us", period) + is_immigrant_family = spm_unit.any(born_outside_us) + # Factor 10: Active Duty Military family + is_military = person("is_military", period) + is_military_family = spm_unit.any(is_military) + # Factor 11: Parent is currently age 21 or younger + is_young_parent_family = person("il_pi_is_young_parent_family", period) + # Factor 13: History of child abuse or neglect + needs_protective_services = person( + "receives_or_needs_protective_services", period + ) + + other_priority_factors = [ + is_low_income, + parent_low_education, + is_immigrant_family, + is_military_family, + is_young_parent_family, + needs_protective_services, + ] + + return sum([f.astype(int) for f in other_priority_factors]) * 25 diff --git a/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_priority_score.py b/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_priority_score.py index 35f1c3aea0f..ade594b2a90 100644 --- a/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_priority_score.py +++ b/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_priority_score.py @@ -12,81 +12,8 @@ class il_pi_priority_score(Variable): ) defined_for = "il_pi_demographic_eligible" - def formula(person, period, parameters): - spm_unit = person.spm_unit - household = person.household - - # Highest priority factors (50 pts each) - # Factor 1: Homeless - is_homeless = household("is_homeless", period) - # Factor 2: Foster care - is_in_foster_care = person("is_in_foster_care", period) - # Factor 3: Early Intervention or developmental delay - is_enrolled_ei = person("is_enrolled_in_early_intervention", period) - has_developmental_delay = person("has_developmental_delay", period) - # Factor 4: Deep poverty (≤50% FPL) - is_deep_poverty = person("il_pi_is_deep_poverty", period) - # Factor 5: Non-English speaking home - is_non_english_home = household("is_non_english_speaking_home", period) - - highest_priority = [ - is_homeless, - is_in_foster_care, - is_enrolled_ei, - has_developmental_delay, - is_deep_poverty, - is_non_english_home, - ] - - # Other priority factors (25 pts each) - # Factor 6: Low income (≤100% FPL) - is_low_income = person("il_pi_is_low_income", period) - # Factor 7: Parent didn't complete high school - parent_low_education = person( - "parent_has_less_than_high_school_education", period - ) - # Factor 8: Child/parent born outside US - born_outside_us = person("is_born_outside_us", period) - is_immigrant_family = spm_unit.any(born_outside_us) - # Factor 10: Active Duty Military family - is_military = person("is_military", period) - is_military_family = spm_unit.any(is_military) - # Factor 11: Parent is currently age 21 or younger - is_young_parent_family = person("il_pi_is_young_parent_family", period) - # Factor 13: History of abuse/neglect (protective services) - needs_protective_services = person( - "receives_or_needs_protective_services", period - ) - # Categorical benefits (income verification proxy) - receives_benefits = person( - "il_pi_receives_categorical_benefits", period - ) - - other_priority = [ - is_low_income, - parent_low_education, - is_immigrant_family, - is_military_family, - is_young_parent_family, - needs_protective_services, - receives_benefits, - ] - - # Lower priority factors (10 pts each) - # Factor 33: Teen parent at birth of first child - was_teen = person("was_teen_parent_at_first_birth", period) - is_teen_parent_family = spm_unit.any(was_teen) - # Factor 36: Experiencing poverty (≤200% FPL) - is_poverty = person("il_pi_is_poverty", period) - - lower_priority = [ - is_teen_parent_family, - is_poverty, - ] - - # Calculate weighted score - highest_score = sum([f.astype(int) for f in highest_priority]) * 50 - other_score = sum([f.astype(int) for f in other_priority]) * 25 - lower_score = sum([f.astype(int) for f in lower_priority]) * 10 - - return highest_score + other_score + lower_score + adds = [ + "il_pi_highest_priority_score", + "il_pi_other_priority_score", + "il_pi_lower_priority_score", + ] diff --git a/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_receives_categorical_benefits.py b/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_receives_categorical_benefits.py deleted file mode 100644 index 38292292e70..00000000000 --- a/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_receives_categorical_benefits.py +++ /dev/null @@ -1,24 +0,0 @@ -from policyengine_us.model_api import * - - -class il_pi_receives_categorical_benefits(Variable): - value_type = bool - entity = Person - label = ( - "Family receives categorical benefits (income verification for IL PI)" - ) - definition_period = YEAR - reference = ( - "https://www.isbe.net/Documents/Prevention-Initiative-Eligibility-Form.pdf#page=1", - ) - defined_for = StateCode.IL - - def formula(person, period, parameters): - spm_unit = person.spm_unit - # Public benefits used for income verification per eligibility form: - # WIC (185% FPL), Medicaid (138% FPL), SNAP (130% FPL), TANF (50% FPL). - snap = spm_unit("snap", period) > 0 - tanf = spm_unit("tanf", period) > 0 - wic = add(spm_unit, period, ["wic"]) > 0 - medicaid = person("is_medicaid_eligible", period) - return snap | tanf | wic | medicaid From 2841650b6976b5bb485b97ece05f141f2fb959ef Mon Sep 17 00:00:00 2001 From: Ziming Date: Tue, 16 Dec 2025 13:45:12 -0500 Subject: [PATCH 05/11] add reference --- .../{eligibility => }/income/income_limit_rate.yaml | 4 +++- .../il/isbe/pi/eligibility/age_threshold/child.yaml | 12 ++++++------ .../pi/eligibility/age_threshold/young_parent.yaml | 4 ++-- .../il/isbe/eligibility/il_isbe_income_eligible.py | 2 +- 4 files changed, 12 insertions(+), 10 deletions(-) rename policyengine_us/parameters/gov/states/il/isbe/{eligibility => }/income/income_limit_rate.yaml (69%) diff --git a/policyengine_us/parameters/gov/states/il/isbe/eligibility/income/income_limit_rate.yaml b/policyengine_us/parameters/gov/states/il/isbe/income/income_limit_rate.yaml similarity index 69% rename from policyengine_us/parameters/gov/states/il/isbe/eligibility/income/income_limit_rate.yaml rename to policyengine_us/parameters/gov/states/il/isbe/income/income_limit_rate.yaml index 9ce359122fe..7de427befc7 100644 --- a/policyengine_us/parameters/gov/states/il/isbe/eligibility/income/income_limit_rate.yaml +++ b/policyengine_us/parameters/gov/states/il/isbe/income/income_limit_rate.yaml @@ -7,5 +7,7 @@ metadata: period: year label: Illinois ISBE income limit as share of FPL reference: - - title: CECIDS Methodology - Prevention Initiative + - title: CECIDS Methodology href: https://cecids.org/methodology/ + - title: 23 Ill. Adm. Code 235.10 + href: http://ilrules.elaws.us/iac/t23_pt235_sec.235.10 diff --git a/policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/age_threshold/child.yaml b/policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/age_threshold/child.yaml index 930f0e2ef78..c5e100982fa 100644 --- a/policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/age_threshold/child.yaml +++ b/policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/age_threshold/child.yaml @@ -1,13 +1,13 @@ -description: Illinois limits eligibility to children under this age for the Prevention Initiative program. +description: Illinois limits eligibility to children under this age under the Prevention Initiative program. values: 2015-01-01: 3 metadata: unit: year period: year - label: Illinois PI maximum age + label: Illinois PI child age threshold reference: - - title: ISBE Prevention Initiative Program - href: https://www.isbe.net/Pages/Birth-to-Age-3-Years.aspx - - title: IECAM Prevention Initiative Description - href: https://iecam.illinois.edu/data-descriptions/prevention-initiative-pi + - title: 105 ILCS 5/2-3.89 + href: https://ilga.gov/Documents/legislation/ilcs/documents/010500050K2-3.89.htm + - title: 23 Ill. Adm. Code 235.10 + href: http://ilrules.elaws.us/iac/t23_pt235_sec.235.10 diff --git a/policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/age_threshold/young_parent.yaml b/policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/age_threshold/young_parent.yaml index e9acc44f101..f54c1a8a951 100644 --- a/policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/age_threshold/young_parent.yaml +++ b/policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/age_threshold/young_parent.yaml @@ -1,11 +1,11 @@ -description: Illinois limits young parent eligibility to parents at or below this age under the Prevention Initiative program. +description: Illinois uses this age threshold for young parent priority under the Prevention Initiative program. values: 2015-01-01: 21 metadata: unit: year period: year - label: Illinois PI young parent maximum age + label: Illinois PI young parent age threshold reference: - title: ISBE Prevention Initiative Eligibility Form (Factor 11) href: https://www.isbe.net/Documents/Prevention-Initiative-Eligibility-Form.pdf#page=2 diff --git a/policyengine_us/variables/gov/states/il/isbe/eligibility/il_isbe_income_eligible.py b/policyengine_us/variables/gov/states/il/isbe/eligibility/il_isbe_income_eligible.py index 8309256c8db..9024cd75a2b 100644 --- a/policyengine_us/variables/gov/states/il/isbe/eligibility/il_isbe_income_eligible.py +++ b/policyengine_us/variables/gov/states/il/isbe/eligibility/il_isbe_income_eligible.py @@ -17,7 +17,7 @@ class il_isbe_income_eligible(Variable): def formula(person, period, parameters): spm_unit = person.spm_unit # Income must be at or below 400% FPL for ISBE programs. - p = parameters(period).gov.states.il.isbe.eligibility.income + p = parameters(period).gov.states.il.isbe.income fpg = spm_unit("spm_unit_fpg", period) income = spm_unit("il_isbe_countable_income", period) threshold = fpg * p.income_limit_rate From a57bc470361bb9b47b161a4148cd39a9e0a905ad Mon Sep 17 00:00:00 2001 From: Ziming Date: Tue, 16 Dec 2025 23:01:10 -0500 Subject: [PATCH 06/11] adjustments --- changelog_entry.yaml | 5 +- .../priority/geriatric_pregnancy_age.yaml | 9 + .../pi/eligibility/il_pi_basic_eligible.yaml | 46 +++++ .../eligibility/il_pi_highest_priority.yaml | 78 --------- .../pi/eligibility/il_pi_risk_eligible.yaml | 4 +- .../il_pi_has_developmental_delay.yaml | 59 +++++++ .../il_pi_has_geriatric_pregnancy.yaml | 50 ++++++ .../il_pi_highest_priority_score.yaml | 100 +++++++++++ .../priority/il_pi_lower_priority_score.yaml | 102 +++++++++++ .../priority/il_pi_other_priority_score.yaml | 160 ++++++++++++++++++ .../priority/il_pi_priority_score.yaml | 153 ----------------- .../gov/states/il/isbe/pi/integration.yaml | 51 +++--- .../il_isbe_was_teen_parent_at_first_birth.py | 17 ++ .../priority/il_pi_has_developmental_delay.py | 15 ++ .../priority/il_pi_has_geriatric_pregnancy.py | 19 +++ .../priority/il_pi_highest_priority.py | 33 ---- .../priority/il_pi_highest_priority_score.py | 4 +- .../priority/il_pi_lower_priority_score.py | 13 +- .../priority/il_pi_other_priority_score.py | 22 ++- ...ent_has_less_than_high_school_education.py | 6 +- .../is_enrolled_in_early_intervention.py | 8 - 21 files changed, 634 insertions(+), 320 deletions(-) create mode 100644 policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/priority/geriatric_pregnancy_age.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/il_pi_basic_eligible.yaml delete mode 100644 policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/il_pi_highest_priority.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/priority/il_pi_has_developmental_delay.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/priority/il_pi_has_geriatric_pregnancy.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/priority/il_pi_highest_priority_score.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/priority/il_pi_lower_priority_score.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/priority/il_pi_other_priority_score.yaml delete mode 100644 policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/priority/il_pi_priority_score.yaml create mode 100644 policyengine_us/variables/gov/states/il/isbe/eligibility/il_isbe_was_teen_parent_at_first_birth.py create mode 100644 policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_has_developmental_delay.py create mode 100644 policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_has_geriatric_pregnancy.py delete mode 100644 policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_highest_priority.py rename policyengine_us/variables/household/demographic/{person => household}/parent_has_less_than_high_school_education.py (55%) delete mode 100644 policyengine_us/variables/household/demographic/person/is_enrolled_in_early_intervention.py diff --git a/changelog_entry.yaml b/changelog_entry.yaml index 5fc8fb1897d..c6b6ff1248a 100644 --- a/changelog_entry.yaml +++ b/changelog_entry.yaml @@ -1,7 +1,4 @@ - bump: minor changes: added: - - Illinois Prevention Initiative (PI) program eligibility for children birth to age 3 and pregnant women. - - PI priority factors including foster care, homelessness, deep poverty, Early Intervention enrollment, and developmental delay. - - PI risk factor counting for eligibility determination. - - New input variables for IEP status, developmental delay, non-English speaking home, parent education level, and Early Intervention enrollment. + - Illinois Prevention Initiative (PI) program. diff --git a/policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/priority/geriatric_pregnancy_age.yaml b/policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/priority/geriatric_pregnancy_age.yaml new file mode 100644 index 00000000000..29d044ed202 --- /dev/null +++ b/policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/priority/geriatric_pregnancy_age.yaml @@ -0,0 +1,9 @@ +description: Minimum age for geriatric pregnancy factor in Illinois PI +metadata: + unit: year + label: Geriatric pregnancy age threshold + reference: + - title: Prevention Initiative Eligibility Form - Factor 28 + href: https://www.isbe.net/Documents/Prevention-Initiative-Eligibility-Form.pdf#page=3 +values: + 0000-01-01: 40 diff --git a/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/il_pi_basic_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/il_pi_basic_eligible.yaml new file mode 100644 index 00000000000..2a32933f7b2 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/il_pi_basic_eligible.yaml @@ -0,0 +1,46 @@ +- name: Case 1, eligible child under 3 with income below 400% FPL. + period: 2024 + input: + state_code: IL + age: 2 + employment_income: 30_000 + output: + il_pi_basic_eligible: true + +- name: Case 2, child under 3 but income above 400% FPL. + period: 2024 + input: + state_code: IL + age: 1 + employment_income: 150_000 + output: + il_pi_basic_eligible: false + +- name: Case 3, child age 3 (too old) with income below 400% FPL. + period: 2024 + input: + state_code: IL + age: 3 + employment_income: 20_000 + output: + il_pi_basic_eligible: false + +- name: Case 4, pregnant person with income below 400% FPL. + period: 2024 + input: + state_code: IL + age: 25 + is_pregnant: true + employment_income: 40_000 + output: + il_pi_basic_eligible: true + +- name: Case 5, pregnant person with income above 400% FPL. + period: 2024 + input: + state_code: IL + age: 30 + is_pregnant: true + employment_income: 200_000 + output: + il_pi_basic_eligible: false diff --git a/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/il_pi_highest_priority.yaml b/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/il_pi_highest_priority.yaml deleted file mode 100644 index 01b69dd6439..00000000000 --- a/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/il_pi_highest_priority.yaml +++ /dev/null @@ -1,78 +0,0 @@ -- name: Case 1, homeless child is highest priority. - period: 2024 - input: - age: 1 - state_code: IL - is_homeless: true - output: - il_pi_highest_priority: true - -- name: Case 2, foster care child is highest priority. - period: 2024 - input: - age: 0 - state_code: IL - is_in_foster_care: true - output: - il_pi_highest_priority: true - -- name: Case 3, child in Early Intervention is highest priority. - period: 2024 - input: - age: 2 - state_code: IL - is_enrolled_in_early_intervention: true - output: - il_pi_highest_priority: true - -- name: Case 4, child with developmental delay is highest priority. - period: 2024 - input: - age: 1 - state_code: IL - has_developmental_delay: true - output: - il_pi_highest_priority: true - -- name: Case 5, child in non-English home is highest priority. - period: 2024 - input: - age: 2 - state_code: IL - is_non_english_speaking_home: true - output: - il_pi_highest_priority: true - -- name: Case 6, child with no priority factors. - period: 2024 - input: - people: - person1: - age: 35 - employment_income: 100_000 - person2: - age: 1 - households: - household: - members: [person1, person2] - state_code: IL - spm_units: - spm_unit: - members: [person1, person2] - il_tanf: 0 - tax_units: - tax_unit: - members: [person1, person2] - output: - # High income family with no risk factors - il_pi_highest_priority: [false, false] - -- name: Case 7, adult without age eligibility has no priority. - period: 2024 - input: - age: 30 - state_code: IL - is_homeless: true - output: - # Adults are not demographically eligible, so priority is 0/false - il_pi_highest_priority: false diff --git a/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/il_pi_risk_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/il_pi_risk_eligible.yaml index cb0e32e2d2b..dcc60cb68be 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/il_pi_risk_eligible.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/il_pi_risk_eligible.yaml @@ -32,12 +32,12 @@ employment_income: 18_000 person2: age: 1 - # Factor 7: Parent didn't complete high school (applies to child) - parent_has_less_than_high_school_education: true households: household: members: [person1, person2] state_code: IL + # Factor 7: Parent didn't complete high school (Household-level) + parent_has_less_than_high_school_education: true spm_units: spm_unit: members: [person1, person2] diff --git a/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/priority/il_pi_has_developmental_delay.yaml b/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/priority/il_pi_has_developmental_delay.yaml new file mode 100644 index 00000000000..8810321c851 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/priority/il_pi_has_developmental_delay.yaml @@ -0,0 +1,59 @@ +- name: Case 1, no disability in household. + period: 2024 + input: + people: + person1: + age: 30 + person2: + age: 1 + spm_units: + spm_unit: + members: [person1, person2] + output: + il_pi_has_developmental_delay: false + +- name: Case 2, child has developmental delay. + period: 2024 + input: + people: + person1: + age: 30 + person2: + age: 1 + has_developmental_delay: true + spm_units: + spm_unit: + members: [person1, person2] + output: + il_pi_has_developmental_delay: true + +- name: Case 3, parent is disabled. + period: 2024 + input: + people: + person1: + age: 30 + is_disabled: true + person2: + age: 1 + spm_units: + spm_unit: + members: [person1, person2] + output: + il_pi_has_developmental_delay: true + +- name: Case 4, both disability and developmental delay. + period: 2024 + input: + people: + person1: + age: 30 + is_disabled: true + person2: + age: 1 + has_developmental_delay: true + spm_units: + spm_unit: + members: [person1, person2] + output: + il_pi_has_developmental_delay: true diff --git a/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/priority/il_pi_has_geriatric_pregnancy.yaml b/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/priority/il_pi_has_geriatric_pregnancy.yaml new file mode 100644 index 00000000000..91f29d45ed7 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/priority/il_pi_has_geriatric_pregnancy.yaml @@ -0,0 +1,50 @@ +- name: Case 1, no pregnancy. + period: 2024 + input: + people: + person1: + age: 42 + spm_units: + spm_unit: + members: [person1] + output: + il_pi_has_geriatric_pregnancy: false + +- name: Case 2, pregnant but under 40. + period: 2024 + input: + people: + person1: + age: 35 + is_pregnant: true + spm_units: + spm_unit: + members: [person1] + output: + il_pi_has_geriatric_pregnancy: false + +- name: Case 3, pregnant at exactly 40. + period: 2024 + input: + people: + person1: + age: 40 + is_pregnant: true + spm_units: + spm_unit: + members: [person1] + output: + il_pi_has_geriatric_pregnancy: true + +- name: Case 4, pregnant over 40. + period: 2024 + input: + people: + person1: + age: 45 + is_pregnant: true + spm_units: + spm_unit: + members: [person1] + output: + il_pi_has_geriatric_pregnancy: true diff --git a/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/priority/il_pi_highest_priority_score.yaml b/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/priority/il_pi_highest_priority_score.yaml new file mode 100644 index 00000000000..0f4ae90e054 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/priority/il_pi_highest_priority_score.yaml @@ -0,0 +1,100 @@ +- name: Case 1, no highest priority factors. + period: 2024 + input: + people: + person1: + age: 30 + employment_income: 100_000 + person2: + age: 1 + households: + household: + members: [person1, person2] + state_code: IL + spm_units: + spm_unit: + members: [person1, person2] + il_tanf: 0 + tax_units: + tax_unit: + members: [person1, person2] + output: + # No factors = 0 pts + il_pi_highest_priority_score: [0, 0] + +- name: Case 2, homeless family. + period: 2024 + input: + people: + person1: + age: 30 + employment_income: 100_000 + person2: + age: 1 + households: + household: + members: [person1, person2] + state_code: IL + is_homeless: true + spm_units: + spm_unit: + members: [person1, person2] + il_tanf: 0 + tax_units: + tax_unit: + members: [person1, person2] + output: + # Homeless (50) = 50 pts for child only + il_pi_highest_priority_score: [0, 50] + +- name: Case 3, foster child. + period: 2024 + input: + people: + person1: + age: 30 + employment_income: 100_000 + person2: + age: 1 + is_in_foster_care: true + households: + household: + members: [person1, person2] + state_code: IL + spm_units: + spm_unit: + members: [person1, person2] + il_tanf: 0 + tax_units: + tax_unit: + members: [person1, person2] + output: + # Foster care (50) = 50 pts for child only + il_pi_highest_priority_score: [0, 50] + +- name: Case 4, multiple highest priority factors. + period: 2024 + input: + people: + person1: + age: 30 + employment_income: 5_000 + person2: + age: 1 + has_developmental_delay: true + households: + household: + members: [person1, person2] + state_code: IL + is_homeless: true + is_non_english_speaking_home: true + spm_units: + spm_unit: + members: [person1, person2] + il_tanf: 0 + tax_units: + tax_unit: + members: [person1, person2] + output: + # Homeless (50) + developmental delay (50) + deep poverty (50) + non-English (50) = 200 pts + il_pi_highest_priority_score: [0, 200] diff --git a/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/priority/il_pi_lower_priority_score.yaml b/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/priority/il_pi_lower_priority_score.yaml new file mode 100644 index 00000000000..6f9c002a8e3 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/priority/il_pi_lower_priority_score.yaml @@ -0,0 +1,102 @@ +- name: Case 1, no lower priority factors married couple. + period: 2024 + input: + people: + person1: + age: 30 + employment_income: 100_000 + person2: + age: 30 + is_tax_unit_spouse: true + person3: + age: 1 + households: + household: + members: [person1, person2, person3] + state_code: IL + spm_units: + spm_unit: + members: [person1, person2, person3] + il_tanf: 0 + tax_units: + tax_unit: + members: [person1, person2, person3] + output: + # No factors = 0 pts + il_pi_lower_priority_score: [0, 0, 0] + +- name: Case 2, single parent only. + period: 2024 + input: + people: + person1: + age: 30 + employment_income: 100_000 + person2: + age: 1 + households: + household: + members: [person1, person2] + state_code: IL + spm_units: + spm_unit: + members: [person1, person2] + il_tanf: 0 + tax_units: + tax_unit: + members: [person1, person2] + output: + # Single parent (10) = 10 pts for child only + il_pi_lower_priority_score: [0, 10] + +- name: Case 3, poverty and single parent. + period: 2024 + input: + people: + person1: + age: 30 + employment_income: 35_000 + person2: + age: 1 + households: + household: + members: [person1, person2] + state_code: IL + spm_units: + spm_unit: + members: [person1, person2] + il_tanf: 0 + tax_units: + tax_unit: + members: [person1, person2] + output: + # Single parent (10) + poverty (10) = 20 pts for child only + il_pi_lower_priority_score: [0, 20] + +- name: Case 4, teen parent family. + period: 2024 + input: + people: + person1: + age: 30 + employment_income: 100_000 + person2: + age: 30 + is_tax_unit_spouse: true + person3: + age: 1 + households: + household: + members: [person1, person2, person3] + state_code: IL + il_isbe_was_teen_parent_at_first_birth: true + spm_units: + spm_unit: + members: [person1, person2, person3] + il_tanf: 0 + tax_units: + tax_unit: + members: [person1, person2, person3] + output: + # Teen parent (10) = 10 pts for child only + il_pi_lower_priority_score: [0, 0, 10] diff --git a/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/priority/il_pi_other_priority_score.yaml b/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/priority/il_pi_other_priority_score.yaml new file mode 100644 index 00000000000..1e8198c08eb --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/priority/il_pi_other_priority_score.yaml @@ -0,0 +1,160 @@ +- name: Case 1, no other priority factors. + period: 2024 + input: + people: + person1: + age: 30 + employment_income: 100_000 + person2: + age: 30 + is_tax_unit_spouse: true + person3: + age: 1 + households: + household: + members: [person1, person2, person3] + state_code: IL + spm_units: + spm_unit: + members: [person1, person2, person3] + il_tanf: 0 + tax_units: + tax_unit: + members: [person1, person2, person3] + output: + # No factors = 0 pts + il_pi_other_priority_score: [0, 0, 0] + +- name: Case 2, low income family. + period: 2024 + input: + people: + person1: + age: 30 + employment_income: 18_000 + person2: + age: 30 + is_tax_unit_spouse: true + person3: + age: 1 + households: + household: + members: [person1, person2, person3] + state_code: IL + spm_units: + spm_unit: + members: [person1, person2, person3] + il_tanf: 0 + tax_units: + tax_unit: + members: [person1, person2, person3] + output: + # Low income (25) = 25 pts for child only + il_pi_other_priority_score: [0, 0, 25] + +- name: Case 3, immigrant family. + period: 2024 + input: + people: + person1: + age: 30 + employment_income: 100_000 + is_born_outside_us: true + person2: + age: 30 + is_tax_unit_spouse: true + person3: + age: 1 + households: + household: + members: [person1, person2, person3] + state_code: IL + spm_units: + spm_unit: + members: [person1, person2, person3] + il_tanf: 0 + tax_units: + tax_unit: + members: [person1, person2, person3] + output: + # Immigrant family (25) = 25 pts for child only + il_pi_other_priority_score: [0, 0, 25] + +- name: Case 4, military family. + period: 2024 + input: + people: + person1: + age: 30 + employment_income: 50_000 + military_basic_pay: 50_000 + person2: + age: 30 + is_tax_unit_spouse: true + person3: + age: 1 + households: + household: + members: [person1, person2, person3] + state_code: IL + spm_units: + spm_unit: + members: [person1, person2, person3] + il_tanf: 0 + tax_units: + tax_unit: + members: [person1, person2, person3] + output: + # Military family (25) = 25 pts for child only + il_pi_other_priority_score: [0, 0, 25] + +- name: Case 5, geriatric pregnancy. + period: 2024 + input: + people: + person1: + age: 42 + is_pregnant: true + employment_income: 100_000 + households: + household: + members: [person1] + state_code: IL + spm_units: + spm_unit: + members: [person1] + il_tanf: 0 + tax_units: + tax_unit: + members: [person1] + output: + # Geriatric pregnancy (25) = 25 pts + il_pi_other_priority_score: [25] + +- name: Case 6, household has disability. + period: 2024 + input: + people: + person1: + age: 30 + employment_income: 100_000 + is_disabled: true + person2: + age: 30 + is_tax_unit_spouse: true + person3: + age: 1 + households: + household: + members: [person1, person2, person3] + state_code: IL + spm_units: + spm_unit: + members: [person1, person2, person3] + il_tanf: 0 + tax_units: + tax_unit: + members: [person1, person2, person3] + output: + # Household has disability (25) = 25 pts for child only + il_pi_other_priority_score: [0, 0, 25] diff --git a/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/priority/il_pi_priority_score.yaml b/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/priority/il_pi_priority_score.yaml deleted file mode 100644 index a9b20ce5176..00000000000 --- a/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/priority/il_pi_priority_score.yaml +++ /dev/null @@ -1,153 +0,0 @@ -- name: Case 1, homeless child with high income (only 50 pts for homelessness). - period: 2024 - input: - people: - person1: - age: 30 - employment_income: 150_000 # High income to avoid income-based factors - person2: - age: 1 - households: - household: - members: [person1, person2] - state_code: IL - is_homeless: true - spm_units: - spm_unit: - members: [person1, person2] - il_tanf: 0 - tax_units: - tax_unit: - members: [person1, person2] - output: - # Only age-eligible child gets priority score; homeless (50 pts) - il_pi_priority_score: [0, 50] - -- name: Case 2, low income family child. - period: 2024 - input: - people: - person1: - age: 30 - employment_income: 18_000 # Below 100% FPL - person2: - age: 1 - households: - household: - members: [person1, person2] - state_code: IL - spm_units: - spm_unit: - members: [person1, person2] - il_tanf: 0 - tax_units: - tax_unit: - members: [person1, person2] - output: - # Low income (25) + poverty (10) = 35 pts for child - il_pi_priority_score: [0, 35] - -- name: Case 3, no risk factors (high income). - period: 2024 - input: - people: - person1: - age: 30 - employment_income: 150_000 - person2: - age: 1 - households: - household: - members: [person1, person2] - state_code: IL - spm_units: - spm_unit: - members: [person1, person2] - il_tanf: 0 - tax_units: - tax_unit: - members: [person1, person2] - output: - il_pi_priority_score: [0, 0] - -- name: Case 4, family of 3 with one eligible child and one ineligible child. - period: 2024 - input: - people: - person1: - age: 35 - employment_income: 20_000 - person2: - age: 1 # Under 3, eligible for PI - person3: - age: 4 # Age 4, not eligible for PI - households: - household: - members: [person1, person2, person3] - state_code: IL - is_homeless: true - spm_units: - spm_unit: - members: [person1, person2, person3] - il_tanf: 0 - tax_units: - tax_unit: - members: [person1, person2, person3] - output: - # Adult: 0 (not demographic eligible) - # Child age 1: homeless (50) + low income (25) + poverty (10) = 85 pts - # Child age 4: 0 (not demographic eligible - too old for PI) - il_pi_priority_score: [0, 85, 0] - -- name: Case 5, pregnant woman with priority factors. - period: 2024 - input: - people: - person1: - age: 25 - is_pregnant: true - employment_income: 15_000 - households: - household: - members: [person1] - state_code: IL - is_non_english_speaking_home: true - spm_units: - spm_unit: - members: [person1] - il_tanf: 0 - tax_units: - tax_unit: - members: [person1] - output: - # Non-English home (50) + low income (25) + poverty (10) = 85 pts - il_pi_priority_score: [85] - -- name: Case 6, family with multiple highest priority factors. - period: 2024 - input: - people: - person1: - age: 28 - employment_income: 5_000 # Deep poverty - person2: - age: 0 - is_in_foster_care: true - is_enrolled_in_early_intervention: true - households: - household: - members: [person1, person2] - state_code: IL - is_homeless: true - spm_units: - spm_unit: - members: [person1, person2] - il_tanf: 0 - tax_units: - tax_unit: - members: [person1, person2] - output: - # Adult: 0 (not demographic eligible) - # Infant: homeless (50) + foster (50) + EI (50) + deep poverty (50) + - # low income (25) + poverty (10) = 235 pts - il_pi_priority_score: [0, 235] diff --git a/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/integration.yaml b/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/integration.yaml index 9ad2b812cad..fe77064c21f 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/integration.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/integration.yaml @@ -1,4 +1,4 @@ -- name: Case 1, low income family with infant in Early Intervention. +- name: Case 1, single parent low income family with infant with developmental delay. period: 2024 input: people: @@ -7,7 +7,7 @@ employment_income: 25_000 person2: age: 1 - is_enrolled_in_early_intervention: true + has_developmental_delay: true households: household: members: [person1, person2] @@ -21,13 +21,11 @@ members: [person1, person2] output: il_pi_demographic_eligible: [false, true] - # Priority only applies to age-eligible (child under 3 or pregnant) - il_pi_highest_priority: [false, true] - # EI (50) + poverty (10) = 60 pts for child only - il_pi_priority_score: [0, 60] + # Developmental delay (50) + household has disability (25) + single parent (10) + poverty (10) = 95 pts + il_pi_priority_score: [0, 95] il_pi_eligible: [false, true] -- name: Case 2, pregnant woman in non-English speaking home. +- name: Case 2, pregnant single woman in non-English speaking home. period: 2024 input: people: @@ -48,12 +46,11 @@ tax_unit: members: [person1] output: - il_pi_highest_priority: [true] - # Non-English home (50) + poverty (10) = 60 pts - il_pi_priority_score: [60] + # Non-English home (50) + single parent (10) + poverty (10) = 70 pts + il_pi_priority_score: [70] il_pi_eligible: [true] -- name: Case 3, homeless family with toddler. +- name: Case 3, homeless single parent family with toddler. period: 2024 input: people: @@ -76,13 +73,11 @@ members: [person1, person2] output: il_pi_demographic_eligible: [false, true] - # Priority only for age-eligible child - il_pi_highest_priority: [false, true] - # Homeless (50) + deep poverty (50) + low income (25) + poverty (10) = 135 pts - il_pi_priority_score: [0, 135] + # Homeless (50) + deep poverty (50) + low income (25) + single parent (10) + poverty (10) = 145 pts + il_pi_priority_score: [0, 145] il_pi_eligible: [false, true] -- name: Case 4, higher income family no risk factors ineligible. +- name: Case 4, higher income married couple no risk factors ineligible. period: 2024 input: people: @@ -90,22 +85,26 @@ age: 35 employment_income: 150_000 person2: + age: 35 + is_tax_unit_spouse: true + child: age: 1 households: household: - members: [person1, person2] + members: [person1, person2, child] state_code: IL spm_units: spm_unit: - members: [person1, person2] + members: [person1, person2, child] il_tanf: 0 tax_units: tax_unit: - members: [person1, person2] + members: [person1, person2, child] output: - il_pi_demographic_eligible: [false, true] - il_pi_priority_score: [0, 0] - il_pi_eligible: [false, false] + il_pi_demographic_eligible: [false, false, true] + # Married couple with high income - no risk factors + il_pi_priority_score: [0, 0, 0] + il_pi_eligible: [false, false, false] - name: Case 5, child age 3 transitions out of PI. period: 2024 @@ -133,7 +132,7 @@ # Child has developmental delay but too old for PI il_pi_eligible: [false, false] -- name: Case 6, foster child infant highest priority. +- name: Case 6, single parent foster child infant highest priority. period: 2024 input: people: @@ -156,8 +155,6 @@ members: [person1, person2] output: il_pi_demographic_eligible: [false, true] - # Priority only for age-eligible child - il_pi_highest_priority: [false, true] - # Foster care (50) = 50 pts for child - il_pi_priority_score: [0, 50] + # Foster care (50) + single parent (10) = 60 pts for child + il_pi_priority_score: [0, 60] il_pi_eligible: [false, true] diff --git a/policyengine_us/variables/gov/states/il/isbe/eligibility/il_isbe_was_teen_parent_at_first_birth.py b/policyengine_us/variables/gov/states/il/isbe/eligibility/il_isbe_was_teen_parent_at_first_birth.py new file mode 100644 index 00000000000..52bf0571c53 --- /dev/null +++ b/policyengine_us/variables/gov/states/il/isbe/eligibility/il_isbe_was_teen_parent_at_first_birth.py @@ -0,0 +1,17 @@ +from policyengine_us.model_api import * + + +class il_isbe_was_teen_parent_at_first_birth(Variable): + value_type = bool + entity = Household + label = "Parent was a teen at birth of first child" + definition_period = YEAR + documentation = ( + "Whether any parent in the household was under age 20 when their " + "first child was born. This is a risk factor for Illinois ISBE " + "early childhood programs." + ) + reference = ( + "https://www.isbe.net/Documents/pdg-eg-grant-enrollment-form.pdf" + ) + defined_for = StateCode.IL diff --git a/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_has_developmental_delay.py b/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_has_developmental_delay.py new file mode 100644 index 00000000000..60b22b461e2 --- /dev/null +++ b/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_has_developmental_delay.py @@ -0,0 +1,15 @@ +from policyengine_us.model_api import * + + +class il_pi_has_developmental_delay(Variable): + value_type = bool + entity = SPMUnit + label = "SPM unit has developmental delay or disability for Illinois PI" + definition_period = YEAR + reference = "https://www.isbe.net/Documents/Prevention-Initiative-Eligibility-Form.pdf#page=2" + + def formula(spm_unit, period, parameters): + # Factor 18: Member of household has developmental delay or disability + has_disability = spm_unit.members("is_disabled", period) + has_dev_delay = spm_unit.members("has_developmental_delay", period) + return spm_unit.any(has_disability | has_dev_delay) diff --git a/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_has_geriatric_pregnancy.py b/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_has_geriatric_pregnancy.py new file mode 100644 index 00000000000..38260e018a3 --- /dev/null +++ b/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_has_geriatric_pregnancy.py @@ -0,0 +1,19 @@ +from policyengine_us.model_api import * + + +class il_pi_has_geriatric_pregnancy(Variable): + value_type = bool + entity = SPMUnit + label = "Household has geriatric pregnancy for Illinois PI" + definition_period = YEAR + reference = "https://www.isbe.net/Documents/Prevention-Initiative-Eligibility-Form.pdf#page=3" + + def formula(spm_unit, period, parameters): + # Factor 28: Pregnant woman age 40 or over + p = parameters(period).gov.states.il.isbe.pi.eligibility.priority + is_pregnant = spm_unit.members("is_pregnant", period) + age = spm_unit.members("age", period) + has_geriatric_pregnancy = is_pregnant & ( + age >= p.geriatric_pregnancy_age + ) + return spm_unit.any(has_geriatric_pregnancy) diff --git a/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_highest_priority.py b/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_highest_priority.py deleted file mode 100644 index c5c42600520..00000000000 --- a/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_highest_priority.py +++ /dev/null @@ -1,33 +0,0 @@ -from policyengine_us.model_api import * - - -class il_pi_highest_priority(Variable): - value_type = bool - entity = Person - label = "Has a highest priority factor for Illinois PI" - definition_period = YEAR - reference = ( - "https://www.isbe.net/Documents/Prevention-Initiative-Eligibility-Form.pdf#page=2", - ) - defined_for = "il_pi_demographic_eligible" - - def formula(person, period, parameters): - # Highest priority factors: foster care, homeless, deep poverty, - # Early Intervention, developmental delay, non-English home. - is_homeless = person.household("is_homeless", period) - is_in_foster_care = person("is_in_foster_care", period) - is_deep_poverty = person("il_pi_is_deep_poverty", period) - is_enrolled_ei = person("is_enrolled_in_early_intervention", period) - has_developmental_delay = person("has_developmental_delay", period) - is_non_english_home = person.household( - "is_non_english_speaking_home", period - ) - - return ( - is_homeless - | is_in_foster_care - | is_deep_poverty - | is_enrolled_ei - | has_developmental_delay - | is_non_english_home - ) diff --git a/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_highest_priority_score.py b/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_highest_priority_score.py index 0a7d73997a8..7d2e9522301 100644 --- a/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_highest_priority_score.py +++ b/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_highest_priority_score.py @@ -19,8 +19,7 @@ def formula(person, period, parameters): is_homeless = household("is_homeless", period) # Factor 2: Youth in Care (foster care, child welfare) is_in_foster_care = person("is_in_foster_care", period) - # Factor 3: Early Intervention or developmental delay - is_enrolled_ei = person("is_enrolled_in_early_intervention", period) + # Factor 3: Developmental delay has_developmental_delay = person("has_developmental_delay", period) # Factor 4: Deep poverty (<=50% FPL) and/or receiving TANF is_deep_poverty = person("il_pi_is_deep_poverty", period) @@ -30,7 +29,6 @@ def formula(person, period, parameters): highest_priority_factors = [ is_homeless, is_in_foster_care, - is_enrolled_ei, has_developmental_delay, is_deep_poverty, is_non_english_home, diff --git a/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_lower_priority_score.py b/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_lower_priority_score.py index 74e2053ffaa..8295e17f0c3 100644 --- a/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_lower_priority_score.py +++ b/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_lower_priority_score.py @@ -12,17 +12,24 @@ class il_pi_lower_priority_score(Variable): defined_for = "il_pi_demographic_eligible" def formula(person, period, parameters): + household = person.household spm_unit = person.spm_unit # Lower priority factors (10 pts each): - # Factor 33: Teen parent at birth of first child - was_teen = person("was_teen_parent_at_first_birth", period) - is_teen_parent_family = spm_unit.any(was_teen) + # Factor 33: Teen parent at birth of first child (Household-level variable) + # Parent was under 20 when first child was born + is_teen_parent_family = household( + "il_isbe_was_teen_parent_at_first_birth", period + ) + # Factor 35: Parent/Caregiver is single parent + is_parent = spm_unit.members("is_tax_unit_head_or_spouse", period) + is_single_parent = spm_unit.sum(is_parent) == 1 # Factor 36: Experiencing poverty (<=200% FPL) is_poverty = person("il_pi_is_poverty", period) lower_priority_factors = [ is_teen_parent_family, + is_single_parent, is_poverty, ] diff --git a/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_other_priority_score.py b/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_other_priority_score.py index d1e9f771910..408e92d3058 100644 --- a/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_other_priority_score.py +++ b/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_other_priority_score.py @@ -13,25 +13,30 @@ class il_pi_other_priority_score(Variable): def formula(person, period, parameters): spm_unit = person.spm_unit + household = person.household # Other priority factors (25 pts each): # Factor 6: Low income (<=100% FPL) is_low_income = person("il_pi_is_low_income", period) - # Factor 7: Parent didn't complete high school - parent_low_education = person( + # Factor 7: Parent didn't complete high school (Household-level variable) + parent_low_education = household( "parent_has_less_than_high_school_education", period ) # Factor 8: Child/parent born outside US born_outside_us = person("is_born_outside_us", period) is_immigrant_family = spm_unit.any(born_outside_us) # Factor 10: Active Duty Military family - is_military = person("is_military", period) - is_military_family = spm_unit.any(is_military) + is_active_duty_military = person("military_basic_pay", period) > 0 + is_military_family = spm_unit.any(is_active_duty_military) # Factor 11: Parent is currently age 21 or younger is_young_parent_family = person("il_pi_is_young_parent_family", period) - # Factor 13: History of child abuse or neglect - needs_protective_services = person( - "receives_or_needs_protective_services", period + # Factor 18: Member of household has developmental delay or disability + has_developmental_delay = spm_unit( + "il_pi_has_developmental_delay", period + ) + # Factor 28: Geriatric pregnancy (pregnant woman age 40+) + has_geriatric_pregnancy = spm_unit( + "il_pi_has_geriatric_pregnancy", period ) other_priority_factors = [ @@ -40,7 +45,8 @@ def formula(person, period, parameters): is_immigrant_family, is_military_family, is_young_parent_family, - needs_protective_services, + has_developmental_delay, + has_geriatric_pregnancy, ] return sum([f.astype(int) for f in other_priority_factors]) * 25 diff --git a/policyengine_us/variables/household/demographic/person/parent_has_less_than_high_school_education.py b/policyengine_us/variables/household/demographic/household/parent_has_less_than_high_school_education.py similarity index 55% rename from policyengine_us/variables/household/demographic/person/parent_has_less_than_high_school_education.py rename to policyengine_us/variables/household/demographic/household/parent_has_less_than_high_school_education.py index 67756f90257..be2f7d8ce68 100644 --- a/policyengine_us/variables/household/demographic/person/parent_has_less_than_high_school_education.py +++ b/policyengine_us/variables/household/demographic/household/parent_has_less_than_high_school_education.py @@ -3,6 +3,10 @@ class parent_has_less_than_high_school_education(Variable): value_type = bool - entity = Person + entity = Household label = "Parent has less than high school education" definition_period = YEAR + documentation = ( + "Whether any parent or guardian in the household has less than " + "a high school diploma or equivalent" + ) diff --git a/policyengine_us/variables/household/demographic/person/is_enrolled_in_early_intervention.py b/policyengine_us/variables/household/demographic/person/is_enrolled_in_early_intervention.py deleted file mode 100644 index 0a1245b329d..00000000000 --- a/policyengine_us/variables/household/demographic/person/is_enrolled_in_early_intervention.py +++ /dev/null @@ -1,8 +0,0 @@ -from policyengine_us.model_api import * - - -class is_enrolled_in_early_intervention(Variable): - value_type = bool - entity = Person - label = "Enrolled in Part C Early Intervention services" - definition_period = YEAR From 617953eddc5ec5c5df7b7a6360581e2bb666b364 Mon Sep 17 00:00:00 2001 From: Ziming Date: Fri, 19 Dec 2025 12:06:53 -0500 Subject: [PATCH 07/11] add benefit amount in 2024 --- .../il/isbe/age_threshold/teen_parent.yaml | 15 + .../il/isbe/income/countable_sources.yaml | 2 +- .../il/isbe/income/income_limit_rate.yaml | 12 +- .../gov/states/il/isbe/pi/benefit/amount.yaml | 12 +- .../eligibility/il_isbe_income_eligible.yaml | 44 +-- ...l_isbe_was_teen_parent_at_first_birth.yaml | 310 ++++++++++++++++++ .../priority/il_pi_lower_priority_score.yaml | 2 +- .../eligibility/il_isbe_income_eligible.py | 18 +- .../il_isbe_was_teen_parent_at_first_birth.py | 27 +- .../priority/il_pi_lower_priority_score.py | 4 +- .../is_non_english_speaking_home.py | 3 +- ...ent_has_less_than_high_school_education.py | 5 +- .../person/has_developmental_delay.py | 1 + 13 files changed, 386 insertions(+), 69 deletions(-) create mode 100644 policyengine_us/parameters/gov/states/il/isbe/age_threshold/teen_parent.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/il/isbe/eligibility/il_isbe_was_teen_parent_at_first_birth.yaml diff --git a/policyengine_us/parameters/gov/states/il/isbe/age_threshold/teen_parent.yaml b/policyengine_us/parameters/gov/states/il/isbe/age_threshold/teen_parent.yaml new file mode 100644 index 00000000000..1f6053d636a --- /dev/null +++ b/policyengine_us/parameters/gov/states/il/isbe/age_threshold/teen_parent.yaml @@ -0,0 +1,15 @@ +description: Illinois sets this age threshold for the teen parent risk factor under the Illinois State Board of Education early childhood programs. +values: + 2015-01-01: 20 + +metadata: + unit: year + period: year + label: Illinois ISBE teen parent age threshold + reference: + # ISBE lists "teen parent" as a risk factor but does not define the age threshold. + # Using IDHS definition of teen parent as "under age 20". + - title: ISBE PFAE Eligibility Form Section 2 (25-point factors) + href: https://www.isbe.net/Documents/pdg-eg-grant-enrollment-form.pdf#page=2 + - title: IDHS Teen Parent Services Program (under age 20) + href: https://www.dhs.state.il.us/Page.aspx?item=32189 diff --git a/policyengine_us/parameters/gov/states/il/isbe/income/countable_sources.yaml b/policyengine_us/parameters/gov/states/il/isbe/income/countable_sources.yaml index 794e73131f2..7d664ce4c03 100644 --- a/policyengine_us/parameters/gov/states/il/isbe/income/countable_sources.yaml +++ b/policyengine_us/parameters/gov/states/il/isbe/income/countable_sources.yaml @@ -1,4 +1,4 @@ -description: Illinois uses these income sources for ISBE early childhood programs. +description: Illinois includes these income sources for countable income under the Illinois State Board of Education early childhood programs. values: 2015-01-01: # Earned income diff --git a/policyengine_us/parameters/gov/states/il/isbe/income/income_limit_rate.yaml b/policyengine_us/parameters/gov/states/il/isbe/income/income_limit_rate.yaml index 7de427befc7..b5434a4ae37 100644 --- a/policyengine_us/parameters/gov/states/il/isbe/income/income_limit_rate.yaml +++ b/policyengine_us/parameters/gov/states/il/isbe/income/income_limit_rate.yaml @@ -1,13 +1,13 @@ -description: Illinois uses this share of the federal poverty guideline as the income limit for ISBE early childhood programs. +description: Illinois uses this share of the federal poverty level as the income limit under the Illinois State Board of Education early childhood programs. values: 2015-01-01: 4 metadata: unit: /1 period: year - label: Illinois ISBE income limit as share of FPL + label: Illinois ISBE income limit FPL rate reference: - - title: CECIDS Methodology - href: https://cecids.org/methodology/ - - title: 23 Ill. Adm. Code 235.10 - href: http://ilrules.elaws.us/iac/t23_pt235_sec.235.10 + - title: 105 ILCS 5/2-3.71(a)(4.5) - Preschool program + href: https://law.onecle.com/illinois/105ilcs5/2-3.71.html + - title: ISBE Preschool for All Implementation Manual + href: https://www.isbe.net/Documents/Preschool_for_All_Implementation_Manual.pdf#page=7 diff --git a/policyengine_us/parameters/gov/states/il/isbe/pi/benefit/amount.yaml b/policyengine_us/parameters/gov/states/il/isbe/pi/benefit/amount.yaml index f6530d3b43a..6d1ff33cb93 100644 --- a/policyengine_us/parameters/gov/states/il/isbe/pi/benefit/amount.yaml +++ b/policyengine_us/parameters/gov/states/il/isbe/pi/benefit/amount.yaml @@ -1,12 +1,16 @@ -description: Illinois provides this amount per child under the Prevention Initiative program. +description: Illinois provides this amount per child under the Prevention Initiative program (center-based). values: - # FY2025: $6.85M total / 512 children = $13,378.91, rounded to $13,379 + # FY2024 Center-Based: $9.39M total / 702 children = $13,383 + 2024-01-01: 13_383 + # FY2025: $6.85M total / 512 children = $13,379 2025-01-01: 13_379 metadata: unit: currency-USD period: year - label: Illinois PI per-child funding amount + label: Illinois PI per-child funding amount (center-based) reference: - - title: Gov. Pritzker Announces 5,150 New Preschool Seats Through Smart Start Initiative (FY2025) + - title: Gov. Pritzker Smart Start FY2024 Press Release ($9.39M / 702 children center-based) + href: https://www.illinois.gov/news/press-release.29519.html + - title: Gov. Pritzker Smart Start FY2025 Press Release ($6.85M / 512 children) href: https://gov-pritzker-newsroom.prezly.com/gov-pritzker-announces-5150-new-preschool-seats-through-smart-start-initiative diff --git a/policyengine_us/tests/policy/baseline/gov/states/il/isbe/eligibility/il_isbe_income_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/il/isbe/eligibility/il_isbe_income_eligible.yaml index 378a753ed01..6dc5a2af696 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/il/isbe/eligibility/il_isbe_income_eligible.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/il/isbe/eligibility/il_isbe_income_eligible.yaml @@ -1,43 +1,15 @@ -- name: Family income below 400% FPL - eligible +- name: Case 1, income well below 400% FPL. period: 2024 input: - people: - person1: - age: 30 - employment_income: 80_000 # Below 400% FPL for family of 2 - person2: - age: 1 - households: - household: - members: [person1, person2] - state_code: IL - spm_units: - spm_unit: - members: [person1, person2] - tax_units: - tax_unit: - members: [person1, person2] + state_code: IL + employment_income: 20_000 output: - il_isbe_income_eligible: [true, true] + il_isbe_income_eligible: true -- name: Family income above 400% FPL - not eligible +- name: Case 2, income above 400% FPL. period: 2024 input: - people: - person1: - age: 30 - employment_income: 150_000 # Above 400% FPL for family of 2 - person2: - age: 1 - households: - household: - members: [person1, person2] - state_code: IL - spm_units: - spm_unit: - members: [person1, person2] - tax_units: - tax_unit: - members: [person1, person2] + state_code: IL + employment_income: 150_000 output: - il_isbe_income_eligible: [false, false] + il_isbe_income_eligible: false diff --git a/policyengine_us/tests/policy/baseline/gov/states/il/isbe/eligibility/il_isbe_was_teen_parent_at_first_birth.yaml b/policyengine_us/tests/policy/baseline/gov/states/il/isbe/eligibility/il_isbe_was_teen_parent_at_first_birth.yaml new file mode 100644 index 00000000000..db6e0eb8bd6 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/il/isbe/eligibility/il_isbe_was_teen_parent_at_first_birth.yaml @@ -0,0 +1,310 @@ +# Edge case tests for il_isbe_was_teen_parent_at_first_birth +# Tests if parent was under age 20 when their oldest child was born +# Formula: has_children & (head_age - oldest_child_age < 20) +# Threshold: teen_parent_age_threshold = 20 + +- name: Case 1, parent was teen at birth. + period: 2024 + input: + people: + person1: + age: 35 + is_tax_unit_head: true + person2: + age: 17 + households: + household: + members: [person1, person2] + state_code: IL + spm_units: + spm_unit: + members: [person1, person2] + tax_units: + tax_unit: + members: [person1, person2] + output: + # Parent age 35, oldest child age 17 + # Age at first birth: 35 - 17 = 18 + # 18 < 20 = TRUE (was teen parent) + il_isbe_was_teen_parent_at_first_birth: true + +- name: Case 2, parent was NOT teen at birth. + period: 2024 + input: + people: + person1: + age: 45 + is_tax_unit_head: true + person2: + age: 17 + households: + household: + members: [person1, person2] + state_code: IL + spm_units: + spm_unit: + members: [person1, person2] + tax_units: + tax_unit: + members: [person1, person2] + output: + # Parent age 45, oldest child age 17 + # Age at first birth: 45 - 17 = 28 + # 28 < 20 = FALSE (was not teen parent) + il_isbe_was_teen_parent_at_first_birth: false + +- name: Case 3, boundary exactly 19 at birth should be TRUE. + period: 2024 + input: + people: + person1: + age: 36 + is_tax_unit_head: true + person2: + age: 17 + households: + household: + members: [person1, person2] + state_code: IL + spm_units: + spm_unit: + members: [person1, person2] + tax_units: + tax_unit: + members: [person1, person2] + output: + # Parent age 36, oldest child age 17 + # Age at first birth: 36 - 17 = 19 + # 19 < 20 = TRUE (was teen parent) + il_isbe_was_teen_parent_at_first_birth: true + +- name: Case 4, boundary exactly 20 at birth should be FALSE. + period: 2024 + input: + people: + person1: + age: 37 + is_tax_unit_head: true + person2: + age: 17 + households: + household: + members: [person1, person2] + state_code: IL + spm_units: + spm_unit: + members: [person1, person2] + tax_units: + tax_unit: + members: [person1, person2] + output: + # Parent age 37, oldest child age 17 + # Age at first birth: 37 - 17 = 20 + # 20 < 20 = FALSE (20 is NOT less than 20) + il_isbe_was_teen_parent_at_first_birth: false + +- name: Case 5, no children in household. + period: 2024 + input: + people: + person1: + age: 30 + is_tax_unit_head: true + households: + household: + members: [person1] + state_code: IL + spm_units: + spm_unit: + members: [person1] + tax_units: + tax_unit: + members: [person1] + output: + # No children (is_child requires age < 18) + # has_children = FALSE + # Result: FALSE regardless of age + il_isbe_was_teen_parent_at_first_birth: false + +- name: Case 6, multiple children uses oldest child age. + period: 2024 + input: + people: + person1: + age: 35 + is_tax_unit_head: true + person2: + age: 5 + person3: + age: 17 + households: + household: + members: [person1, person2, person3] + state_code: IL + spm_units: + spm_unit: + members: [person1, person2, person3] + tax_units: + tax_unit: + members: [person1, person2, person3] + output: + # Parent age 35, children ages 5 and 17 + # Oldest child is 17 (rank 0 with -age ordering) + # Age at first birth: 35 - 17 = 18 + # 18 < 20 = TRUE + il_isbe_was_teen_parent_at_first_birth: true + +- name: Case 7, all adults no children under 18. + period: 2024 + input: + people: + person1: + age: 40 + is_tax_unit_head: true + person2: + age: 18 + households: + household: + members: [person1, person2] + state_code: IL + spm_units: + spm_unit: + members: [person1, person2] + tax_units: + tax_unit: + members: [person1, person2] + output: + # Person2 is 18, is_child requires age < 18 + # No qualifying children + # has_children = FALSE + il_isbe_was_teen_parent_at_first_birth: false + +- name: Case 8, newborn with parent exactly 20 at birth. + period: 2024 + input: + people: + person1: + age: 20 + is_tax_unit_head: true + person2: + age: 0 + households: + household: + members: [person1, person2] + state_code: IL + spm_units: + spm_unit: + members: [person1, person2] + tax_units: + tax_unit: + members: [person1, person2] + output: + # Parent age 20, child age 0 + # Age at first birth: 20 - 0 = 20 + # 20 < 20 = FALSE (exactly at threshold) + il_isbe_was_teen_parent_at_first_birth: false + +- name: Case 9, young parent with young child was teen. + period: 2024 + input: + people: + person1: + age: 21 + is_tax_unit_head: true + person2: + age: 2 + households: + household: + members: [person1, person2] + state_code: IL + spm_units: + spm_unit: + members: [person1, person2] + tax_units: + tax_unit: + members: [person1, person2] + output: + # Parent age 21, child age 2 + # Age at first birth: 21 - 2 = 19 + # 19 < 20 = TRUE + il_isbe_was_teen_parent_at_first_birth: true + +- name: Case 10, newborn with parent exactly 19 at birth. + period: 2024 + input: + people: + person1: + age: 19 + is_tax_unit_head: true + person2: + age: 0 + households: + household: + members: [person1, person2] + state_code: IL + spm_units: + spm_unit: + members: [person1, person2] + tax_units: + tax_unit: + members: [person1, person2] + output: + # Parent age 19, child age 0 + # Age at first birth: 19 - 0 = 19 + # 19 < 20 = TRUE + il_isbe_was_teen_parent_at_first_birth: true + +- name: Case 11, three children uses oldest. + period: 2024 + input: + people: + person1: + age: 40 + is_tax_unit_head: true + person2: + age: 3 + person3: + age: 10 + person4: + age: 16 + households: + household: + members: [person1, person2, person3, person4] + state_code: IL + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + tax_units: + tax_unit: + members: [person1, person2, person3, person4] + output: + # Parent age 40, children ages 3, 10, 16 + # Oldest child is 16 + # Age at first birth: 40 - 16 = 24 + # 24 < 20 = FALSE + il_isbe_was_teen_parent_at_first_birth: false + +- name: Case 12, boundary 21 at birth should be FALSE. + period: 2024 + input: + people: + person1: + age: 38 + is_tax_unit_head: true + person2: + age: 17 + households: + household: + members: [person1, person2] + state_code: IL + spm_units: + spm_unit: + members: [person1, person2] + tax_units: + tax_unit: + members: [person1, person2] + output: + # Parent age 38, oldest child age 17 + # Age at first birth: 38 - 17 = 21 + # 21 < 20 = FALSE + il_isbe_was_teen_parent_at_first_birth: false diff --git a/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/priority/il_pi_lower_priority_score.yaml b/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/priority/il_pi_lower_priority_score.yaml index 6f9c002a8e3..5caebe1330b 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/priority/il_pi_lower_priority_score.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/priority/il_pi_lower_priority_score.yaml @@ -89,11 +89,11 @@ household: members: [person1, person2, person3] state_code: IL - il_isbe_was_teen_parent_at_first_birth: true spm_units: spm_unit: members: [person1, person2, person3] il_tanf: 0 + il_isbe_was_teen_parent_at_first_birth: true tax_units: tax_unit: members: [person1, person2, person3] diff --git a/policyengine_us/variables/gov/states/il/isbe/eligibility/il_isbe_income_eligible.py b/policyengine_us/variables/gov/states/il/isbe/eligibility/il_isbe_income_eligible.py index 9024cd75a2b..c96905fcf8f 100644 --- a/policyengine_us/variables/gov/states/il/isbe/eligibility/il_isbe_income_eligible.py +++ b/policyengine_us/variables/gov/states/il/isbe/eligibility/il_isbe_income_eligible.py @@ -4,20 +4,22 @@ class il_isbe_income_eligible(Variable): value_type = bool entity = Person - label = "Meets income requirements for Illinois ISBE programs" + label = ( + "Meets income requirements for Illinois ISBE early childhood programs" + ) definition_period = YEAR - documentation = ( - "Shared income eligibility check for Illinois State Board of Education " - "early childhood programs (PI, PFA, PFAE). Income must be at or below " - "400% of the Federal Poverty Level." + reference = ( + "https://www.isbe.net/pages/preschool-for-all.aspx", + "https://law.onecle.com/illinois/105ilcs5/2-3.71.html", ) - reference = "https://cecids.org/methodology/" defined_for = StateCode.IL def formula(person, period, parameters): - spm_unit = person.spm_unit - # Income must be at or below 400% FPL for ISBE programs. + # Income must be at or below 400% FPL for program eligibility. + # 105 ILCS 5/2-3.71 establishes "4 times the poverty guidelines" as the + # maximum income threshold for preschool program eligibility. p = parameters(period).gov.states.il.isbe.income + spm_unit = person.spm_unit fpg = spm_unit("spm_unit_fpg", period) income = spm_unit("il_isbe_countable_income", period) threshold = fpg * p.income_limit_rate diff --git a/policyengine_us/variables/gov/states/il/isbe/eligibility/il_isbe_was_teen_parent_at_first_birth.py b/policyengine_us/variables/gov/states/il/isbe/eligibility/il_isbe_was_teen_parent_at_first_birth.py index 52bf0571c53..16fbaf267a1 100644 --- a/policyengine_us/variables/gov/states/il/isbe/eligibility/il_isbe_was_teen_parent_at_first_birth.py +++ b/policyengine_us/variables/gov/states/il/isbe/eligibility/il_isbe_was_teen_parent_at_first_birth.py @@ -3,15 +3,30 @@ class il_isbe_was_teen_parent_at_first_birth(Variable): value_type = bool - entity = Household + entity = SPMUnit label = "Parent was a teen at birth of first child" definition_period = YEAR - documentation = ( - "Whether any parent in the household was under age 20 when their " - "first child was born. This is a risk factor for Illinois ISBE " - "early childhood programs." - ) reference = ( "https://www.isbe.net/Documents/pdg-eg-grant-enrollment-form.pdf" ) defined_for = StateCode.IL + + def formula(spm_unit, period, parameters): + person = spm_unit.members + age = person("age", period.this_year) + is_child = person("is_child", period.this_year) + + # Find oldest child using get_rank (rank 0 = oldest when using -age) + is_oldest_child = person.get_rank(spm_unit, -age, is_child) == 0 + + # Get ages + head_age = spm_unit.max(age * person("is_tax_unit_head", period)) + oldest_child_age = spm_unit.max(age * is_oldest_child) + + # Calculate parent's age at first birth + age_at_first_birth = head_age - oldest_child_age + + # Check if parent was under threshold age at birth and has children + p = parameters(period).gov.states.il.isbe.age_threshold + has_children = spm_unit.any(is_child) + return has_children & (age_at_first_birth < p.teen_parent) diff --git a/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_lower_priority_score.py b/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_lower_priority_score.py index 8295e17f0c3..9c9d313e25a 100644 --- a/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_lower_priority_score.py +++ b/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_lower_priority_score.py @@ -16,9 +16,9 @@ def formula(person, period, parameters): spm_unit = person.spm_unit # Lower priority factors (10 pts each): - # Factor 33: Teen parent at birth of first child (Household-level variable) + # Factor 33: Teen parent at birth of first child (SPMUnit-level variable) # Parent was under 20 when first child was born - is_teen_parent_family = household( + is_teen_parent_family = spm_unit( "il_isbe_was_teen_parent_at_first_birth", period ) # Factor 35: Parent/Caregiver is single parent diff --git a/policyengine_us/variables/household/demographic/geographic/is_non_english_speaking_home.py b/policyengine_us/variables/household/demographic/geographic/is_non_english_speaking_home.py index ea77a8fde6a..b6259d13d0e 100644 --- a/policyengine_us/variables/household/demographic/geographic/is_non_english_speaking_home.py +++ b/policyengine_us/variables/household/demographic/geographic/is_non_english_speaking_home.py @@ -4,5 +4,6 @@ class is_non_english_speaking_home(Variable): value_type = bool entity = Household - label = "Primary language spoken at home is not English" + label = "Non-English speaking home" definition_period = YEAR + documentation = "Whether the household's primary language is not English" diff --git a/policyengine_us/variables/household/demographic/household/parent_has_less_than_high_school_education.py b/policyengine_us/variables/household/demographic/household/parent_has_less_than_high_school_education.py index be2f7d8ce68..62d34ed1484 100644 --- a/policyengine_us/variables/household/demographic/household/parent_has_less_than_high_school_education.py +++ b/policyengine_us/variables/household/demographic/household/parent_has_less_than_high_school_education.py @@ -6,7 +6,4 @@ class parent_has_less_than_high_school_education(Variable): entity = Household label = "Parent has less than high school education" definition_period = YEAR - documentation = ( - "Whether any parent or guardian in the household has less than " - "a high school diploma or equivalent" - ) + documentation = "Whether any parent or guardian in the household has less than a high school diploma or equivalent" diff --git a/policyengine_us/variables/household/demographic/person/has_developmental_delay.py b/policyengine_us/variables/household/demographic/person/has_developmental_delay.py index a88e6c5522e..55a719dab6c 100644 --- a/policyengine_us/variables/household/demographic/person/has_developmental_delay.py +++ b/policyengine_us/variables/household/demographic/person/has_developmental_delay.py @@ -6,3 +6,4 @@ class has_developmental_delay(Variable): entity = Person label = "Has a developmental delay" definition_period = YEAR + documentation = "Whether the child has a screening-indicated developmental delay or disability" From d842e8194d4a2e912257bf14cc9d201efdddfe8a Mon Sep 17 00:00:00 2001 From: Ziming Date: Fri, 19 Dec 2025 12:07:22 -0500 Subject: [PATCH 08/11] uv --- uv.lock | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/uv.lock b/uv.lock index f260826736c..16b92ccd8de 100644 --- a/uv.lock +++ b/uv.lock @@ -1085,7 +1085,7 @@ wheels = [ [[package]] name = "nbclient" -version = "0.10.2" +version = "0.10.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "jupyter-client" }, @@ -1093,9 +1093,9 @@ dependencies = [ { name = "nbformat" }, { name = "traitlets" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/87/66/7ffd18d58eae90d5721f9f39212327695b749e23ad44b3881744eaf4d9e8/nbclient-0.10.2.tar.gz", hash = "sha256:90b7fc6b810630db87a6d0c2250b1f0ab4cf4d3c27a299b0cde78a4ed3fd9193", size = 62424, upload-time = "2024-12-19T10:32:27.164Z" } +sdist = { url = "https://files.pythonhosted.org/packages/8d/f3/1f6cf2ede4b026bc5f0b424cb41adf22f9c804e90a4dbd4fdb42291a35d5/nbclient-0.10.3.tar.gz", hash = "sha256:0baf171ee246e3bb2391da0635e719f27dc77d99aef59e0b04dcb935ee04c575", size = 62564, upload-time = "2025-12-19T15:50:09.331Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/34/6d/e7fa07f03a4a7b221d94b4d586edb754a9b0dc3c9e2c93353e9fa4e0d117/nbclient-0.10.2-py3-none-any.whl", hash = "sha256:4ffee11e788b4a27fabeb7955547e4318a5298f34342a4bfd01f2e1faaeadc3d", size = 25434, upload-time = "2024-12-19T10:32:24.139Z" }, + { url = "https://files.pythonhosted.org/packages/b2/77/0c73678f5260501a271fd7342bee5d639440f2e9e07d590f1100a056d87c/nbclient-0.10.3-py3-none-any.whl", hash = "sha256:39e9bd403504dd2484dd0fd25235bb6a683ce8cd9873356e40d880696adc9e35", size = 25473, upload-time = "2025-12-19T15:50:07.671Z" }, ] [[package]] @@ -1519,7 +1519,7 @@ wheels = [ [[package]] name = "policyengine-us" -version = "1.465.3" +version = "1.467.0" source = { editable = "." } dependencies = [ { name = "microdf-python" }, @@ -2317,15 +2317,15 @@ wheels = [ [[package]] name = "typer-slim" -version = "0.20.0" +version = "0.20.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "click" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/8e/45/81b94a52caed434b94da65729c03ad0fb7665fab0f7db9ee54c94e541403/typer_slim-0.20.0.tar.gz", hash = "sha256:9fc6607b3c6c20f5c33ea9590cbeb17848667c51feee27d9e314a579ab07d1a3", size = 106561, upload-time = "2025-10-20T17:03:46.642Z" } +sdist = { url = "https://files.pythonhosted.org/packages/3f/3d/6a4ec47010e8de34dade20c8e7bce90502b173f62a6b41619523a3fcf562/typer_slim-0.20.1.tar.gz", hash = "sha256:bb9e4f7e6dc31551c8a201383df322b81b0ce37239a5ead302598a2ebb6f7c9c", size = 106113, upload-time = "2025-12-19T16:48:54.206Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/5e/dd/5cbf31f402f1cc0ab087c94d4669cfa55bd1e818688b910631e131d74e75/typer_slim-0.20.0-py3-none-any.whl", hash = "sha256:f42a9b7571a12b97dddf364745d29f12221865acef7a2680065f9bb29c7dc89d", size = 47087, upload-time = "2025-10-20T17:03:44.546Z" }, + { url = "https://files.pythonhosted.org/packages/d8/f9/a273c8b57c69ac1b90509ebda204972265fdc978fbbecc25980786f8c038/typer_slim-0.20.1-py3-none-any.whl", hash = "sha256:8e89c5dbaffe87a4f86f4c7a9e2f7059b5b68c66f558f298969d42ce34f10122", size = 47440, upload-time = "2025-12-19T16:48:52.678Z" }, ] [[package]] From b0cbb045d525aa99835b67ed4657abf778feac82 Mon Sep 17 00:00:00 2001 From: Ziming Date: Fri, 19 Dec 2025 12:15:10 -0500 Subject: [PATCH 09/11] delete unused filles --- .../variables/household/demographic/person/has_iep.py | 8 -------- .../demographic/person/was_teen_parent_at_first_birth.py | 9 --------- 2 files changed, 17 deletions(-) delete mode 100644 policyengine_us/variables/household/demographic/person/has_iep.py delete mode 100644 policyengine_us/variables/household/demographic/person/was_teen_parent_at_first_birth.py diff --git a/policyengine_us/variables/household/demographic/person/has_iep.py b/policyengine_us/variables/household/demographic/person/has_iep.py deleted file mode 100644 index 791fd6b4720..00000000000 --- a/policyengine_us/variables/household/demographic/person/has_iep.py +++ /dev/null @@ -1,8 +0,0 @@ -from policyengine_us.model_api import * - - -class has_iep(Variable): - value_type = bool - entity = Person - label = "Has an Individualized Education Program (IEP)" - definition_period = YEAR diff --git a/policyengine_us/variables/household/demographic/person/was_teen_parent_at_first_birth.py b/policyengine_us/variables/household/demographic/person/was_teen_parent_at_first_birth.py deleted file mode 100644 index 927f0f4cfec..00000000000 --- a/policyengine_us/variables/household/demographic/person/was_teen_parent_at_first_birth.py +++ /dev/null @@ -1,9 +0,0 @@ -from policyengine_us.model_api import * - - -class was_teen_parent_at_first_birth(Variable): - value_type = bool - entity = Person - label = "Was a teen parent at birth of first child" - definition_period = YEAR - documentation = "Whether the parent was a teenager (under 20) when their first child was born" From e2732bfbbc5d1b3190b82c3858978ce23913ded1 Mon Sep 17 00:00:00 2001 From: Ziming Date: Fri, 19 Dec 2025 20:51:49 -0500 Subject: [PATCH 10/11] adjustment --- .../priority/geriatric_pregnancy_age.yaml | 3 +- .../il_pi_has_developmental_delay.yaml | 16 ++++++++ .../il_pi_has_geriatric_pregnancy.yaml | 32 ++++++++++++++-- .../il_pi_is_young_parent_family.yaml | 37 +++++++++++++++---- .../gov/states/il/isbe/pi/integration.yaml | 27 ++++++++++++++ .../priority/il_pi_has_developmental_delay.py | 1 + .../priority/il_pi_has_geriatric_pregnancy.py | 1 + .../priority/il_pi_is_young_parent_family.py | 19 ++++------ .../priority/il_pi_other_priority_score.py | 4 +- 9 files changed, 114 insertions(+), 26 deletions(-) diff --git a/policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/priority/geriatric_pregnancy_age.yaml b/policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/priority/geriatric_pregnancy_age.yaml index 29d044ed202..14b5ca7de0a 100644 --- a/policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/priority/geriatric_pregnancy_age.yaml +++ b/policyengine_us/parameters/gov/states/il/isbe/pi/eligibility/priority/geriatric_pregnancy_age.yaml @@ -1,9 +1,10 @@ description: Minimum age for geriatric pregnancy factor in Illinois PI metadata: unit: year + period: year label: Geriatric pregnancy age threshold reference: - title: Prevention Initiative Eligibility Form - Factor 28 href: https://www.isbe.net/Documents/Prevention-Initiative-Eligibility-Form.pdf#page=3 values: - 0000-01-01: 40 + 2015-01-01: 40 diff --git a/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/priority/il_pi_has_developmental_delay.yaml b/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/priority/il_pi_has_developmental_delay.yaml index 8810321c851..1e8d6f5e290 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/priority/il_pi_has_developmental_delay.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/priority/il_pi_has_developmental_delay.yaml @@ -6,6 +6,10 @@ age: 30 person2: age: 1 + households: + household: + members: [person1, person2] + state_code: IL spm_units: spm_unit: members: [person1, person2] @@ -21,6 +25,10 @@ person2: age: 1 has_developmental_delay: true + households: + household: + members: [person1, person2] + state_code: IL spm_units: spm_unit: members: [person1, person2] @@ -36,6 +44,10 @@ is_disabled: true person2: age: 1 + households: + household: + members: [person1, person2] + state_code: IL spm_units: spm_unit: members: [person1, person2] @@ -52,6 +64,10 @@ person2: age: 1 has_developmental_delay: true + households: + household: + members: [person1, person2] + state_code: IL spm_units: spm_unit: members: [person1, person2] diff --git a/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/priority/il_pi_has_geriatric_pregnancy.yaml b/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/priority/il_pi_has_geriatric_pregnancy.yaml index 91f29d45ed7..557e75bded6 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/priority/il_pi_has_geriatric_pregnancy.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/priority/il_pi_has_geriatric_pregnancy.yaml @@ -4,9 +4,15 @@ people: person1: age: 42 + person2: + age: 1 + households: + household: + members: [person1, person2] + state_code: IL spm_units: spm_unit: - members: [person1] + members: [person1, person2] output: il_pi_has_geriatric_pregnancy: false @@ -17,9 +23,15 @@ person1: age: 35 is_pregnant: true + person2: + age: 1 + households: + household: + members: [person1, person2] + state_code: IL spm_units: spm_unit: - members: [person1] + members: [person1, person2] output: il_pi_has_geriatric_pregnancy: false @@ -30,9 +42,15 @@ person1: age: 40 is_pregnant: true + person2: + age: 1 + households: + household: + members: [person1, person2] + state_code: IL spm_units: spm_unit: - members: [person1] + members: [person1, person2] output: il_pi_has_geriatric_pregnancy: true @@ -43,8 +61,14 @@ person1: age: 45 is_pregnant: true + person2: + age: 1 + households: + household: + members: [person1, person2] + state_code: IL spm_units: spm_unit: - members: [person1] + members: [person1, person2] output: il_pi_has_geriatric_pregnancy: true diff --git a/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/priority/il_pi_is_young_parent_family.yaml b/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/priority/il_pi_is_young_parent_family.yaml index 52871379e45..db3e7f94e1a 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/priority/il_pi_is_young_parent_family.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/eligibility/priority/il_pi_is_young_parent_family.yaml @@ -1,4 +1,4 @@ -- name: Young parent family (parent age 20) +- name: Case 1, young parent family with parent age 20. period: 2024 input: people: @@ -18,10 +18,9 @@ tax_unit: members: [person1, person2] output: - # Both get true because young parent status applies to all family members - il_pi_is_young_parent_family: [true, true] + il_pi_is_young_parent_family: true -- name: Mixed age parents (30 and 20) - not eligible +- name: Case 2, mixed age parents (30 and 20) eligible if any parent is young. period: 2024 input: people: @@ -44,10 +43,10 @@ tax_unit: members: [person1, person2, person3] output: - # Not eligible because one parent is > 21 - il_pi_is_young_parent_family: [false, false, false] + # Eligible because one parent is 20 (<=21) + il_pi_is_young_parent_family: true -- name: Older parent (age 25) - not eligible +- name: Case 3, older parent age 25 not eligible. period: 2024 input: people: @@ -67,4 +66,26 @@ tax_unit: members: [person1, person2] output: - il_pi_is_young_parent_family: [false, false] + il_pi_is_young_parent_family: false + +- name: Case 4, parent exactly 21 is eligible. + period: 2024 + input: + people: + person1: + age: 21 + is_parent: true + person2: + age: 1 + households: + household: + members: [person1, person2] + state_code: IL + spm_units: + spm_unit: + members: [person1, person2] + tax_units: + tax_unit: + members: [person1, person2] + output: + il_pi_is_young_parent_family: true diff --git a/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/integration.yaml b/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/integration.yaml index fe77064c21f..d1cc99554a0 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/integration.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pi/integration.yaml @@ -158,3 +158,30 @@ # Foster care (50) + single parent (10) = 60 pts for child il_pi_priority_score: [0, 60] il_pi_eligible: [false, true] + +- name: Case 7, 45 points ineligible boundary case. + period: 2024 + input: + people: + person1: + age: 21 + employment_income: 25_000 + is_parent: true + person2: + age: 1 + households: + household: + members: [person1, person2] + state_code: IL + spm_units: + spm_unit: + members: [person1, person2] + il_tanf: 0 + tax_units: + tax_unit: + members: [person1, person2] + output: + il_pi_demographic_eligible: [false, true] + # Young parent age 21 (25) + single parent (10) + poverty (10) = 45 pts (below 50 threshold) + il_pi_priority_score: [0, 45] + il_pi_eligible: [false, false] diff --git a/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_has_developmental_delay.py b/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_has_developmental_delay.py index 60b22b461e2..0bf4b5f3962 100644 --- a/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_has_developmental_delay.py +++ b/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_has_developmental_delay.py @@ -7,6 +7,7 @@ class il_pi_has_developmental_delay(Variable): label = "SPM unit has developmental delay or disability for Illinois PI" definition_period = YEAR reference = "https://www.isbe.net/Documents/Prevention-Initiative-Eligibility-Form.pdf#page=2" + defined_for = StateCode.IL def formula(spm_unit, period, parameters): # Factor 18: Member of household has developmental delay or disability diff --git a/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_has_geriatric_pregnancy.py b/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_has_geriatric_pregnancy.py index 38260e018a3..f8164b318e7 100644 --- a/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_has_geriatric_pregnancy.py +++ b/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_has_geriatric_pregnancy.py @@ -7,6 +7,7 @@ class il_pi_has_geriatric_pregnancy(Variable): label = "Household has geriatric pregnancy for Illinois PI" definition_period = YEAR reference = "https://www.isbe.net/Documents/Prevention-Initiative-Eligibility-Form.pdf#page=3" + defined_for = StateCode.IL def formula(spm_unit, period, parameters): # Factor 28: Pregnant woman age 40 or over diff --git a/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_is_young_parent_family.py b/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_is_young_parent_family.py index c0a6406a983..a067477d821 100644 --- a/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_is_young_parent_family.py +++ b/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_is_young_parent_family.py @@ -3,7 +3,7 @@ class il_pi_is_young_parent_family(Variable): value_type = bool - entity = Person + entity = SPMUnit label = "Young parent family for Illinois PI (Factor 11)" definition_period = YEAR reference = ( @@ -11,16 +11,11 @@ class il_pi_is_young_parent_family(Variable): ) defined_for = StateCode.IL - def formula(person, period, parameters): + def formula(spm_unit, period, parameters): # Factor 11 (25 pts): Parent is currently age 21 years or younger. p = parameters(period).gov.states.il.isbe.pi.eligibility.age_threshold - age = person("age", period) - is_parent = person("is_parent", period) - young_parent_max_age = p.young_parent - is_young_parent = is_parent & (age <= young_parent_max_age) - is_old_parent = is_parent & (age > young_parent_max_age) - spm_unit = person.spm_unit - has_young_parent = spm_unit.any(is_young_parent) - has_old_parent = spm_unit.any(is_old_parent) - # Only eligible if there's at least one young parent and no old parents. - return has_young_parent & ~has_old_parent + age = spm_unit.members("age", period) + is_parent = spm_unit.members("is_parent", period) + is_young = age <= p.young_parent + # Eligible if any parent is 21 or younger. + return spm_unit.any(is_parent & is_young) diff --git a/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_other_priority_score.py b/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_other_priority_score.py index 408e92d3058..b28c5f76e10 100644 --- a/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_other_priority_score.py +++ b/policyengine_us/variables/gov/states/il/isbe/pi/eligibility/priority/il_pi_other_priority_score.py @@ -29,7 +29,9 @@ def formula(person, period, parameters): is_active_duty_military = person("military_basic_pay", period) > 0 is_military_family = spm_unit.any(is_active_duty_military) # Factor 11: Parent is currently age 21 or younger - is_young_parent_family = person("il_pi_is_young_parent_family", period) + is_young_parent_family = spm_unit( + "il_pi_is_young_parent_family", period + ) # Factor 18: Member of household has developmental delay or disability has_developmental_delay = spm_unit( "il_pi_has_developmental_delay", period From ab00968d7b4ad56fd532fa5946247e7d137a6fed Mon Sep 17 00:00:00 2001 From: Ziming Date: Fri, 19 Dec 2025 20:52:41 -0500 Subject: [PATCH 11/11] uv --- uv.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/uv.lock b/uv.lock index 7511808d966..e4c36b69aed 100644 --- a/uv.lock +++ b/uv.lock @@ -1535,7 +1535,7 @@ wheels = [ [[package]] name = "policyengine-us" -version = "1.467.0" +version = "1.469.0" source = { editable = "." } dependencies = [ { name = "microdf-python" },