On Mon, Jun 6, 2016 at 6:51 PM, Lawrence D’Oliveiro
<lawrenced...@gmail.com> wrote:
> On Sunday, June 5, 2016 at 11:43:20 PM UTC+12, Marko Rauhamaa wrote:
>> I often experiment with different loop constructs to find the one most
>> pleasing to the eye. Working directly off iterators is quite rare but a
>> while-vs-for consideration is frequent. Also, should the stepping part
>> be in the beginning, middle or end of the loop body?
>
> It is nice to have a common, versatile looping form which can be arranged in 
> different ways to suit the problem at hand. That’s why I like the C-style 
> for-statement.
>
> Here’s another example 
> <https://github.com/ldo/ipy_magics/blob/master/rman_magic.py>, for the 
> consideration of those who don’t seem too familiar with looping:

A 500-line function? Yikes, what an eyesore. When you have to include
#end comments in order to visually match things up, that should be a
smell that your code is excessively complex. It took me a lot of
scrolling up and down just to figure out what the scopes of the
variables were.

>     while True :
>         while True :
>             line = next(input_line, None)
>             if line != None :
>                 if len(include_stack) == 0 :
>                     linenr += 1
>                 #end if
>                 break
>             #end if
>             if len(include_stack) == 0 :
>                 break
>             input_line = include_stack.pop()
>         #end while
>         if line == None or ... line contains something special ... :
>             ...
>             if line == None :
>                 break
>             ... process special line ...
>             ... replace with None to indicate it’s been processed ...
>         #end if
>         if line != None :
>             ... process regular line ...
>         #end if
>     #end while

    def generate_lines():
        nonlocal input_line
        while True:
            try:
                # Note input_line appears to be an iterator, not a string
                # as suggested by the name.
                yield next(input_line)
            except StopIteration:
                if include_stack:
                    input_line = include_stack.pop()
                else:
                    return

    for line in generate_lines():
        if not include_stack:
            linenr += 1
        if ... line contains something special ...:
            ... process special line ...
        else:
            ... process regular line ...

Much simpler than the nested while loop hell above, and not a single
break needed (if you don't count the return, that is; in any case each
loop has a single exit point). I'd be tempted to refactor input_line
and include_stack into some sort of input context class and make
generate_lines a method of the class in order to avoid having those
variables be (effectively) global, but my goal was to keep this as
close to the original in design as possible.
-- 
https://mail.python.org/mailman/listinfo/python-list

Reply via email to