Reputation: 219
I'm trying to iterate through multiple generators that are dynamically generated, in the order as specified in the user code.
I want to modify run()
so that it can support n number of tasks, as opposed to three as of now. I tried using itertools.product()
but I'm not sure how to call next()
on my generators one at a time.
I think I will have to use recursion here but I'm not sure how to proceed. Any points are greatly appreciated.
class ImageSeries:
def __init__(self):
self.tasks = []
def xy(self, position):
print(f"xy: {position}")
yield "xy"
def z(self, position):
print(f"z: {position}")
yield "z"
def exp(self, exposure):
print(f"exp: {exposure}")
yield "exposure"
def xy_scan(self, positions):
self._xy_task = lambda: (self.xy(pos) for pos in positions)
self.tasks.append(self._xy_task)
def z_scan(self, positions):
self._z_task = lambda: (self.z(pos) for pos in positions)
self.tasks.append(self._z_task)
def exp_scan(self, exposures):
self._exp_task = lambda: (self.exp(e) for e in exposures)
self.tasks.append(self._exp_task)
def run(self):
for generator_0 in self.tasks[0]():
next(generator_0)
for generator_1 in self.tasks[1]():
next(generator_1)
for generator_2 in self.tasks[2]():
next(generator_2)
def __repr__(self):
return str(self.self.tasks)
if __name__ == "__main__":
s = ImageSeries()
positions = [[0, 0], [100, 100], [1000, 1000]]
s.xy_scan(positions)
s.exp_scan([50, 100, 150])
s.z_scan([0, 100, 1000, 10000])
s.run()
My desired output is:
xy: [0, 0]
exp: 50
z: 0
z: 100
z: 1000
z: 10000
exp: 100
z: 0
z: 100
z: 1000
z: 10000
exp: 150
z: 0
z: 100
z: 1000
z: 10000
xy: [100, 100]
exp: 50
z: 0
z: 100
z: 1000
z: 10000
exp: 100
z: 0
z: 100
z: 1000
z: 10000
exp: 150
z: 0
z: 100
z: 1000
z: 10000
xy: [1000, 1000]
exp: 50
z: 0
z: 100
z: 1000
z: 10000
exp: 100
z: 0
z: 100
z: 1000
z: 10000
exp: 150
z: 0
z: 100
z: 1000
z: 10000
Upvotes: 1
Views: 79
Reputation: 650
Here is the recursive function where n should be start with 0
def run(self,n):
for generator in self.tasks[n]():
next(generator)
m=n+1
if m < len(self.tasks):
self.run(m)
Upvotes: 1
Reputation: 320
How about modifying the for
loop in run
method as below,
def get_task(self):
for task in self.tasks:
yield task()
def loop_over(self, generator_obj):
for generator in generator_obj:
next(generator)
self.loop_over(self.get_task())
def run(self):
self.loop_over(self.get_task())
This will ensure that all the n
number of tasks are called.
Upvotes: 1