A simple lazy Python Calculation Engine.
The module is still in development. You can install it by cloning this repository and using the poetry install command.
git clone git@github.com:bsdz/calcengine.git
cd calcengine
python3 -mvenv --prompt calceng .venv
. ./.venv/bin/activate
poetry installAlternatively, you can add to your existing poetry project:
poetry add git+https://github.com/bsdz/calcengine.gitOr install via pip:
pip install git+https://github.com/bsdz/calcengine.git#masterThe core module for the calculation engine only uses core python standard library.
The demo spreadsheet application uses pyqt5, pandas, matplotlib and pillow.
First instantiate a CalcEngine and use watch decorator
to register functions as nodes. Note that a function along
with any arguments and keyword arguments make a unique node.
fromcalcengineimportCalcEnginece=CalcEngine()
@ce.watch()defa():
print("..in a")
return100@ce.watch()defb():
print("..in b")
returna() @ce.watch()defc(x, y):
print(f"..in c with x={x} and y={y}")
return2*a() +x*y@ce.watch()defd(x, y=0):
print(f"..in d with x={x} and y={y}")
return3*b() +x-y@ce.watch()defe():
print("..in e")
_x=d(5, y=-3)
returnc(2, 3) -5+_x@ce.watch()deff():
print("..in f")
returnd(0) +e()Calling a function will cache all values and path during first run.
>>>f()
..inf
..indwithx=0andy=0
..inb
..ina
..ine
..indwithx=5andy=-3
..incwithx=2andy=3809And obviously a 2nd invocation will retrieve the final value from cache.
>>>f()
809Invalidating a node by calling function helper method.
>>>e.invalidate()
>>>f()
..inf
..ine809Invalidating a node without arguments if previous call did have arguments won't have any effect.
>>>d.invalidate()
>>>f()
809Whereas with arguments specified exactly as prior call will. Note the sensitivity of argument specification.
>>>d.invalidate(5, y=-3)
>>>f()
..inf
..ine
..indwithx=5andy=-3809It is also possible to add a trigger that will be called on completion of a function. This might be used to produce some form of data binding in applications.
defmy_trigger(res):
print(f"got {res}")
>>>c.node_calculated.append(my_trigger)
>>>c.invalidate(2, 3)
>>>f()
callfcallecallcwithx=2andy=3got206809Included is a simple spreadsheet demo. Read more here
To install the dependencies required by the demo. When cloning this repo also include the "demo" extras.
poetry install -E demo
python demo/spreadsheet/main.py- Support watching global variables.
- Support multiprocessing.
- Support asyncio?.
Some similar packages spotted. None of them tested.
