The expression is given as such:
e = Plus(Plus(Const(3),Const(4)),Const(5))
if I print(e) it should give me:
print(e)
(3 4) 5
My code is this, my logic is that for parent class value of prec is 0 so that when the class is evaluating inner Plus it should introduce '( )' as shown in the if-statment. Kindly correct my code. I am beginner here.
class Expr:
prec=0
def __str__(self):
if self.prec>prec:
return "(" str(self.l) self.op str(self.r) ")"
else:
return str(self.l) self.op str(self.r)
class Plus(Expr) :
op=' '
prec=1
def __init__(self,l,r) :
self.l = l
self.r = r
class Const(Expr) :
def __init__(self,v) :
self.v = v
def __str__(self):
return str(self.v)
e = Plus(Plus(Const(3),Const(4)),Const(5))
print(e)
#(3 4) 5
CodePudding user response:
It looks like prec should be a parameter passed to the __str__ function.
class Expr:
def __init__(self):
self.prec = 0
self.nb_operands = 0
def __str__(self, prec=0):
if self.nb_operands == 0:
return str(self.v)
elif self.nb_operands == 1:
return self.op self.v.__str__(self.prec)
elif self.nb_operands == 2:
if self.prec < prec:
return ''.join([
"(",
self.l.__str__(self.prec),
self.op,
self.r.__str__(self.prec),
")"
])
else:
return self.op.join((
self.l.__str__(self.prec),
self.r.__str__(self.prec)
))
class Plus(Expr) :
def __init__(self,l,r) :
self.op = ' '
self.prec = 1
self.nb_operands = 2
self.l = l
self.r = r
class Times(Expr) :
def __init__(self,l,r) :
self.op = '*'
self.prec = 2
self.nb_operands = 2
self.l = l
self.r = r
class Minus(Expr) :
def __init__(self,v) :
self.op = '-'
self.prec = 1
self.nb_operands = 1
self.v = v
class Const(Expr) :
def __init__(self,v) :
self.prec = 0
self.v = v
self.nb_operands = 0
Testing:
print( Plus(Plus(Const(3),Const(4)),Const(5)) )
3 4 5
print( Plus(Times(Const(3),Const(4)),Const(5)) )
3*4 5
print( Times(Plus(Const(3),Const(4)),Const(5)) )
(3 4)*5
print( Times(Plus(Const(3),Const(4)),Minus(Const(5))) )
(3 4)*-5
CodePudding user response:
This is a supplement to @Stef's terrific answer. I wanted to show a way to keep the class code simple while maintaining the elegance of her/his recursive process -
class Expr:
def __init__(self):
self.prec = 0
self.nb_operands = 0
def __str__(self):
return to_str(self) # keep classes simple
Where to_str is defined as an ordinary function. Avoiding over a dozen instances of self and manual calls to __str__ improves readability -
def to_str(e, prec=0):
match e.nb_operands:
case 0:
return str(e.v)
case 1:
return e.op to_str(e.v, e.prec)
case 2:
if e.prec < prec:
return ''.join([
"(",
to_str(e.l, e.prec),
e.op,
to_str(e.r, e.prec),
")"
])
else:
return e.op.join([
to_str(e.l, e.prec),
to_str(e.r, e.prec)
])
