Use engine as function or generator
Introduce a new engine feature to allow returning values from the RHS.
This has been requested many times, last time here: https://github.com/buguroo/pyknow/issues/47
@nilp0inter Happy to offer some help if I can :)
My hacky workaround is not optimal!
Hi! Thank you for the help, it is very welcome.
As you mentioned in your original post, this can be accomplished in several ways. I think the best way to decide is to enumerate the options to better compare them (and maybe code a proof of concept to test them)
For example it can be done by:
- Add a method in the
KnowledgeEngineto store the return value internally and then return it with therun()call return value. - A subclass of
KnowledgeEngineas you mentioned. - Convert
run()into a generator and let the RHSs of the engineyield/returnvalues to be yielded from therun(). This is similar to (1). - Use an special exception to raise the value to the
run()method, capture it there and return it. - Don't use the return value of
run()but a special attribute to store the value. - Create a wrapper function to reset and run the given knowledge engine combined with (4) or (5)
I'll be coding some of this ideas in Gists and linking them here. You can do the same if you think of any alternatives not mentioned here.
This is the first proof of concept. Implementing ideas from (3). It has some drawbacks, though:
- You can mix yield/return RHS with unexpected results from the user perspective.
- The user have to decide if she wants to consume a generator or not.
- Can't return
None.
Note: The method _run_activations is a copy of the original run() method with some minor changes. The amount of modifications in the library would be pretty small.
Hi! I need some help, I've been reading this post for a while but I don't know how to implement this in my code.
I need to return resultadoPublicaciones value in order to use it in other method, but I don't know how to do it. Could someone help me?
class EvaluacionPublicacionesCE(KnowledgeEngine):
@Rule(Publicaciones(publicaciones = P(lambda x: x >= 12)))
def publicaciones_max(self):
print('resultado = 35')
@Rule(Publicaciones(publicaciones = P(lambda x: 8 <= x <= 11)))
def publicaciones_med(self):
publicaciones = self.facts[1]['publicaciones']
factor = self.facts[2]['factor']
medio = self.facts[3]['medio']
cuartil = self.facts[4]['cuartil']
numeroAutores = self.facts[5]['numeroAutores']
tiempoDesdeLectura = self.facts[6]['tiempoDesdeLectura']
continua = self.facts[7]['continua']
resultadoPublicaciones = 16
cuartiles12 = 0
cuartiles34 = 0
for i in cuartil:
if i == "Q1" or i == "Q2":
cuartiles12 += 1
elif i =="Q3" or i == "Q4":
cuartiles34 += 1
if cuartiles12 >= 8:
resultadoPublicaciones = resultadoPublicaciones + 6
elif (4 <= cuartiles12 <= 7):
resultadoPublicaciones = resultadoPublicaciones + 4
elif (2 <= cuartiles12 < 4):
resultadoPublicaciones = resultadoPublicaciones + 2
elif (cuartiles12 == 1):
resultadoPublicaciones = resultadoPublicaciones + 1
if cuartiles34 >= 8:
resultadoPublicaciones = resultadoPublicaciones + 3
elif (4 <= cuartiles34 <= 7):
resultadoPublicaciones = resultadoPublicaciones + 2
elif (2 <= cuartiles34 < 4):
resultadoPublicaciones = resultadoPublicaciones + 1
factorAlto = 0
factorMedio = 0
factorBajo = 0
for i in factor:
if i == "alto":
factorAlto += 1
elif i == "medio":
factorMedio += 1
if factorAlto > 5:
resultadoPublicaciones = resultadoPublicaciones + 3
elif (3 <= factorAlto <= 5):
resultadoPublicaciones = resultadoPublicaciones + 2
if factorMedio >= 6:
resultadoPublicaciones = resultadoPublicaciones + 1
if ((factorMedio < 6) and (factorAlto < 3)):
if ((factorMedio + factorAlto) > 3):
resultadoPublicaciones = resultadoPublicaciones + 1
cuentaContinua = 0
for i in continua:
if i == "Si":
cuentaContinua += 1
else:
continue
if (cuentaContinua > 7):
resultadoPublicaciones = resultadoPublicaciones + 3
elif (5 < cuentaContinua <= 7):
resultadoPublicaciones = resultadoPublicaciones + 2
elif (2 <= cuentaContinua <= 5):
resultadoPublicaciones = resultadoPublicaciones + 1
print("resultado = " + str(resultadoPublicaciones))
@Rule(Publicaciones(publicaciones = P(lambda x: 0 < x <= 7)))
def publicaciones_min(self):
publicaciones = self.facts[1]['publicaciones']
factor = self.facts[2]['factor']
medio = self.facts[3]['medio']
cuartil = self.facts[4]['cuartil']
numeroAutores = self.facts[5]['numeroAutores']
tiempoDesdeLectura = self.facts[6]['tiempoDesdeLectura']
continua = self.facts[7]['continua']
resultadoPublicaciones = 2 * publicaciones
if (resultadoPublicaciones > 12):
resultadoPublicaciones = 12
cuartiles12 = 0
cuartiles34 = 0
for i in cuartil:
if i == 'Q1' or i == 'Q2':
cuartiles12 += 1
elif i == 'Q3' or i =='Q4':
cuartiles34 += 1
if cuartiles12 >= 5:
resultadoPublicaciones = resultadoPublicaciones + 3
elif (2 <= cuartiles12 <= 4):
resultadoPublicaciones = resultadoPublicaciones + 2
elif cuartiles12 == 1:
resultadoPublicaciones = resulresultadoPublicacionestado + 1
if cuartiles34 >= 5:
resultadoPublicaciones = resultadoPublicaciones + 2
elif (2 <= cuartiles34 <= 4):
resultadoPublicaciones = resultadoPublicaciones + 1
factorAlto = 0
factorMedio = 0
for i in factor:
if i == "alto":
factorAlto += 1
elif i == "medio":
factorMedio += 1
if factorAlto >= 4:
resultadoPublicaciones = resultadoPublicaciones + 2
elif (2 <= factorAlto <= 3):
resultadoPublicaciones = resultadoPublicaciones + 1
if factorMedio >= 4:
resultadoPublicaciones = resultadoPublicaciones + 1
if ((factorAlto == 1) and (factorMedio < 4)):
if ((factorAlto + factorMedio) >= 3):
resultadoPublicaciones = resultadoPublicaciones + 1
cuentaContinua = 0
for i in continua:
if i == "Si":
cuentaContinua += 1
else:
continue
if cuentaContinua >= 4:
resultadoPublicaciones = resultadoPublicaciones + 2
elif (2 <= cuentaContinua <= 3):
resultadoPublicaciones = resultadoPublicaciones + 1
print('resultado = ' + str(resultadoPublicaciones))