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
-
1in general you do it with recursion. I have several answers about "nested loops" but they are mostly in Common Lisp or Scheme or Prolog (or Haskell). there's a whole tag for it, too, recursive-backtracking. then there's also this and this, in C++.Will Ness– Will Ness2020年07月18日 20:19:31 +00:00Commented Jul 18, 2020 at 20:19
-
1here's an answer with pseudocode creating n nested loops dynamically. see of any of this helps.Will Ness– Will Ness2020年07月18日 20:32:43 +00:00Commented Jul 18, 2020 at 20:32
2 Answers 2
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)
Comments
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.