From f973ef96fd3666c6a54167da3179bdbb40330593 Mon Sep 17 00:00:00 2001 From: TKE Date: Tue, 2 Mar 2021 19:11:13 +0100 Subject: [PATCH] add kv pyparsing test --- codegrab/kv.py | 171 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 171 insertions(+) create mode 100644 codegrab/kv.py diff --git a/codegrab/kv.py b/codegrab/kv.py new file mode 100644 index 0000000..931c555 --- /dev/null +++ b/codegrab/kv.py @@ -0,0 +1,171 @@ +import sys +from pyparsing import * +from icecream import ic + +sys.setrecursionlimit(3000) +ParserElement.enablePackrat() +ppc = pyparsing_common +integer = ppc.integer +variable = Word(alphas, exact=1) +operand = integer | variable + +undop = Literal("*") +oderop = Literal("+") +notop = Literal("!") + +expr = infixNotation( + operand, + [ + (notop, 1, opAssoc.RIGHT), + (undop, 2, opAssoc.LEFT), + (oderop, 2, opAssoc.LEFT), + ], +) + + +class operation(): + + def _unpack(self,data): + if isinstance(data,str): + if len(data) == 1: + return data + else: + raise ValueError + else: + return operation(data) + + def __init__(self,data) -> None: + if isinstance(data,str): + data=expr.parseString(data.lower().strip()).asList() + + self.operands = [] + self.operator = "" + if isinstance(data,list): + if len(data) == 1: + data = data[0] + + if isinstance(data,list): + if len(data) == 2: + self.operator = data[0] + self.operands.append(self._unpack(data[1])) + + if len(data) >2: + self.operator = data[1] + for x in data: + if x == self.operator: + continue + else: + self.operands.append(self._unpack(x)) + else: + raise ValueError + + + def __tt(vars): + if len(vars) == 1: + yield {vars[0] : False} + yield {vars[0] : True} + else: + for rv in operation.__tt(vars[1:]): + yield {vars[0] : False, **rv } + yield {vars[0] : True, **rv } + + + + def print_tt(self): + myvars = self.get_vars() + print(" " + " ".join(myvars)+ " Y") + print("--" * len(myvars) + "-----") + tt=operation.__tt(myvars) + for line in tt: + r=[f"{'1' if line[x] else '0'}" for x in line] + result="1" if self.solve(line) else "0" + print(" " + " ".join(r) + " " + result) + + + + def __repr__(self) -> str: + if self.operator == "!": + return f"NICHT {self.operands[0]}" + else: + if self.operator == "*": + return "(" + " UND ".join([str(x) for x in self.operands]) + ")" + + if self.operator == "+": + return "(" + " ODER ".join([str(x) for x in self.operands]) + ")" + + def solve(self,values): + for vary in self.get_vars(): + if not vary in values: + raise KeyError + if self.operator == '!': + if isinstance(self.operands[0],operation): + return not self.operands[0].solve(values) + else: + return not values[self.operands[0]] + + if self.operator == '*': + result = True + for operand in self.operands: + if isinstance(operand,operation): + result = result and operand.solve(values) + else: + result = result and values[operand] + return result + + if self.operator == '+': + result = False + for operand in self.operands: + if isinstance(operand,operation): + result = result or operand.solve(values) + else: + result = result or values[operand] + return result + + + + def get_vars(self): + vars = [] + for x in self.operands: + if isinstance(x,operation): + vars += x.get_vars() + else: + vars.append(x) + return list(dict.fromkeys(vars)) + + + @property + def hasop(self): + return len(self.operator)>0 + + + + +test = [ + "(a*b+(a*(!c+b))*c)", + "a*b+(a*(!c+b)*c)", + "a *b+ ( a * ( ! c + (b) ) *c)", + "a*b+c+d", + "a*b+c", + "!a*!(a+b*!c)", +] + +testval={'a':True,'b':False,'c':True, 'd':False} + +def tt(vars): + if len(vars) == 1: + yield {vars[0] : False} + yield {vars[0] : True} + else: + for rv in tt(vars[1:]): + yield {vars[0] : False, **rv } + yield {vars[0] : True, **rv } + + + + +for t in test: + ic(t) + c=operation(t) + c.print_tt() + +