A
Antoon Pardon
The following is a proof of concept. The idea is to have variables that
represent symbolic names/expressions, you can work with like ordinary
values, but that can be evaluated later.
This is the code:
------------------------------------------------------------------------
import operator
from functools import partial
class Expression (object) :
def __add__(self, term):
return Binary(self, operator.__add__, term)
def __getattr__(self, name):
op = getattr(operator, name)
return partial(Binary, self, op)
class Binary (Expression) :
def __init__(self, left, op, right):
self.left = left
self.operator = op
if not isinstance(right, Expression):
right = Value(right)
self.right = right
def eval(self, dct):
left = self.left.eval(dct)
right = self.right.eval(dct)
return self.operator(left, right)
class Symbol (Expression):
def __init__(self, name):
self.name = name
def eval(self, dct={}):
return dct[self.name]
class Value (Expression):
def __init__(self, val):
self.value = val
def eval(self, dct={}):
return self.value
def test():
dct = {"var1" : 5, "var2" : 7}
val1 = Symbol("var1")
val2 = Symbol("var2")
print val1.eval(dct)
sum = val1 + 3
print sum.eval(dct)
sum = sum + val2
print sum.eval(dct)
product = val1 * 7
print product.eval(dct)
test()
--------------------------------------------------------------------------
The result I get is:
5
8
15
Traceback (most recent call last):
File "Symbolics", line 54, in <module>
test()
File "Symbolics", line 51, in test
product = val1 * 7
TypeError: unsupported operand type(s) for *: 'Symbol' and 'int'
What I had hoped for was, that the line:
product = val1 * 7
would be translated into something like
product = val1.__mul__(7)
which would then be treated by the __getattr__ of the Expression superclass.
That doesn't seem to happen.
Does anyone have another idea, so I can get this to work without having
to manually add all numeric special methods to the Expression class.
represent symbolic names/expressions, you can work with like ordinary
values, but that can be evaluated later.
This is the code:
------------------------------------------------------------------------
import operator
from functools import partial
class Expression (object) :
def __add__(self, term):
return Binary(self, operator.__add__, term)
def __getattr__(self, name):
op = getattr(operator, name)
return partial(Binary, self, op)
class Binary (Expression) :
def __init__(self, left, op, right):
self.left = left
self.operator = op
if not isinstance(right, Expression):
right = Value(right)
self.right = right
def eval(self, dct):
left = self.left.eval(dct)
right = self.right.eval(dct)
return self.operator(left, right)
class Symbol (Expression):
def __init__(self, name):
self.name = name
def eval(self, dct={}):
return dct[self.name]
class Value (Expression):
def __init__(self, val):
self.value = val
def eval(self, dct={}):
return self.value
def test():
dct = {"var1" : 5, "var2" : 7}
val1 = Symbol("var1")
val2 = Symbol("var2")
print val1.eval(dct)
sum = val1 + 3
print sum.eval(dct)
sum = sum + val2
print sum.eval(dct)
product = val1 * 7
print product.eval(dct)
test()
--------------------------------------------------------------------------
The result I get is:
5
8
15
Traceback (most recent call last):
File "Symbolics", line 54, in <module>
test()
File "Symbolics", line 51, in test
product = val1 * 7
TypeError: unsupported operand type(s) for *: 'Symbol' and 'int'
What I had hoped for was, that the line:
product = val1 * 7
would be translated into something like
product = val1.__mul__(7)
which would then be treated by the __getattr__ of the Expression superclass.
That doesn't seem to happen.
Does anyone have another idea, so I can get this to work without having
to manually add all numeric special methods to the Expression class.