Closed wwwslinger closed 2 years ago
If I understand correctly, you want to apply an expression written once to multiple things that are identical. If that's right, then list comprehension should do the trick for you.
Something like this:
$ PYTHONPATH=$(pwd)/lib python -m rule_engine.debug_repl --edit-console
edit the 'context' and 'thing' objects as necessary
>>> measurements = {'measurement_1': 9999, 'measurement_2': 9999}
>>> thing = {'prior':measurements, 'current':measurements}
>>> exit()
exiting the edit console...
rule > [m for m in [prior, current] if m.measurement_1 > 100 or m.measurement_2 > 25].length > 0
result:
True
rule >
In this case, prior
and current
are both in the top-level namespace. You create an array containing both of them (or even more if you wanted) and then filter them based on the expression that you don't want to repeat. Count the number that were filtered and you should be all set.
Thanks! I like that example. That works well for this case and some others.
In general, though, there is no way to include one rule as part of another? Like this scenario:
rule1 = 'measurement_1 > 100 or measurement_2 > 90'
rule2 = 'measurement_3 < 1000 and measurement_3 > 250'
rule3 = 'measurement_3 == 300 or measurement_1 == 150'
measurements = {'measurement_1': 9999, 'measurement_2': 9999, 'measurement_3': 9999}
testA = rule1.matches(measurements)
...do some things because testA matched...
testB = rule2.matches(measurements)
...do some things because testB matched...
thing = { "r1": testA, "r2": testB, "r3": rule3.matches(measurements), "measurement_2": measurements["measurement_2"] }
rule4 = 'r1 and r2 and r3 and measurement_2 < 100'
testC = rule4.matches(thing)
Would be great if I can use rule1
and rule2
separately, then write rule4
without creating the thing
object, more simply as:
rule4 = 'rule1 and rule2 and rule3 and measurement_2 < 100`
testC = rule4.matches(measurements)
(edited for bad rule numbering)
Not really, no. Each rule is a completely separate object with no reference to any other rules. You'd need to do something in Python to make almost like a macro maybe using format strings, string concatenation or direct AST manipulation.
You could always store the evaluated result from a previous rule but it wouldn't be reevaluated for the current object thats being matched on.
I have a rule like the following:
(prior.measurement_1 > 100 or prior.measurment_2 > 25) and (current.measurement_1 > 100 or current.measurement_2 > 25)
I'd like to create a rule for just the measurements and another rule for it matching on prior and current events toghether:
It doesn't have to be structured like this, but I'd prefer to keep the whole rule as one, leveraging other rules within, to avoid coding up the logic in Python. Is that possible? I can't find anything like this in your examples.
It's trivial to code, but redefining the same rule (like the
measurement_rule
above) is something I'm going to have to do for hundreds or more. It would be great to mix and match rules.