Skip to content

Instantly share code, notes, and snippets.

@danielSanchezQ
Created September 23, 2018 12:13
Show Gist options
  • Save danielSanchezQ/91aecf65110d1a0319584d83fa5ed9c6 to your computer and use it in GitHub Desktop.
Save danielSanchezQ/91aecf65110d1a0319584d83fa5ed9c6 to your computer and use it in GitHub Desktop.
batching operations groping method
#! /user/bin/python3
from collections import defaultdict
from itertools import groupby
import operator
class Operation(object):
TAPE = []
RECORD = defaultdict(lambda: 0)
RESULTS = {}
OPERATIONS = {
operation : getattr(operator, operation) for operation in ("add", "sub", "mul", "truediv")
}
def __init__(self, op, *args):
self.op = op
self.args = args
self.evalDependancies(*args)
self.TAPE.append(self)
def run(self):
args = [self.RESULTS.get(v, v) for v in self.args]
res = self.OPERATIONS[self.op](*args)
self.RESULTS[self] = res
return res
def evalDependancies(self, *args):
level = max(self.RECORD[arg] for arg in args)
self.RECORD[self] = level+1
@classmethod
def reset(cls):
cls.TAPE = []
cls.RECORD = defaultdict(lambda: 0)
@classmethod
def getOrderedTape(cls):
return sorted(cls.TAPE, key=lambda x: cls.RECORD[x])
@classmethod
def runOrderedTape(cls):
return (x.run() for x in cls.getOrderedTape())
@classmethod
def batchOrderedTape(cls):
results = []
for batch, operations in groupby(orderedTape, key=lambda x: Operation.RECORD[x]):
for op in operations: #here can be parallelized also
results.append(op.run())
return results
if __name__ == "__main__":
a = 5
b = 10
op1 = Operation("add", a, b)
c = 100
op2 = Operation("sub", c, op1)
op3 = Operation("mul", a, b)
op4 = Operation("mul", op2, op3)
from pprint import pprint
pprint(Operation.TAPE)
pprint(Operation.RECORD)
orderedTape = Operation.getOrderedTape()
pprint(list(Operation.runOrderedTape()))
pprint(Operation.batchOrderedTape())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment