Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Check if reforms are active using a consolidated function #4913

Open
MaxGhenis opened this issue Aug 17, 2024 · 0 comments
Open

Check if reforms are active using a consolidated function #4913

MaxGhenis opened this issue Aug 17, 2024 · 0 comments

Comments

@MaxGhenis
Copy link
Contributor

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:

# 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:

# 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:

# 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant