Skip to content

Got a AttributeError: 'Rule' object has no attribute '__name__' #39

@wangyingsm

Description

@wangyingsm

Background, I am new to Pyknow. I want to build a expert system to auto calculate a cell quality score based on some parameters. The score algorithm should be loaded from a json data, such like:

	{
		"PN": [{
			"condition": "pn",
			"symbol": "=",
			"value": "2PN",
			"score": "20",
			"weight": "1.0"
		}, {
			"condition": "time",
			"symbol": "<=",
			"value": "12",
			"score": "20",
			"weight": "1.0"
		}],
		"4C": [{
			"condition": "cell",
			"symbol": "=",
			"value": "4C",
			"score": "20",
			"weight": "1.0"
		}, {
			"condition": "even",
			"symbol": "=",
			"value": true,
			"score": "20",
			"weight": "1.0"
		}, {
			"condition": "fragment",
			"symbol": "=",
			"value": "<5%",
			"score": "20",
			"weight": "1.0"
		}, {
			"condition": "fragment",
			"symbol": "=",
			"value": "5%-10%",
			"score": "15",
			"weight": "1.0"
		}, {
			"condition": "fragment",
			"symbol": "=",
			"value": "10%-20%",
			"score": "10",
			"weight": "1.0"
		}, {
			"condition": "time",
			"symbol": "<=",
			"value": "36",
			"score": "20",
			"weight": "1.0"
		}]
	}

Here are my codes for this,

	from pyknow import *
	from functools import partial

	class EmbryoScore(KnowledgeEngine):
	    score = 0
	    @classmethod
	    def removeAllRules(cls):
	        for m in [attr for attr in cls.__dict__ if attr.startswith('rule')]:
	            delattr(cls, m)

	def parse_json_rules(rule_json):
	    import json
	    rules = json.loads(rule_json)
	    sal = 100
	    index = 0
	    for stage in rules:
	        for rule_item in rules[stage]:
	            rule = {'condition': rule_item['condition']}
	            rule['stage'] = stage
	            if rule_item['symbol'] not in ('=', '<', '<=', '>', '>='):
	                continue
	            def _cond(value, symbol):
	                if symbol == '=': return EQ(value)
	                if symbol == '<': return LT(value)
	                if symbol == '<=': return LE(value)
	                if symbol == '>': return GT(value)
	                if symbol == '>=': return GE(value)

	            def _add(self, **kwargs):
	                if 'score' not in kwargs or 'weight' not in kwargs:
	                    raise ValueError('No score or weight specified')
	                s, w = int(kwargs['score']), float(kwargs['weight'])
	                self.score += s * w
	        
	            R = Rule(AND(Fact(**rule, value=MATCH.value & 
                        _cond(rule_item['value'], rule_item['symbol']))),
	                    salience=sal)(partial(_add, score=rule_item['score'], 
                        weight=rule_item['weight']))
	            setattr(EmbryoScore, f'rule{index}', R)
	            index += 1
	            sal -= 1

	def init_engine(rule_json):
	    EmbryoScore.removeAllRules()
	    parse_json_rules(rule_json)
	    engine = EmbryoScore()
	    engine.reset()
	    return engine

	import unittest

	class ScoreTest(unittest.TestCase):
		def test(self):
			engine = init_engine(rule_json)
			engine.declare(Fact(condition='pn', stage='PN', value='2PN'))
			engine.declare(Fact(stage='4C', condition='cell', value='4C'))
			engine.declare(Fact(stage='4C', condition='fragment', value='10%-20%'))
			engine.declare(Fact(stage='4C', condition='time', value='32'))
			engine.run()
			self.assertEqual(engine.score, 70)


	if __name__ == '__main__':
	    unittest.main()

It raises a AttributeError: 'Rule' object has no attribute 'name' when engine.run() on engine.py line 162

	watchers.RULES.info(
         "FIRE %s %s: %s",
         execution,
         activation.rule.__name__,
         ", ".join(str(f) for f in activation.facts))

I can't find out what the problem is. Wonder if I can get some help here. THANKS.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions