Skip to content

Conversation

@xudonglai0426
Copy link
Collaborator

@xudonglai0426 xudonglai0426 commented May 1, 2023

Fixes #2217

Co-authored-by: VioletChen0916 VioletChen0916@users.noreply.github.com

🤖 Generated by Copilot at 268a820

Summary

✨📄🛠️

This pull request adds the New Jersey TANF earned income disregards as a new feature to the policy engine. It introduces new parameters, variables, and tests for calculating the countable earned income for TANF households in New Jersey, based on the state's administrative code. It also adds some auxiliary variables for tracking the months enrolled in TANF and the weekly hours worked by TANF recipients.

nj_tanf changes
earned income disregards
autumn leaves fall fast

Walkthrough

  • Add New Jersey TANF earned income disregards as a new feature (link)
  • Create new parameters for the earned income disregards, with values and references from the administrative code (link, link, link, link)
  • Implement a new variable nj_tanf_countable_earned_income that calculates the amount of earned income that is considered for TANF eligibility and benefit amount, using the new parameters and the existing gross_earned_income variable (link)
  • Add new input variables months_enrolled_in_tanf and hours_worked that record the duration and intensity of work for TANF recipients, and derive a new variable weekly_hours_worked from the latter (link, link, link)
  • Write test cases for the nj_tanf_countable_earned_income variable, covering different scenarios of income, enrollment, and work hours, and the expected output according to the New Jersey rules (link)

xudonglai0426 and others added 2 commits May 1, 2023 14:35
Fixes PolicyEngine#2217

Co-authored-by: VioletChen0916 <VioletChen0916@users.noreply.github.com>
@codecov
Copy link

codecov bot commented May 1, 2023

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 97.19%. Comparing base (09c71fc) to head (16a9ae0).
⚠️ Report is 12401 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #2222   +/-   ##
=======================================
  Coverage   97.18%   97.19%           
=======================================
  Files        1265     1269    +4     
  Lines       19997    20048   +51     
  Branches      163      163           
=======================================
+ Hits        19434    19485   +51     
  Misses        537      537           
  Partials       26       26           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@xudonglai0426 xudonglai0426 marked this pull request as ready for review May 1, 2023 19:13
@xudonglai0426 xudonglai0426 marked this pull request as draft May 2, 2023 00:51
@xudonglai0426 xudonglai0426 marked this pull request as ready for review May 2, 2023 14:46
@MaxGhenis MaxGhenis requested a review from PavelMakarchuk May 3, 2023 03:41
Fixes PolicyEngine#2217

Co-authored-by: VioletChen0916 <VioletChen0916@users.noreply.github.com>
person_enrolled_in_tanf_for_additional_months_with_Work_hours_below_20 = (
months_enrolled_in_tanf > p.first_month_threshold
)
if person_meet_higher_work_hours_threshold:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since if statements aren't vectorized, we have to use where and select statements instead

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK. Is there an example shows how to use "select" statement or how to use "where" and "select" to achieve the function of "if" there? Originally, we are using a nested where function, it is not so readable although it passes all the test. That's why we are trying to use "if" function.

Copy link
Collaborator

@leogoldman leogoldman May 26, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@xudonglai0426 see my comment in the review below. Select is much cleaner than nested where (although both are vectorized). if will still achieve the same result, but is not vectorized so it will be much slower.

Copy link
Collaborator

@leogoldman leogoldman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Try to use variable names that aren't quite as long (but still descriptive) to make the code a bit easier to read. Also, avoid creating variables that are the opposite of existing variables (use the boolean inverse instead)

Comment on lines +22 to +27
person_meet_higher_work_hours_threshold = (
weekly_hours_worked >= p.work_hours_threshold
)
person_meet_lower_work_hours_threshold = (
weekly_hours_worked < p.work_hours_threshold
)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
person_meet_higher_work_hours_threshold = (
weekly_hours_worked >= p.work_hours_threshold
)
person_meet_lower_work_hours_threshold = (
weekly_hours_worked < p.work_hours_threshold
)
meets_hours_threshold = weekly_hours_worked >= p.work_hours_threshold

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need for a variable that is the opposite of the first variable. If you need to check if the number of hours is less than the threshold, you can use ~meets_hours_threshold, flipping all the booleans

Comment on lines +45 to +75
result = 0
# If applicant is enrolled in TANF for the first month, the earned income deduction is 100%.
result = where(
person_enrolled_in_tanf_for_first_month,
gross_earned_income
* (1 - p.higher_work_hours.first_month_percent),
result,
)
# If applicant is enrolled in TANF for consecutive months with work hours over 20, the earned income deduction is 75%.
result = where(
(
person_meet_higher_work_hours_threshold
and person_enrolled_in_tanf_for_consecutive_months_with_work_hours_over_20
),
gross_earned_income
* (1 - p.higher_work_hours.consecutive_month_percent),
result,
)
# If applicant is enrolled in TANF for additional months with work hours over 20, the earned income deduction is 50%.
result = where(
person_enrolled_in_tanf_for_additional_months_with_work_hours_over_20,
gross_earned_income * (1 - p.higher_work_hours.additional_percent),
result,
)
# If applicant is enrolled in TANF for additional months with work hours below 20, the earned income deduction is 50%.
result = where(
person_enrolled_in_tanf_for_additional_months_with_work_hours_below_20,
gross_earned_income * (1 - p.lower_work_hours.additional_percent),
result,
)
return result
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here's an example of how to use select():

The function's first argument is a condition list, the second argument is the list of values to return if that condition is true, and the (optional) third argument is the value to return if none of them are true (by default this is zero). The function goes through the condition list and returns the corresponding value. For example, if the third condition is true, the third value in the return list would be returned.
Here, you would want something like
select( [ enrolled_in_tanf_first_month, meets_hours_threshold, ... ], [ gross_earned_income * ( 1-p.higher_work_hours.first_month_percent), gross_earned_income * (1 - p.higher_work_hours.consecutive_month_percent), ... ] )
You don't need to specify a default return value since you want zero anyway.

Comment on lines +31 to +43
person_enrolled_in_tanf_for_consecutive_months_with_work_hours_over_20 = (
months_enrolled_in_tanf <= p.consecutive_month_threshold
and months_enrolled_in_tanf > p.first_month_threshold
and person_meet_higher_work_hours_threshold
)
person_enrolled_in_tanf_for_additional_months_with_work_hours_over_20 = (
months_enrolled_in_tanf > p.consecutive_month_threshold
and person_meet_higher_work_hours_threshold
)
person_enrolled_in_tanf_for_additional_months_with_work_hours_below_20 = (
months_enrolled_in_tanf > p.first_month_threshold
and person_meet_lower_work_hours_threshold
)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since you want element-wise boolean operations, make sure you use & instead of and.

@nikhilwoodruff nikhilwoodruff force-pushed the master branch 2 times, most recently from 7926ec9 to d2543dc Compare July 12, 2025 15:13
@hua7450
Copy link
Collaborator

hua7450 commented Jan 7, 2026

Consolidated into #7123

@hua7450 hua7450 closed this Jan 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

New Jersey TANF earned income disregard

4 participants