On Aug 31, 5:51 pm, Daniel <dali...@gmail.com> wrote: > Dear All, > > I have some complicated loops of the following form > > for c in configurations: # loop 1 > while nothing_bad_happened: # loop 2 > while step1_did_not_work: # loop 3 > for substeps in step1 # loop 4a > # at this point, we may have to > -leave loop 1 > -restart loop 4 > -skip a step in loop 4 > -continue on to loop 4b > > while step2_did_not_work: # loop 4b > for substeps in step2: > # at this point, we may have to > -leave loop 1 > -restart loop 2 > -restart loop 4b > ... > ...many more loops... > > I don't see any way to reduce these nested loops logically, they > describe pretty well what the software has to do. > This is a data acquisition application, so on ever line there is > a lot of IO that might fail or make subsequent steps useless or > require a > retry. > > Now every step could need to break out of any of the enclosing loops. > So basically I have to transform every loop to be of the following > horror: > > # general transformation of > # "for c in configurations..." > # to provide restart, break and continue > # callable from any nesting level inside of the loop > > class loop1_restart(Exception): pass > class loop1_break(Exception): pass > class loop1_continue(Exception): pass > > while True: > try: > for c in configurations: > while True: > try: > # inner loops go here, of course, they would have > to get > # all the boilerplate added, too > while nothing_bad_happened: > while step1_did_not_work: > if cond1: > raise loop1_restart() > elif cond3: > raise loop1_break() > elif cond3: > raise loop1_continue() > > break > > except loop1_continue: > pass > break > except loop1_restart: > pass > except loop1_break: > break > > Of course this is extremely tedious and error prone. > If Python had named loops (PEP 3136, unfortunately rejected), this > would be trivial: > In Fortran I can continue (cycle), break (exit) and redo (goto label) > arbitrary > loops, which results in neat code: > > 10 loop1: do I=1,3 > loop2: do J=1,4 > print *,I,J > goto 10 > cycle loop1 > exit loop1 > enddo loop2 > enddo loop1 > > My question is, how do I obtain something that implements the > following logic: > > @named_loop(fred) # I wish this would be possible > for i in range(10): > for j in range(10): > break fred # breaks out of outer loop > continue fred # continues outer loop > redo fred # resets outer loop and restarts with i=0 > > The best solution would be something along the Proposal D - Explicit > iterators > in PEP 3136, in this case it would even be possible to peek at the > next i or > advance/reverse the iterator a few steps. > > Has anyone an idea on a nice way to write breaks/continues/redos for > deeply > nested loops?
Hi Dan, it looks like you have already answered all your questions. one more idea, a kind of named loop: ic=0 op='what to do' while ic<len(configurations): c=configuration[ic] if op=='restart': ic=0 elif op=='next' ic+=1 elif op=='terminate' ic=len(configurations) and at first explicit iterator was also a good idea, when you don't need to iter in reverse order When it become too complicate, I use state machine: http://en.wikipedia.org/wiki/Finite-state_machine Regards > > Dan -- http://mail.python.org/mailman/listinfo/python-list