PolicyEngine / PolicyEngine/policyengine-us

Check if reforms are active using a consolidated function

Open
#4,913 0 comments 1 reaction 0 assignees View on GitHub
code-health
Dominant language
Python
Stars
162
Forks
212
Avg merge
3d 3h
Merged PRs (30d)
97

Description

There's a lot of redundancy in each reform checking if it's active or not. We can make this a function for them all to call, either here or in policyengine-core.

Here's one way:
```python
# File: policyengine_us/reforms/utils.py

from policyengine_core.periods import period as period_

def create_reform_if_active(parameters, period, parameter_path, reform_function, bypass: bool = False):
"""
Check if a reform's parameter is truthy in any of the next five years and create the reform if so.

Args:
parameters: The parameters object from the reform function.
period: The current period.
parameter_path: A string representing the path to the relevant parameter.
reform_function: A function that creates and returns the reform.
bypass: If True, always return the reform regardless of the parameter value.

Returns:
Reform or None: The reform if the parameter is truthy or bypassed, None otherwise.
"""
if bypass:
return reform_function()

current_period = period_(period)

for _ in range(5):
if parameters(current_period).get_descendants(parameter_path):
return reform_function()
current_period = current_period.offset(1, "year")

return None

# Example usage:
# def create_my_reform():
# # Reform creation logic here
# return Reform()
#
# my_reform = create_reform_if_active(parameters, period, "gov.some.parameter", create_my_reform)
```
For example, Wyden-Smith would look like:
```python
# File: policyengine_us/reforms/congress/wyden_smith/ctc_expansion.py

from policyengine_us.model_api import *
from policyengine_us.reforms.utils import create_reform_if_active

def create_ctc_expansion():
# Your existing create_ctc_expansion logic here
class reform(Reform):
def apply(self):
# Reform application logic
pass
return reform

ctc_expansion = create_reform_if_active(
None,
None,
"gov.contrib.congress.wyden_smith",
create_ctc_expansion,
bypass=True
)
```
and DC CTC would look like:
```python
# File: policyengine_us/reforms/states/dc/dc_ctc.py

from policyengine_us.model_api import *
from policyengine_us.reforms.utils import create_reform_if_active

def create_dc_ctc():
# Your existing create_dc_ctc logic here
class reform(Reform):
def apply(self):
# Reform application logic
pass
return reform

dc_ctc = create_reform_if_active(
None,
None,
"gov.contrib.states.dc.ctc.in_effect",
create_dc_ctc,
bypass=True
)
```
@nikhilwoodruff should this go in core?

@PavelMakarchuk fyi given the new reform modeling hire.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.