add kv pyparsing test
This commit is contained in:
171
codegrab/kv.py
Normal file
171
codegrab/kv.py
Normal file
@@ -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()
|
||||||
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user