diff --git a/changelog_entry.yaml b/changelog_entry.yaml index e69de29bb2d..7602c3c4dbd 100644 --- a/changelog_entry.yaml +++ b/changelog_entry.yaml @@ -0,0 +1,5 @@ +- bump: minor + changes: + added: + - Illinois Preschool For All (PFA) and Preschool For All Expansion (PFAE) programs with age (3-5), income (400% FPL), and weighted priority factor eligibility. + - New input variables for IEP status, developmental delay, non-English speaking home, parent education level, born outside US, and no prior formal early learning. 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 new file mode 100644 index 00000000000..7d664ce4c03 --- /dev/null +++ b/policyengine_us/parameters/gov/states/il/isbe/income/countable_sources.yaml @@ -0,0 +1,28 @@ +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 + - 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 ISBE countable income sources + reference: + - title: ISBE Household and Income Form (69-72) + href: https://www.isbe.net/Documents/69-72_hshld_income.pdf 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 new file mode 100644 index 00000000000..b5434a4ae37 --- /dev/null +++ b/policyengine_us/parameters/gov/states/il/isbe/income/income_limit_rate.yaml @@ -0,0 +1,13 @@ +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 FPL rate + reference: + - 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/pfa/benefit/amount.yaml b/policyengine_us/parameters/gov/states/il/isbe/pfa/benefit/amount.yaml new file mode 100644 index 00000000000..61a59d8c61c --- /dev/null +++ b/policyengine_us/parameters/gov/states/il/isbe/pfa/benefit/amount.yaml @@ -0,0 +1,15 @@ +description: Illinois provides this amount as per-child funding under the Preschool For All program. +values: + # FY2024: $20.99M total / 5,383 children = $3,900 + # FY2025: $15.63M total / 4,008 children = $3,900 + 2024-01-01: 3_900 + +metadata: + unit: currency-USD + period: year + label: Illinois PFA per-child funding amount + reference: + - title: Gov. Pritzker Smart Start FY2024 Press Release ($20.99M / 5,383 children) + href: https://www.illinois.gov/news/press-release.29519.html + - title: Gov. Pritzker Smart Start FY2025 Press Release ($15.63M / 4,008 children) + 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/pfae/benefit/amount.yaml b/policyengine_us/parameters/gov/states/il/isbe/pfae/benefit/amount.yaml new file mode 100644 index 00000000000..0d9a7199568 --- /dev/null +++ b/policyengine_us/parameters/gov/states/il/isbe/pfae/benefit/amount.yaml @@ -0,0 +1,15 @@ +description: Illinois provides this amount as per-child funding under the Preschool For All Expansion program. +values: + # FY2024: $4.28M total / 503 children = $8,500 + # FY2025: $9.70M total / 1,142 children = $8,500 + 2024-01-01: 8_500 + +metadata: + unit: currency-USD + period: year + label: Illinois PFAE per-child funding amount + reference: + - title: Gov. Pritzker Smart Start FY2024 Press Release ($4.28M / 503 children) + href: https://www.illinois.gov/news/press-release.29519.html + - title: Gov. Pritzker Smart Start FY2025 Press Release ($9.70M / 1,142 children) + 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/pfae/eligibility/age_range.yaml b/policyengine_us/parameters/gov/states/il/isbe/pfae/eligibility/age_range.yaml new file mode 100644 index 00000000000..27bbdff6a9e --- /dev/null +++ b/policyengine_us/parameters/gov/states/il/isbe/pfae/eligibility/age_range.yaml @@ -0,0 +1,26 @@ +description: Illinois limits eligibility to children of this age under the Preschool For All Expansion (PFAE) program. +brackets: + - threshold: + 2015-01-01: 0 + amount: + 2015-01-01: false + - threshold: + 2015-01-01: 3 + amount: + 2015-01-01: true + - threshold: + 2015-01-01: 6 + amount: + 2015-01-01: false + +metadata: + type: single_amount + amount_unit: bool + threshold_unit: year + period: year + label: Illinois PFAE eligible age range + reference: + - title: 23 IAC ยง 235.10 - Definitions (ages 3 to kindergarten enrollment) + href: https://www.law.cornell.edu/regulations/illinois/Ill-Admin-Code-tit-23-SS-235.10 + - title: 105 ILCS 5/10-20.12 - Kindergarten enrollment age (age 5 by Sept 1) + href: https://law.onecle.com/illinois/105ilcs5/10-20.12.html diff --git a/policyengine_us/parameters/gov/states/il/isbe/pfae/eligibility/income/deep_poverty_rate.yaml b/policyengine_us/parameters/gov/states/il/isbe/pfae/eligibility/income/deep_poverty_rate.yaml new file mode 100644 index 00000000000..2c66055d222 --- /dev/null +++ b/policyengine_us/parameters/gov/states/il/isbe/pfae/eligibility/income/deep_poverty_rate.yaml @@ -0,0 +1,10 @@ +description: Illinois uses this share of the federal poverty level as the deep poverty threshold (50-point factor) under the Preschool For All Expansion (PFAE) program. +metadata: + unit: /1 + period: year + label: Illinois PFAE deep poverty FPL rate + reference: + - title: ISBE PDG Enrollment Form (50-point factors) + href: https://www.isbe.net/Documents/pdg-eg-grant-enrollment-form.pdf#page=2 +values: + 2015-01-01: 0.5 diff --git a/policyengine_us/parameters/gov/states/il/isbe/pfae/eligibility/income/low_income_rate.yaml b/policyengine_us/parameters/gov/states/il/isbe/pfae/eligibility/income/low_income_rate.yaml new file mode 100644 index 00000000000..754665d8f31 --- /dev/null +++ b/policyengine_us/parameters/gov/states/il/isbe/pfae/eligibility/income/low_income_rate.yaml @@ -0,0 +1,10 @@ +description: Illinois uses this share of the federal poverty level as the low income threshold (25-point factor) under the Preschool For All Expansion (PFAE) program. +metadata: + unit: /1 + period: year + label: Illinois PFAE low income FPL rate + reference: + - title: ISBE PDG Enrollment Form (25-point factors) + href: https://www.isbe.net/Documents/pdg-eg-grant-enrollment-form.pdf#page=2 +values: + 2015-01-01: 1 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..6dc5a2af696 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/il/isbe/eligibility/il_isbe_income_eligible.yaml @@ -0,0 +1,15 @@ +- name: Case 1, income well below 400% FPL. + period: 2024 + input: + state_code: IL + employment_income: 20_000 + output: + il_isbe_income_eligible: true + +- name: Case 2, income above 400% FPL. + period: 2024 + input: + state_code: IL + employment_income: 150_000 + output: + 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/pfae/eligibility/il_pfae_age_eligible_child.yaml b/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pfae/eligibility/il_pfae_age_eligible_child.yaml new file mode 100644 index 00000000000..31d0c75f6d3 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pfae/eligibility/il_pfae_age_eligible_child.yaml @@ -0,0 +1,39 @@ +- name: Case 1, eligible child age 3. + period: 2024 + input: + age: 3 + state_code: IL + output: + il_pfae_age_eligible_child: true + +- name: Case 2, eligible child age 4. + period: 2024 + input: + age: 4 + state_code: IL + output: + il_pfae_age_eligible_child: true + +- name: Case 3, eligible child age 5. + period: 2024 + input: + age: 5 + state_code: IL + output: + il_pfae_age_eligible_child: true + +- name: Case 4, ineligible child age 2 too young. + period: 2024 + input: + age: 2 + state_code: IL + output: + il_pfae_age_eligible_child: false + +- name: Case 5, ineligible child age 6 too old. + period: 2024 + input: + age: 6 + state_code: IL + output: + il_pfae_age_eligible_child: false diff --git a/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pfae/eligibility/il_pfae_basic_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pfae/eligibility/il_pfae_basic_eligible.yaml new file mode 100644 index 00000000000..a4854ff8237 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pfae/eligibility/il_pfae_basic_eligible.yaml @@ -0,0 +1,26 @@ +- name: Case 1, age and income eligible. + period: 2024 + input: + state_code: IL + age: 4 + employment_income: 20_000 + output: + il_pfae_basic_eligible: true + +- name: Case 2, age eligible but income too high. + period: 2024 + input: + state_code: IL + age: 4 + employment_income: 150_000 + output: + il_pfae_basic_eligible: false + +- name: Case 3, income eligible but age too old. + period: 2024 + input: + state_code: IL + age: 7 + employment_income: 20_000 + output: + il_pfae_basic_eligible: false diff --git a/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pfae/eligibility/il_pfae_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pfae/eligibility/il_pfae_eligible.yaml new file mode 100644 index 00000000000..10d1ac47966 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pfae/eligibility/il_pfae_eligible.yaml @@ -0,0 +1,49 @@ +- name: Case 1, eligible with highest priority factor (IEP). + period: 2024 + input: + state_code: IL + age: 4 + has_individualized_education_program: true + employment_income: 20_000 + output: + il_pfae_eligible: true + +- name: Case 2, eligible with highest priority factor (foster care). + period: 2024 + input: + state_code: IL + age: 3 + is_in_foster_care: true + employment_income: 15_000 + output: + il_pfae_eligible: true + +- name: Case 3, eligible with two secondary priority factors. + period: 2024 + input: + state_code: IL + age: 4 + parent_has_less_than_high_school_education: true + employment_income: 10_000 + output: + # low_income (25pt) + low_education (25pt) = 2 factors + il_pfae_eligible: true + +- name: Case 4, ineligible age too old. + period: 2024 + input: + state_code: IL + age: 6 + has_individualized_education_program: true + output: + il_pfae_eligible: false + +- name: Case 5, ineligible income too high. + period: 2024 + input: + state_code: IL + age: 4 + has_individualized_education_program: true + employment_income: 150_000 + output: + il_pfae_eligible: false diff --git a/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pfae/integration.yaml b/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pfae/integration.yaml new file mode 100644 index 00000000000..835f009624b --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pfae/integration.yaml @@ -0,0 +1,102 @@ +- name: Case 1, family with one eligible and one ineligible child. + period: 2024 + input: + people: + person1: + age: 35 + employment_income: 20_000 + person2: + age: 4 + has_individualized_education_program: true + person3: + age: 8 + 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: + # Age eligibility: only person2 (age 4) is eligible + il_pfae_age_eligible_child: [false, true, false] + # Highest priority: person2 has IEP + il_pfae_has_highest_priority_factor: [false, true, false] + # PFAE eligibility: only person2 is eligible + il_pfae_eligible: [false, true, false] + # PFA eligibility mirrors PFAE + il_pfa_eligible: [false, true, false] + # Benefit amounts (FY2024 values same as FY2025) + il_pfae: [0, 8_500, 0] + il_pfa: [0, 3_900, 0] + +- name: Case 2, family with two eligible children showing benefit amounts. + period: 2025 + input: + people: + person1: + age: 32 + employment_income: 15_000 + person2: + age: 3 + has_individualized_education_program: true + person3: + age: 5 + is_in_foster_care: true + 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: + # Both children are age eligible + il_pfae_age_eligible_child: [false, true, true] + # Both have highest priority factors (IEP, foster care) + il_pfae_has_highest_priority_factor: [false, true, true] + # Both children are PFAE eligible + il_pfae_eligible: [false, true, true] + il_pfa_eligible: [false, true, true] + # Benefit amounts per eligible child (FY2025 values) + # PFAE: $8,500 per child + il_pfae: [0, 8_500, 8_500] + # PFA: $3,900 per child + il_pfa: [0, 3_900, 3_900] + +- name: Case 3, family with no eligible children. + period: 2024 + input: + people: + person1: + age: 40 + employment_income: 80_000 + person2: + age: 10 + person3: + age: 2 + 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: + # No children in age range 3-5 + il_pfae_age_eligible_child: [false, false, false] + # No PFAE eligibility + il_pfae_eligible: [false, false, false] + il_pfa_eligible: [false, false, false] + # No benefits + il_pfae: [0, 0, 0] + il_pfa: [0, 0, 0] diff --git a/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pfae/priority/il_pfae_has_highest_priority_factor.yaml b/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pfae/priority/il_pfae_has_highest_priority_factor.yaml new file mode 100644 index 00000000000..25f8a87db44 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pfae/priority/il_pfae_has_highest_priority_factor.yaml @@ -0,0 +1,31 @@ +- name: Case 1, has IEP. + period: 2024 + input: + state_code: IL + has_individualized_education_program: true + output: + il_pfae_has_highest_priority_factor: true + +- name: Case 2, in foster care. + period: 2024 + input: + state_code: IL + is_in_foster_care: true + output: + il_pfae_has_highest_priority_factor: true + +- name: Case 3, deep poverty. + period: 2024 + input: + state_code: IL + employment_income: 5_000 + output: + il_pfae_has_highest_priority_factor: true + +- name: Case 4, no highest priority factors. + period: 2024 + input: + state_code: IL + employment_income: 30_000 + output: + il_pfae_has_highest_priority_factor: false diff --git a/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pfae/priority/il_pfae_is_deep_poverty.yaml b/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pfae/priority/il_pfae_is_deep_poverty.yaml new file mode 100644 index 00000000000..b6104cbbff7 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pfae/priority/il_pfae_is_deep_poverty.yaml @@ -0,0 +1,15 @@ +- name: Case 1, income below 50% FPL. + period: 2024 + input: + state_code: IL + employment_income: 5_000 + output: + il_pfae_is_deep_poverty: true + +- name: Case 2, income above 50% FPL. + period: 2024 + input: + state_code: IL + employment_income: 30_000 + output: + il_pfae_is_deep_poverty: false diff --git a/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pfae/priority/il_pfae_is_low_income.yaml b/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pfae/priority/il_pfae_is_low_income.yaml new file mode 100644 index 00000000000..a711168ce2d --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pfae/priority/il_pfae_is_low_income.yaml @@ -0,0 +1,15 @@ +- name: Case 1, income below 100% FPL. + period: 2024 + input: + state_code: IL + employment_income: 10_000 + output: + il_pfae_is_low_income: true + +- name: Case 2, income above 100% FPL. + period: 2024 + input: + state_code: IL + employment_income: 50_000 + output: + il_pfae_is_low_income: false diff --git a/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pfae/priority/il_pfae_secondary_priority_factor_count.yaml b/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pfae/priority/il_pfae_secondary_priority_factor_count.yaml new file mode 100644 index 00000000000..006a55a890a --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/il/isbe/pfae/priority/il_pfae_secondary_priority_factor_count.yaml @@ -0,0 +1,85 @@ +- name: Case 1, low income only. + period: 2024 + input: + state_code: IL + employment_income: 10_000 + output: + il_pfae_secondary_priority_factor_count: 1 + +- name: Case 2, low income and low education. + period: 2024 + input: + state_code: IL + employment_income: 10_000 + parent_has_less_than_high_school_education: true + output: + il_pfae_secondary_priority_factor_count: 2 + +- name: Case 3, developmental delay without IEP. + period: 2024 + input: + state_code: IL + has_developmental_delay: true + employment_income: 50_000 + output: + il_pfae_secondary_priority_factor_count: 1 + +- name: Case 4, developmental delay with IEP not counted. + period: 2024 + input: + state_code: IL + has_developmental_delay: true + has_individualized_education_program: true + employment_income: 50_000 + output: + # IEP is 50-pt factor, so delay doesn't count as 25-pt + il_pfae_secondary_priority_factor_count: 0 + +- name: Case 5, no secondary priority factors. + period: 2024 + input: + state_code: IL + employment_income: 50_000 + output: + il_pfae_secondary_priority_factor_count: 0 + +- name: Case 6, immigrant family factor (child born outside US). + period: 2024 + input: + state_code: IL + employment_income: 50_000 + is_born_outside_us: true + output: + il_pfae_secondary_priority_factor_count: 1 + +- name: Case 7, no prior formal early learning factor. + period: 2024 + input: + state_code: IL + employment_income: 50_000 + has_no_prior_formal_early_learning: true + output: + # Child has NOT participated in formal early learning = 25 pts + il_pfae_secondary_priority_factor_count: 1 + +- name: Case 8, teen parent at first birth factor. + period: 2024 + input: + state_code: IL + employment_income: 50_000 + il_isbe_was_teen_parent_at_first_birth: true + output: + # Parent was under 20 when first child was born = 25 pts + il_pfae_secondary_priority_factor_count: 1 + +- name: Case 9, multiple factors combined. + period: 2024 + input: + state_code: IL + employment_income: 50_000 + il_isbe_was_teen_parent_at_first_birth: true + is_born_outside_us: true + has_no_prior_formal_early_learning: true + output: + # Teen parent (1) + immigrant (1) + no prior learning (1) = 3 + il_pfae_secondary_priority_factor_count: 3 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..c96905fcf8f --- /dev/null +++ b/policyengine_us/variables/gov/states/il/isbe/eligibility/il_isbe_income_eligible.py @@ -0,0 +1,26 @@ +from policyengine_us.model_api import * + + +class il_isbe_income_eligible(Variable): + value_type = bool + entity = Person + label = ( + "Meets income requirements for Illinois ISBE early childhood programs" + ) + definition_period = YEAR + reference = ( + "https://www.isbe.net/pages/preschool-for-all.aspx", + "https://law.onecle.com/illinois/105ilcs5/2-3.71.html", + ) + defined_for = StateCode.IL + + def formula(person, period, parameters): + # 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 + return income <= threshold 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..16fbaf267a1 --- /dev/null +++ b/policyengine_us/variables/gov/states/il/isbe/eligibility/il_isbe_was_teen_parent_at_first_birth.py @@ -0,0 +1,32 @@ +from policyengine_us.model_api import * + + +class il_isbe_was_teen_parent_at_first_birth(Variable): + value_type = bool + entity = SPMUnit + label = "Parent was a teen at birth of first child" + definition_period = YEAR + 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/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/pfa/il_pfa.py b/policyengine_us/variables/gov/states/il/isbe/pfa/il_pfa.py new file mode 100644 index 00000000000..863cb4df9b8 --- /dev/null +++ b/policyengine_us/variables/gov/states/il/isbe/pfa/il_pfa.py @@ -0,0 +1,15 @@ +from policyengine_us.model_api import * + + +class il_pfa(Variable): + value_type = float + entity = Person + label = "Illinois Preschool For All (PFA) benefit" + definition_period = YEAR + unit = USD + reference = ( + "https://www.isbe.net/pages/preschool-for-all.aspx", + "https://gov-pritzker-newsroom.prezly.com/gov-pritzker-announces-5150-new-preschool-seats-through-smart-start-initiative", + ) + defined_for = "il_pfa_eligible" + adds = ["gov.states.il.isbe.pfa.benefit.amount"] diff --git a/policyengine_us/variables/gov/states/il/isbe/pfa/il_pfa_eligible.py b/policyengine_us/variables/gov/states/il/isbe/pfa/il_pfa_eligible.py new file mode 100644 index 00000000000..f80d8d51f49 --- /dev/null +++ b/policyengine_us/variables/gov/states/il/isbe/pfa/il_pfa_eligible.py @@ -0,0 +1,18 @@ +from policyengine_us.model_api import * + + +class il_pfa_eligible(Variable): + value_type = bool + entity = Person + label = "Eligible for Illinois Preschool For All (PFA)" + definition_period = YEAR + reference = ( + "https://www.isbe.net/pages/preschool-for-all.aspx", + "https://www.isbe.net/Documents/pdg-eg-grant-enrollment-form.pdf", + ) + defined_for = StateCode.IL + # PFA and PFAE share identical eligibility criteria. The difference is + # service level: PFA provides half-day, PFAE provides full-day programs. + # A child receives one or the other based on local program availability, + # not both simultaneously. + adds = ["il_pfae_eligible"] diff --git a/policyengine_us/variables/gov/states/il/isbe/pfae/eligibility/il_pfae_age_eligible_child.py b/policyengine_us/variables/gov/states/il/isbe/pfae/eligibility/il_pfae_age_eligible_child.py new file mode 100644 index 00000000000..ac197fd605d --- /dev/null +++ b/policyengine_us/variables/gov/states/il/isbe/pfae/eligibility/il_pfae_age_eligible_child.py @@ -0,0 +1,23 @@ +from policyengine_us.model_api import * + + +class il_pfae_age_eligible_child(Variable): + value_type = bool + entity = Person + label = "Child meets age requirements for Illinois PFAE" + definition_period = YEAR + reference = ( + "https://www.isbe.net/pages/preschool-for-all.aspx", + "https://www.isbe.net/Documents/pdg-eg-grant-enrollment-form.pdf", + ) + defined_for = StateCode.IL + + def formula(person, period, parameters): + # PFA/PFAE serves children ages 3-4, plus 5-year-olds not yet + # kindergarten eligible. Per 105 ILCS 5/10-20.12, children who + # turn 5 on or before September 1 are kindergarten eligible. + # Since PolicyEngine uses age in whole years without birth month, + # we include all 5-year-olds as a simplification (some are eligible). + p = parameters(period).gov.states.il.isbe.pfae.eligibility + age = person("age", period) + return p.age_range.calc(age) diff --git a/policyengine_us/variables/gov/states/il/isbe/pfae/eligibility/il_pfae_basic_eligible.py b/policyengine_us/variables/gov/states/il/isbe/pfae/eligibility/il_pfae_basic_eligible.py new file mode 100644 index 00000000000..9ed07aa2bd7 --- /dev/null +++ b/policyengine_us/variables/gov/states/il/isbe/pfae/eligibility/il_pfae_basic_eligible.py @@ -0,0 +1,19 @@ +from policyengine_us.model_api import * + + +class il_pfae_basic_eligible(Variable): + value_type = bool + entity = Person + label = "Meets basic eligibility for Illinois PFAE (age and income)" + definition_period = YEAR + reference = ( + "https://www.isbe.net/pages/preschool-for-all.aspx", + "https://www.isbe.net/Documents/pdg-eg-grant-enrollment-form.pdf", + ) + defined_for = StateCode.IL + + def formula(person, period, parameters): + # Basic eligibility: age 3-5 and income <= 400% FPL + age_eligible = person("il_pfae_age_eligible_child", period) + income_eligible = person("il_isbe_income_eligible", period) + return age_eligible & income_eligible diff --git a/policyengine_us/variables/gov/states/il/isbe/pfae/eligibility/il_pfae_eligible.py b/policyengine_us/variables/gov/states/il/isbe/pfae/eligibility/il_pfae_eligible.py new file mode 100644 index 00000000000..c54b4c20eef --- /dev/null +++ b/policyengine_us/variables/gov/states/il/isbe/pfae/eligibility/il_pfae_eligible.py @@ -0,0 +1,28 @@ +from policyengine_us.model_api import * + + +class il_pfae_eligible(Variable): + value_type = bool + entity = Person + label = "Eligible for Illinois Preschool For All Expansion (PFAE)" + definition_period = YEAR + reference = ( + "https://www.isbe.net/pages/preschool-for-all.aspx", + "https://www.isbe.net/Documents/pdg-eg-grant-enrollment-form.pdf#page=2", + ) + defined_for = StateCode.IL + + def formula(person, period, parameters): + # PFAE eligibility requires: + # - Basic eligibility (age 3-5, income <= 400% FPL) + # - AND either: + # - Any highest priority factor (direct enrollment), OR + # - 2+ secondary priority factors + basic_eligible = person("il_pfae_basic_eligible", period) + has_highest_priority = person( + "il_pfae_has_highest_priority_factor", period + ) + secondary_count = person( + "il_pfae_secondary_priority_factor_count", period + ) + return basic_eligible & (has_highest_priority | (secondary_count >= 2)) diff --git a/policyengine_us/variables/gov/states/il/isbe/pfae/il_pfae.py b/policyengine_us/variables/gov/states/il/isbe/pfae/il_pfae.py new file mode 100644 index 00000000000..88d7565ad8d --- /dev/null +++ b/policyengine_us/variables/gov/states/il/isbe/pfae/il_pfae.py @@ -0,0 +1,19 @@ +from policyengine_us.model_api import * + + +class il_pfae(Variable): + value_type = float + entity = Person + label = "Illinois Preschool For All Expansion (PFAE) benefit" + definition_period = YEAR + unit = USD + reference = ( + "https://www.isbe.net/pages/preschool-for-all.aspx", + "https://gov-pritzker-newsroom.prezly.com/gov-pritzker-announces-5150-new-preschool-seats-through-smart-start-initiative", + ) + defined_for = "il_pfae_eligible" + # PFA and PFAE share identical eligibility criteria. The difference is + # service level: PFA provides half-day, PFAE provides full-day programs. + # A child receives one or the other based on local program availability, + # not both simultaneously. + adds = ["gov.states.il.isbe.pfae.benefit.amount"] diff --git a/policyengine_us/variables/gov/states/il/isbe/pfae/priority/il_pfae_has_highest_priority_factor.py b/policyengine_us/variables/gov/states/il/isbe/pfae/priority/il_pfae_has_highest_priority_factor.py new file mode 100644 index 00000000000..b73e6c325a4 --- /dev/null +++ b/policyengine_us/variables/gov/states/il/isbe/pfae/priority/il_pfae_has_highest_priority_factor.py @@ -0,0 +1,40 @@ +from policyengine_us.model_api import * + + +class il_pfae_has_highest_priority_factor(Variable): + value_type = bool + entity = Person + label = "Has highest priority selection factor for Illinois PFAE" + definition_period = YEAR + reference = ( + "https://www.isbe.net/pages/preschool-for-all.aspx", + "https://www.isbe.net/Documents/pdg-eg-grant-enrollment-form.pdf#page=2", + ) + defined_for = StateCode.IL + + def formula(person, period, parameters): + # Highest priority selection factors (50 points each): + # 1. Homeless (McKinney-Vento) + # 2. Child welfare involvement (foster care, Ward of State) + # 3. Has IEP or referred for special education evaluation + # 4. Family income at or below 50% FPL and/or receiving TANF + # Factor 1: Homeless + is_homeless = person.household("is_homeless", period) + + # Factor 2: Child welfare involvement (foster care) + is_in_foster_care = person("is_in_foster_care", period) + + # Factor 3: Has IEP + has_iep = person("has_individualized_education_program", period) + + # Factor 4: Income <= 50% FPL OR receiving TANF + is_deep_poverty = person("il_pfae_is_deep_poverty", period) + receives_tanf = person.spm_unit("il_tanf", period) > 0 + + return ( + is_homeless + | is_in_foster_care + | has_iep + | is_deep_poverty + | receives_tanf + ) diff --git a/policyengine_us/variables/gov/states/il/isbe/pfae/priority/il_pfae_is_deep_poverty.py b/policyengine_us/variables/gov/states/il/isbe/pfae/priority/il_pfae_is_deep_poverty.py new file mode 100644 index 00000000000..b778968fb6a --- /dev/null +++ b/policyengine_us/variables/gov/states/il/isbe/pfae/priority/il_pfae_is_deep_poverty.py @@ -0,0 +1,23 @@ +from policyengine_us.model_api import * + + +class il_pfae_is_deep_poverty(Variable): + value_type = bool + entity = Person + label = "Family income at or below 50% FPL (50-point factor for IL PFAE)" + definition_period = YEAR + reference = ( + "https://www.isbe.net/Documents/pdg-eg-grant-enrollment-form.pdf#page=2", + ) + defined_for = StateCode.IL + + def formula(person, period, parameters): + # Deep poverty (income <= 50% FPL) is a highest priority factor. + # Per the ISBE PDG enrollment form, Factor 4 includes "Family income at + # or below 50% of the federal poverty guidelines." + p = parameters(period).gov.states.il.isbe.pfae.eligibility.income + spm_unit = person.spm_unit + 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/pfae/priority/il_pfae_is_low_income.py b/policyengine_us/variables/gov/states/il/isbe/pfae/priority/il_pfae_is_low_income.py new file mode 100644 index 00000000000..e1fc3ed7b73 --- /dev/null +++ b/policyengine_us/variables/gov/states/il/isbe/pfae/priority/il_pfae_is_low_income.py @@ -0,0 +1,21 @@ +from policyengine_us.model_api import * + + +class il_pfae_is_low_income(Variable): + value_type = bool + entity = Person + label = "Family income at or below 100% FPL (secondary priority factor)" + definition_period = YEAR + reference = ( + "https://www.isbe.net/pages/preschool-for-all.aspx", + "https://www.isbe.net/Documents/pdg-eg-grant-enrollment-form.pdf#page=2", + ) + defined_for = StateCode.IL + + def formula(person, period, parameters): + p = parameters(period).gov.states.il.isbe.pfae.eligibility.income + spm_unit = person.spm_unit + 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/pfae/priority/il_pfae_secondary_priority_factor_count.py b/policyengine_us/variables/gov/states/il/isbe/pfae/priority/il_pfae_secondary_priority_factor_count.py new file mode 100644 index 00000000000..f71e0169c5d --- /dev/null +++ b/policyengine_us/variables/gov/states/il/isbe/pfae/priority/il_pfae_secondary_priority_factor_count.py @@ -0,0 +1,65 @@ +from policyengine_us.model_api import * + + +class il_pfae_secondary_priority_factor_count(Variable): + value_type = int + entity = Person + label = "Number of secondary priority factors for Illinois PFAE" + definition_period = YEAR + reference = ( + "https://www.isbe.net/pages/preschool-for-all.aspx", + "https://www.isbe.net/Documents/pdg-eg-grant-enrollment-form.pdf#page=2", + ) + defined_for = StateCode.IL + + def formula(person, period, parameters): + spm_unit = person.spm_unit + household = person.household + + # Factor 5: Income <= 100% FPL + is_low_income = person("il_pfae_is_low_income", period) + + # Factor 6: Parent didn't complete high school (Household-level variable) + parent_low_education = household( + "parent_has_less_than_high_school_education", period + ) + + # Factor 7: Teen parent at birth of first child + # Parent was under 20 when first child was born + was_teen_parent = spm_unit( + "il_isbe_was_teen_parent_at_first_birth", period + ) + + # Factor 8: Child or parent born outside US + born_outside_us = person("is_born_outside_us", period) + is_immigrant_family = spm_unit.any(born_outside_us) + + # Factor 9: Non-English speaking home (Household-level variable) + is_non_english_home = household("is_non_english_speaking_home", period) + + # Factor 10: Active Duty Military family + is_active_duty_military = person("military_basic_pay", period) > 0 + is_military_family = spm_unit.any(is_active_duty_military) + + # Factor 11: Developmental delay (without IEP) + has_developmental_delay = person("has_developmental_delay", period) + has_iep = person("has_individualized_education_program", period) + delay_without_iep = has_developmental_delay & ~has_iep + + # Factor 12: No prior formal early learning + no_prior_learning = person( + "has_no_prior_formal_early_learning", period + ) + + factors = [ + is_low_income, + parent_low_education, + was_teen_parent, + is_immigrant_family, + is_non_english_home, + is_military_family, + delay_without_iep, + no_prior_learning, + ] + + return sum([f.astype(int) for f in factors]) 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..b6259d13d0e --- /dev/null +++ b/policyengine_us/variables/household/demographic/geographic/is_non_english_speaking_home.py @@ -0,0 +1,9 @@ +from policyengine_us.model_api import * + + +class is_non_english_speaking_home(Variable): + value_type = bool + entity = Household + 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 new file mode 100644 index 00000000000..62d34ed1484 --- /dev/null +++ b/policyengine_us/variables/household/demographic/household/parent_has_less_than_high_school_education.py @@ -0,0 +1,9 @@ +from policyengine_us.model_api import * + + +class parent_has_less_than_high_school_education(Variable): + value_type = bool + 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/has_developmental_delay.py b/policyengine_us/variables/household/demographic/person/has_developmental_delay.py new file mode 100644 index 00000000000..55a719dab6c --- /dev/null +++ b/policyengine_us/variables/household/demographic/person/has_developmental_delay.py @@ -0,0 +1,9 @@ +from policyengine_us.model_api import * + + +class has_developmental_delay(Variable): + value_type = bool + entity = Person + label = "Has a developmental delay" + definition_period = YEAR + documentation = "Whether the child has a screening-indicated developmental delay or disability" diff --git a/policyengine_us/variables/household/demographic/person/has_individualized_education_program.py b/policyengine_us/variables/household/demographic/person/has_individualized_education_program.py new file mode 100644 index 00000000000..3c104bdcd6c --- /dev/null +++ b/policyengine_us/variables/household/demographic/person/has_individualized_education_program.py @@ -0,0 +1,9 @@ +from policyengine_us.model_api import * + + +class has_individualized_education_program(Variable): + value_type = bool + entity = Person + label = "Has an Individualized Education Program (IEP)" + definition_period = YEAR + documentation = "Whether the child has an IEP under the Individuals with Disabilities Education Act (IDEA)" 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/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/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]]