Skip to content

Instantly share code, notes, and snippets.

@nikzasel
Created October 26, 2020 04:08
Show Gist options
  • Select an option

  • Save nikzasel/43ea3dd4eb7467326e23a717dde38baf to your computer and use it in GitHub Desktop.

Select an option

Save nikzasel/43ea3dd4eb7467326e23a717dde38baf to your computer and use it in GitHub Desktop.
import time
from durable.lang import *
def timed(func):
def wrapper():
start = time.time()
func()
end = time.time()
print(f'Done in: {end-start:.2f}')
return wrapper
@timed
def main():
class Result:
set = False
with ruleset('test'):
@when_all(
# мы пишем в контекст историю, чтобы потом можно было словить событие с ней
c.history << m.type == 'history',
# m (событие) должно быть всегда слева от оператора
m.stats.SOME_CATEGORY == c.history.stats.SOME_CATEGORY
)
def rule1(c):
Result.set = True
print ('rule 1')
@when_all(
c.history << m.type == 'history',
# сложные гипотезы должны быть в скобках (то есть в условии всегда 2 элемента: запись истории и гипотеза)
# причем гипотеза должна быть объеденена сс помощью & или |
((m.stats.VES >= c.history.stats.VES_MIN) &
(m.stats.VES <= c.history.stats.VES_MAX))
)
def rule2(c):
Result.set = True
print ('rule 2')
@when_all(
c.history << m.type == 'history',
((m.stats.SOME_CATEGORY == 5) &
# Обычные регулярки
(m.stats.SOME_STRING.matches('DF.*')))
)
def rule3(c):
Result.set = True
print ('rule 3')
# итерируемся по згк в целевых данных и отбираем строчки из истории с нужными згк
# дальше строится статистика по нужным столбцам и получается переменная history(агрегированная статистика по переменным) и event
history = {
'type':'history',
'zgk': '1,2,3',
'stats': {
'VES_MIN': 1,
'VES_MAX': 5,
'SOME_CATEGORY': 5
}
}
event = {
'type':'event',
'zgk': '1,2,3',
'stats': {
'VES': 3,
'SOME_STRING': 'DF123',
'SOME_CATEGORY': 5,
}
}
facts = [history, event]
# когда любое правило срабатывает, то оно ставит флаг в True
# иначе флаг останется False
for i in range(100):
Result.set = False
# почему assert_facts, если делать через post, то срабатывает максимум 1 правило. В нашем случае, когда на выходе True/False
# разницы нет, но мы можем добавить логирвоание других правил, если используем факты
assert_facts('test', facts)
retract_facts('test', facts)
assert Result.set == True
if __name__ == "__main__":
# производительность на моём компе на 100 правил 0.15 секунды
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment