Python programming "deferred settlement"

This is a two-part python question. The first part is devoted to aesthetics, the second - to implementation. The sample code I received so far is attached at the bottom.

Problem.

I am trying to create a python module / class that allows me to do lazy calculations / pending calculations. After setting up these calculations, I would like to determine exactly why the answer is as it is, as well as change the inputs of the functions and recalculate the output without having to redefine the intermediate variables.

In essence, I would like to do something as close to this as possible:

>>> a=3 >>> b=5 >>> c=a+b >>> c 8 >>> a = 6 >>> c 11 

and stuff like

 >>> c.calculation 'a [ 6 ] + b [ 5 ] = 11' 

Now I'm not worried about circular dependencies (for now), and the closest I got above:

 a = constant(2) b = constant(3) c = a + b d = a * b 

and it gives me things like:

 c is 5 [ 2 <built-in function __add__> 3 ] d is 6 [ 2 <built-in function __mul__> 3 ] 

which is not perfect, but it is approaching. Then I change the values โ€‹โ€‹of a and b to recalculate the values โ€‹โ€‹of c, d

I know that I cannot use assignment to change the value of a, b without completely overwriting it, so things like a = 2, b = 3.

Q1: Aesthetics: What is the best way to write this so that it is the most obvious (pythonic?) Way for the client to use?

Further, if you look at the code below, you will see that I just implemented the operators for add and mul, but I would like to reproduce this for (preferably) all the built-in operators.

Q2: Implementation: What is the best way for me to code this?

Ultimately, I would like to be able to make some matrix products / amounts using this library.

I understand that this will be the memory of God, but for me it is more important for me to explain โ€œhow this number ultimately is xโ€ than the memory usage / processor cycles.

 import operator class operable(object): def __add__(self,other): if isinstance(other,operable): d = calculation() d.operator = operator.__add__ d.operands = [self,other] return d def __mul__(self,other): if isinstance(other,operable): d = calculation() d.operator = operator.__mul__ d.operands = [self,other] return d class calculation(operable): def __init__(self): self.operands = [] self.operator = None @property def value(self): return reduce(self.operator, [x.value for x in self.operands]) @property def calculation(self): return (" %s " % str(self.operator)).join([x.__repr__() for x in self.operands]) def __repr__(self): return "%d [ %s ] " % ( self.value, self.calculation ) class constant(operable): def __init__(self, x = 0): self._value = x def __repr__(self): return "%d" %( self.value) @property def value(self): return self._value @value.setter def value(self,new_val): self._value = new_val def test_1(): a = constant(2) b = constant(3) c = a + b d = a * b z = a + b + c + d print "c is",c print "d is",d print "z is ",z b.value = 5 print "c is now",c print "d is now",d print "z is now ",z if __name__ == "__main__": test_1() 
+4
source share
1 answer

I really like Raymond Hettinger's approach to a similar problem:

 class SpreadSheet: _cells = {} tools = {} def __setitem__(self, key, formula): self._cells[key] = formula def getformula(self, key): return self._cells[key] def __getitem__(self, key ): return eval(self._cells[key], SpreadSheet.tools, self) >>> from math import sin, pi >>> SpreadSheet.tools.update(sin=sin, pi=pi, len=len) >>> ss = SpreadSheet() >>> ss['a1'] = '5' >>> ss['a2'] = 'a1*6' >>> ss['a3'] = 'a2*7' >>> ss['a3'] 210 >>> ss['b1'] = 'sin(pi/4)' >>> ss['b1'] 0.70710678118654746 >>> ss.getformula('b1') 'sin(pi/4)' 

Taken from: http://code.activestate.com/recipes/355045-spreadsheet/

+1
source

Source: https://habr.com/ru/post/1502033/


All Articles