[Tutor] Nested loops/test conditions

Paul Sidorsky paulsid@shaw.ca
Sun, 10 Feb 2002 12:48:58 -0700


Chris Keelan wrote:

> So I need to write two loops, I think. The first loop should parse the
> file line-by-line to find the start condition e.g., <Chapter1> then
> write each line from that point to the end condition </Chapter1> to a
> separate file.

For this kind of thing I would use a single state-based loop.  I've
rewritten your code with such a loop below.  It should be fairly
self-explanatory.  The gist of it is that the loop does different things
based on the setting of the variable called 'state', which kind of
allows it to act like two loops at once.

This technique is simple yet very powerful.  You can get really fancy
with it, like putting the action for each state in a function and using
a dictionary of functions (e.g. 
funcdict = {STATE_1: func_1, STATE_2: func_2}) and then calling
funcdict[state]() on each iteration.  This is very useful for when there
are lots of states as it keeps the code for each state well-separated
and the loop very clean.

Hope this helps.  (Code below is untested.)

*********

#!/usr/bin/python

import os
import string

#startCond = '<Chapter1>'
#exitCond = '</Chapter1>'

startchapter = 1

def set_conditions(ch)
    return ("<Chapter%i>" % ch, "</Chapter%i>" % ch)

testFile = '/shared/docs/testtext'

def fix_string(badString):     # need this to strip newlines, etc.
    goodString = string.split(badString)
    goodString = string.join(goodString)
    return goodString

# State variables.
FIND_START = 1
WRITE_LINES = 2

def parse_file(inHandle, ch)
    startCond, exitCond = set_conditions(ch)
    state = FIND_START
    for line in inHandle.readlines():
        line = fix_string(line)
        if state == FIND_START:
            if line == startCond:
                state = WRITE_LINES
        elif state == WRITE_LINES:
            if line == exitCond:
                ch += 1
                startCond, exitCond = set_conditions(ch)
                state = FIND_START
            else:
                print line
        else:
            print "ERROR - Invalid State"
            
def main():
    inHandle = open(testFile, 'r')
    parse_file(inHandle, startchapter)
    inHandle.close()

if __name__ == "__main__":
    main()

-- 
======================================================================
Paul Sidorsky                                          Calgary, Canada
paulsid@shaw.ca                        http://members.shaw.ca/paulsid/