[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/