1

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
asked Jul 18, 2020 at 19:07
2
  • 1
    in 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++. Commented Jul 18, 2020 at 20:19
  • 1
    here's an answer with pseudocode creating n nested loops dynamically. see of any of this helps. Commented Jul 18, 2020 at 20:32

2 Answers 2

1

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)
answered Jul 18, 2020 at 20:14
Sign up to request clarification or add additional context in comments.

Comments

1

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.

answered Jul 18, 2020 at 19:12

2 Comments

Each tasks are to be nested and looped over. This will only loop over all the tasks once, and not produce the desired output.
@pskeshu, have edited my answer now. Hope it helps you.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.