Last active
August 29, 2021 21:17
-
-
Save fabian-paul/2647b3ea142c2db0efbe6dc60763d0aa to your computer and use it in GitHub Desktop.
switch_network_renderer
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Renderer: | |
def __init__(self, root): | |
self.root = root | |
def svg(self): | |
leftmost = self.root.leftmost(0) | |
s = min(300 / self.root.w, 300 / self.root.h) | |
svg = f""" | |
<!DOCTYPE html> | |
<html> | |
<body> | |
<svg height="300" width="300"> | |
<g transform="scale({s} {s})"> | |
{self.root.svg(-leftmost, 0, 1, 1)} | |
</g> | |
</svg> | |
</body> | |
</html> | |
""" | |
return svg | |
def _repr_html_(self): | |
return self.svg() | |
class Op: | |
style = 'stroke:rgb(255,0,0); stroke-width:0.1' | |
class And(Op): | |
def __init__(self, *children): | |
self.children = children | |
@property | |
def h(self): | |
return sum(child.h for child in self.children) | |
@property | |
def w(self): | |
return max(child.w for child in self.children) | |
def leftmost(self, x0): | |
return min(child.leftmost(x0) for child in self.children) | |
def svg(self, x0, y0, sx, sy) -> str: | |
y = y0 | |
svg = '' | |
for child in self.children: | |
svg += child.svg(x0=x0, y0=y, sx=sx, sy=sy) | |
y += child.h*sy | |
return svg | |
class Or(Op): | |
def __init__(self, *children): | |
self.children = children | |
@property | |
def h(self): | |
return max(child.h for child in self.children) | |
@property | |
def w(self): | |
return sum(child.w for child in self.children) | |
def leftmost(self, x0): | |
return x0 - self.w/2 | |
# shrinking does not work... | |
def svg(self, x0, y0, sx, sy) -> str: | |
leftmost = x0 - self.w/2 + self.children[0].w / 2 | |
x = leftmost | |
svg = '' | |
h = self.h | |
for k, child in enumerate(self.children): | |
#print(dict(x0=x, y0=y0, sx=sx, sy=sy*(h/child.h))) | |
svg += child.svg(x0=x, y0=y0, sx=sx, sy=sy*(h/child.h)) | |
if k + 1 < len(self.children): | |
x += child.w / 2 + self.children[k+1].w / 2 | |
svg += f'<line x1="{leftmost}" y1="{y0}" x2="{x}" y2="{y0}" style="{self.style}" />' | |
svg += f'<line x1="{leftmost}" y1="{y0 + sy*h}" x2="{x}" y2="{y0 + sy*h}" style="{self.style}" />' | |
return svg | |
class Element(Op): | |
def __init__(self, name: str, w=1.): | |
self.h = 1. | |
self.w = w | |
self.name = name | |
def leftmost(self, x0): | |
return x0 | |
def svg(self, x0, y0, sx, sy) -> str: | |
x1 = x0 + 0. | |
y1 = y0 + 0. | |
x2 = x0 + 0. | |
y2 = y0 + self.h*sy | |
#print(dict(x1=x1, y1=y1, x2=x2, y2=y2)) | |
# <rect x="{x0}" y="{}" width="{}" height="{}" fill="red"></rect> | |
# <rect x="{x0}" y="{y0 + 0.25*self.h*sy}" width="{self.w}" height="{self.h / 2}" stroke="red" stroke-width="0.01px" fill="white"/> | |
svg = f""" | |
<line x1="{x1}" y1="{y1}" x2="{x2}" y2="{y2}" style="{self.style}" /> | |
<text x="{x0}" y="{y0 + self.h*sy*0.5}" font-family="Verdana" | |
dominant-baseline="middle" text-anchor="middle" font-size="0.4" fill="blue">{self.name}</text> | |
""" | |
# | |
return svg | |
#f'<circle cx="{x1}" cy="{y0 + 0.5*sy}" r="0.05" stroke="black" />' | |
import pyparsing as pp | |
expression = pp.Forward() | |
word = pp.Word(pp.alphas) | |
word.setParseAction(lambda c: Element(c.asList()[0])) | |
pure_value = (pp.Suppress("(") + expression + pp.Suppress(")")) | word | |
negated_value = pp.Suppress(pp.Literal('not')) + pure_value | |
negated_value.setParseAction(lambda c: ('not', c.asList()[0])) | |
value = negated_value | pure_value | |
true_conjunction = value + pp.OneOrMore(pp.Suppress("and") + value) | |
true_conjunction.setParseAction(lambda c: And(*c.asList())) | |
conjunction = true_conjunction | value | |
true_disjunction = (conjunction + pp.OneOrMore(pp.Suppress("or") + conjunction)) | |
true_disjunction.setParseAction(lambda c: Or(*c.asList())) | |
disjunction = (true_disjunction | conjunction) | |
expression <<= disjunction | |
string = pp.StringStart() + expression + pp.StringEnd() | |
e = Element('nm') | |
#x = Or(Or(And(Or(e,e,e),e,Or(e,e)), e), | |
# And(And(Or(e,e),e,Or(e,e,e)), e),e) | |
#Renderer(Or(Or(And(Or(x,e,e),x,Or(e,e)), e), | |
# And(And(Or(x,e),e,Or(e,e,e)), e),x)) | |
#x = Or(And(And(Or(e,e),e),Or(e,e)), And(e,Or(e))) | |
#Renderer(And(Or(And(Or(e,x),e),Or(e,x)), Or(e,And(e)))) | |
x = And(Element('re',5), Or(e, e)) | |
#y = And(x, Or(And(x, Or(x,e)), And(x, Or(e,e))), x) | |
#Renderer(y) | |
#Renderer(And(e, Or(e,e))) | |
#Renderer(Or(Or(And(Or(x,e,y),x,Or(e,e)), e), | |
# And(And(Or(x,e),e,Or(e,y,y)), e),x)) | |
for _ in range(3): | |
x = And(Or(e, x), Or(e, x)) | |
Renderer(x) | |
#TODO: add labels, combine... | |
#Renderer(list(string.parseString("abc and def or (zz or (x and (y or t)))"))[0]) | |
Renderer(list(string.parseString("(aaaa or bb and c or e) and f or g and (h or i) and j"))[0]) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment