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

Use both ANY and ALL conditions together in one rule #64

Open
yinongwu-blink opened this issue Sep 21, 2021 · 0 comments
Open

Use both ANY and ALL conditions together in one rule #64

yinongwu-blink opened this issue Sep 21, 2021 · 0 comments

Comments

@yinongwu-blink
Copy link

Based on the rules example in ReadMe, we are able to have both ANY and ALL conditions in one rule and pass it to Venmo/business-rules.

# current_inventory < 5 OR (current_month = "December" AND current_inventory < 20)
{ "conditions": { "any": [
      { "name": "current_inventory",
        "operator": "less_than",
        "value": 5,
      },
    ]},
      { "all": [
        {  "name": "current_month",
          "operator": "equal_to",
          "value": "December",
        },
        { "name": "current_inventory",
          "operator": "less_than",
          "value": 20,
        }
      ]},
  },
  "actions": [
    { "name": "order_more",
      "params":{"number_to_order": 40},
    },
  ],
}]

However, in the actual code, it doesn't look like working as it described in the example. "==" seems to limit that only when one kind of condition is in the condition list, it will work. For mixed situation it doesn't seem work.

Current Code in business_rules/engine.py :

def check_conditions_recursively(conditions, defined_variables):
    keys = list(conditions.keys())
    if keys == ['all']:
        assert len(conditions['all']) >= 1
        for condition in conditions['all']:
            if not check_conditions_recursively(condition, defined_variables):
                return False
        return True

    elif keys == ['any']:
        assert len(conditions['any']) >= 1
        for condition in conditions['any']:
            if check_conditions_recursively(condition, defined_variables):
                return True
        return False

    else:
        # help prevent errors - any and all can only be in the condition dict
        # if they're the only item
        assert not ('any' in keys or 'all' in keys)
        return check_condition(conditions, defined_variables)

Here, me and my team want to have a mixed rule with both ANY and ALL conditions, and also wish it won't make any final decision when just validating one of it. So first to check if ANY or ALL exists, then start checking one of it, if doesn't apply, then go to validate the other one if exists.

Proposal code (mainly update "keys == ..." to "... in keys" and update the return condition):

def check_conditions_recursively(conditions, defined_variables):
    keys = list(conditions.keys())
    if 'any' in keys:
        assert len(conditions['any']) >= 1
        for condition in conditions['any']:
            if check_conditions_recursively(condition, defined_variables):
                return True
        if 'all' not in keys:
            return False

    elif 'all' in keys:
        assert len(conditions['all']) >= 1
        for condition in conditions['all']:
            if not check_conditions_recursively(condition, defined_variables):
                return False
        return True

    else:
        # help prevent errors - any and all can only be in the condition dict
        # if they're the only item
        assert not ('any' in keys or 'all' in keys)
        return check_condition(conditions, defined_variables)

Please feel free to leave any comments to help me have a better understanding of this part of code. Thank you!

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

No branches or pull requests

1 participant