Re: [Tutor] Working with lines from file and printing to another keeping sequential order
Le Mon, 27 Apr 2009 23:29:13 -0400, Dan Liang s'exprima ainsi: > Hi Bob, Shantanoo, Kent, and tutors, > > Thank you Bob, Shantanoo, Kent for all the nice feedback. Exception > handling, the concept of states in cs, and the use of the for loop with > offset helped a lot. Here is the code I now have, based on your suggestions, > and it does what I need: > > ListLines = [ line.rstrip() for line in open('test.txt') ] > > countYes = 0 > countNo = 0 > > for i in range(len(ListLines)): > if ListLines[i].endswith('yes'): > countYes+=1 > print "countYes", countYes, "\t\t", ListLines[i] > > if not ListLines[i].endswith('yes'): > continue > > for offset in (1, 2, 3, 4, 5, 6, 7, 8): > if i+offset < len(ListLines) and ListLines[i+offset].endswith('no'): > >countNo+=1 > >print "countNo", countNo, "\t\t", ListLines[i+offset] It probably works, but there is something uselessly complicated, logically speaking: -1- case ends with 'yes', do -2- case not ends with 'yes', do -3- case ends with 'yes', again, do You'd better group -1- and -3-, no? Moreover, as action -2- is to continue, further code is simplified if -2- is placed first: for i in range(len(ListLines)): if not ListLines[i].endswith('yes'): continue # case line ends with 'yes': process it countYes+=1 print "countYes", countYes, "\t\t", ListLines[i] for offset in (1, 2, 3, 4, 5, 6, 7, 8): if i+offset < len(ListLines) and ListLines[i+offset].endswith('no'): countNo+=1 print "countNo", countNo, "\t\t", ListLines[i+offset] Also, use more than 1 space for indent, and be consistent (set the value in your editor settings and use the TAB key to achieve that); and avoid too many useless blank lines. Denis -- la vita e estrany ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Working with lines from file and printing to another keeping sequential order
Hi Bob, Shantanoo, Kent, and tutors, Thank you Bob, Shantanoo, Kent for all the nice feedback. Exception handling, the concept of states in cs, and the use of the for loop with offset helped a lot. Here is the code I now have, based on your suggestions, and it does what I need: ListLines = [ line.rstrip() for line in open('test.txt') ] countYes = 0 countNo = 0 for i in range(len(ListLines)): if ListLines[i].endswith('yes'): countYes+=1 print "countYes", countYes, "\t\t", ListLines[i] if not ListLines[i].endswith('yes'): continue for offset in (1, 2, 3, 4, 5, 6, 7, 8): if i+offset < len(ListLines) and ListLines[i+offset].endswith('no'): countNo+=1 print "countNo", countNo, "\t\t", ListLines[i+offset] Thank you again! --dan On Sun, Apr 26, 2009 at 10:55 AM, Kent Johnson wrote: > On Sat, Apr 25, 2009 at 2:11 PM, Dan Liang wrote: > > Hi Bob and tutors, > > > > Thanks Bob for your response! currently I have the current code, but it > does > > not work: > > > > ListLines= [] > > for line in open('test.txt'): > > line = line.rstrip() > > ListLines.append(line) > > This could be written with a list comprehension: > ListLines = [ line.rstrip() for line in open('test.txt') ] > > > > > for i in range(len(ListLines)): > > > > if ListLines[i].endswith("yes") and ListLines[i+1].endswith("no") and > > ListLines[i+1].endswith("no"): > > print ListLines[i], ListLines[i+1], ListLines[i+2] > > elif ListLines[i].endswith("yes") and ListLines[i+1].endswith("no"): > > print ListLines[i], ListLines[i+1] > > elif ListLines[i].endswith("yes"): > > print ListLines[i] > > elif ListLines[i].endswith("no"): > > continue > > else: > > break > > You only need to test for ListLines[i].endswith('yes') once. Then you > could use a loop to test for lines ending with 'no'. > > for i in range(len(ListLines)): > if not ListLines[i].endswith('yes'): >continue > for offset in (1, 2): >if i+offset < len(ListLines) and ListLines[i+offset].endswith('no'): > print ListLines[i+offset] > > You could adapt the above for a variable number of 'no' lines with > something like > for offset in range(1, maxNo+1): > > > I get the following error: > > Traceback (most recent call last): > > File "test.py", line 18, in > > if ListLines[i].endswith("yes") and ListLines[i+1].endswith("no") and > > ListLines[i+1].endswith("no"): > > IndexError: list index out of range > > That is because you have a 'yes' line at the end of the file so the > check for 'no' tries to read past the end of ListLines. In my code the > test for i+offset < len(ListLines) will prevent that exception. > > Kent > ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Working with lines from file and printing to another keeping sequential order
On Sat, Apr 25, 2009 at 2:11 PM, Dan Liang wrote: > Hi Bob and tutors, > > Thanks Bob for your response! currently I have the current code, but it does > not work: > > ListLines= [] > for line in open('test.txt'): > line = line.rstrip() > ListLines.append(line) This could be written with a list comprehension: ListLines = [ line.rstrip() for line in open('test.txt') ] > > for i in range(len(ListLines)): > > if ListLines[i].endswith("yes") and ListLines[i+1].endswith("no") and > ListLines[i+1].endswith("no"): > print ListLines[i], ListLines[i+1], ListLines[i+2] > elif ListLines[i].endswith("yes") and ListLines[i+1].endswith("no"): > print ListLines[i], ListLines[i+1] > elif ListLines[i].endswith("yes"): > print ListLines[i] > elif ListLines[i].endswith("no"): > continue > else: > break You only need to test for ListLines[i].endswith('yes') once. Then you could use a loop to test for lines ending with 'no'. for i in range(len(ListLines)): if not ListLines[i].endswith('yes'): continue for offset in (1, 2): if i+offset < len(ListLines) and ListLines[i+offset].endswith('no'): print ListLines[i+offset] You could adapt the above for a variable number of 'no' lines with something like for offset in range(1, maxNo+1): > I get the following error: > Traceback (most recent call last): > File "test.py", line 18, in > if ListLines[i].endswith("yes") and ListLines[i+1].endswith("no") and > ListLines[i+1].endswith("no"): > IndexError: list index out of range That is because you have a 'yes' line at the end of the file so the check for 'no' tries to read past the end of ListLines. In my code the test for i+offset < len(ListLines) will prevent that exception. Kent ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Working with lines from file and printing to another keeping sequential order
Dan Liang wrote: Hi Bob and tutors, Thanks Bob for your response! currently I have the current code, but it does not work: [snip] Thank you for code, sample data and more complete specs. Lines in the file look like following: word1 word2 word3 word4 yes word1 word2 word3 word4 no word1 word2 word3 word4 no word1 word2 word3 word4 no word1 word2 word3 word4 yes word1 word2 word3 word4 no word1 word2 word3 word4 yes word1 word2 word3 word4 no word1 word2 word3 word4 yes word1 word2 word3 word4 yes word1 word2 word3 word4 no word1 word2 word3 word4 no word1 word2 word3 word4 no word1 word2 word3 word4 yes word1 word2 word3 word4 no word1 word2 word3 word4 yes word1 word2 word3 word4 yes word1 word2 word3 word4 no word1 word2 word3 word4 no word1 word2 word3 word4 no word1 word2 word3 word4 no word1 word2 word3 word4 yes Any suggestions are appreciated. Also, I feel that my code is not the best way of solving the problem even if the problem of list indices is solved. Is my guess right? Yes indeed. In actuality you need only to examine one line at a time and keep track of the "state" of things. In computer theory we refer to a "state machine". There is a set of states. The program is always in exactly one of these states. In each state there are actions to take and a (conditional) moves to other states. the program starts in, let's say, state 0: state 0: open file, goto state 1. state 1: read next line, at eof goto state 6; if it ends in yes, goto state 2 else stay in state 1. state 2: read next line, at eof goto state 6; if it ends in yes stay in state 2 else goto state 3. state 3: read next line, at eof goto state 6. if it ends in yes goto state 2 else print line and goto state 4. state 4: read next line, at eof goto state 6. if it ends in yes goto state 2 else print line and goto state 5. state 5: read next line, at eof goto state 6. if it ends in yes goto state 2 else stay in state 5. state 6: close file and terminate That can be implemented in Python as follows. This is not the prettiest or most compact program, but is it a straightforward implementation of a state machine. state = 0 # initial state data = open('test.txt') while True: # iterate over lines if state == 0: # look for first line ending in 'yes' line = data.read().strip() if line: if line.endswith('yes'): state = 1 else state = 6 elif state == 1: # code for state i # more states elif state == 6: data.close() break To simplify things I'd create a function to read and strip a line and raise an exception at end of file. -- Bob Gailer Chapel Hill NC 919-636-4239 ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Working with lines from file and printing to another keeping sequential order
On 25-Apr-09, at 11:41 PM, Dan Liang wrote: Hi Bob and tutors, Thanks Bob for your response! currently I have the current code, but it does not work: ListLines= [] for line in open('test.txt'): line = line.rstrip() ListLines.append(line) for i in range(len(ListLines)): if ListLines[i].endswith("yes") and ListLines[i +1].endswith("no") and ListLines[i+1].endswith("no"): print ListLines[i], ListLines[i+1], ListLines[i+2] elif ListLines[i].endswith("yes") and ListLines[i +1].endswith("no"): print ListLines[i], ListLines[i+1] elif ListLines[i].endswith("yes"): print ListLines[i] elif ListLines[i].endswith("no"): continue else: break I get the following error: Traceback (most recent call last): File "test.py", line 18, in if ListLines[i].endswith("yes") and ListLines[i +1].endswith("no") and ListLines[i+1].endswith("no"): IndexError: list index out of range You need to put check for i <= len(ListLines)-2 or you can have a look @ try and except (exception handling in python) Lines in the file look like following: word1 word2 word3 word4 yes word1 word2 word3 word4 no word1 word2 word3 word4 no word1 word2 word3 word4 no word1 word2 word3 word4 yes word1 word2 word3 word4 no word1 word2 word3 word4 yes word1 word2 word3 word4 no word1 word2 word3 word4 yes word1 word2 word3 word4 yes word1 word2 word3 word4 no word1 word2 word3 word4 no word1 word2 word3 word4 no word1 word2 word3 word4 yes word1 word2 word3 word4 no word1 word2 word3 word4 yes word1 word2 word3 word4 yes word1 word2 word3 word4 no word1 word2 word3 word4 no word1 word2 word3 word4 no word1 word2 word3 word4 no word1 word2 word3 word4 yes > What do we do at steps 4ff if the line does not end in "yes" or "no"? I forgot to mention that I know for sure that the file has ONLY lines that end in either "yes" or "no". Any suggestions are appreciated. Also, I feel that my code is not the best way of solving the problem even if the problem of list indices is solved. Is my guess right? Another suggestion. I would not read all data from file into array (memory). If your file is large, you may hit out of memory error. regards, shantanoo Thank you! -dan On Sat, Apr 25, 2009 at 10:32 AM, bob gailer wrote: Dan Liang wrote: Dear Tutors, I have a file from which I want to extract lines that end in certain strings and print to a second file. More specifically, I want to: 1) iterate over each line in the file, and if it ends in "yes", print it. 2) move to the line following the one described in #1 above, and if it ends in, "no" print it. 3) move to third line, and if it ends in "no", print it. 4) move to fourth line, and if it ends in "no" discard it, but if it ends in "yes" repeat 1, 2, and 3 above. 5) move to fifth line, and if it ends in "no" discard it, but if it ends in "yes" repeat 1, 2, 3, and 4 above, and so on. The goal is to get a ratio of 1 to 2 "yes" to "no" lines from a file in such a way that keeps the order of the lines in output. An abstraction away from this so that any ratio of "yes" to "no" lines could be printed while keeping the order of the original lines would be great. Please show us what code you have written, and in what way it fails to meet your expectations. Your specification is IMHO a nice piece of pseudocode which could translate to Python fairly easily! What do we do at steps 4ff if the line does not end in "yes" or "no"? If you have not written any code make a stab at it. You could start by asking "how in Python does one": open a file? iterate (loop)? get the next line from a file? test for equality? examine the end of a string? -- Bob Gailer Chapel Hill NC 919-636-4239 ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Working with lines from file and printing to another keeping sequential order
Hi Bob and tutors, Thanks Bob for your response! currently I have the current code, but it does not work: ListLines= [] for line in open('test.txt'): line = line.rstrip() ListLines.append(line) for i in range(len(ListLines)): if ListLines[i].endswith("yes") and ListLines[i+1].endswith("no") and ListLines[i+1].endswith("no"): print ListLines[i], ListLines[i+1], ListLines[i+2] elif ListLines[i].endswith("yes") and ListLines[i+1].endswith("no"): print ListLines[i], ListLines[i+1] elif ListLines[i].endswith("yes"): print ListLines[i] elif ListLines[i].endswith("no"): continue else: break I get the following error: Traceback (most recent call last): File "test.py", line 18, in if ListLines[i].endswith("yes") and ListLines[i+1].endswith("no") and ListLines[i+1].endswith("no"): IndexError: list index out of range Lines in the file look like following: word1 word2 word3 word4 yes word1 word2 word3 word4 no word1 word2 word3 word4 no word1 word2 word3 word4 no word1 word2 word3 word4 yes word1 word2 word3 word4 no word1 word2 word3 word4 yes word1 word2 word3 word4 no word1 word2 word3 word4 yes word1 word2 word3 word4 yes word1 word2 word3 word4 no word1 word2 word3 word4 no word1 word2 word3 word4 no word1 word2 word3 word4 yes word1 word2 word3 word4 no word1 word2 word3 word4 yes word1 word2 word3 word4 yes word1 word2 word3 word4 no word1 word2 word3 word4 no word1 word2 word3 word4 no word1 word2 word3 word4 no word1 word2 word3 word4 yes > What do we do at steps 4ff if the line does not end in "yes" or "no"? I forgot to mention that I know for sure that the file has ONLY lines that end in either "yes" or "no". Any suggestions are appreciated. Also, I feel that my code is not the best way of solving the problem even if the problem of list indices is solved. Is my guess right? Thank you! -dan On Sat, Apr 25, 2009 at 10:32 AM, bob gailer wrote: > Dan Liang wrote: > >> Dear Tutors, >> >> >> I have a file from which I want to extract lines that end in certain >> strings and print to a second file. More specifically, I want to: >> >> 1) iterate over each line in the file, and if it ends in "yes", print it. >> 2) move to the line following the one described in #1 above, and if it >> ends in, "no" print it. >> 3) move to third line, and if it ends in "no", print it. >> 4) move to fourth line, and if it ends in "no" discard it, but if it ends >> in "yes" repeat 1, 2, and 3 above. >> 5) move to fifth line, and if it ends in "no" discard it, but if it ends >> in "yes" repeat 1, 2, 3, and 4 above, and so on. >> >> The goal is to get a ratio of 1 to 2 "yes" to "no" lines from a file in >> such a way that keeps the order of the lines in output. An abstraction away >> from this so that any ratio of "yes" to "no" lines could be printed while >> keeping the order of the original lines would be great. >> > > Please show us what code you have written, and in what way it fails to meet > your expectations. > > Your specification is IMHO a nice piece of pseudocode which could translate > to Python fairly easily! > > What do we do at steps 4ff if the line does not end in "yes" or "no"? > > If you have not written any code make a stab at it. You could start by > asking "how in Python does one": > open a file? > iterate (loop)? > get the next line from a file? > test for equality? > examine the end of a string? > > > -- > Bob Gailer > Chapel Hill NC > 919-636-4239 > ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Working with lines from file and printing to another keeping sequential order
Dan Liang wrote: Dear Tutors, I have a file from which I want to extract lines that end in certain strings and print to a second file. More specifically, I want to: 1) iterate over each line in the file, and if it ends in "yes", print it. 2) move to the line following the one described in #1 above, and if it ends in, "no" print it. 3) move to third line, and if it ends in "no", print it. 4) move to fourth line, and if it ends in "no" discard it, but if it ends in "yes" repeat 1, 2, and 3 above. 5) move to fifth line, and if it ends in "no" discard it, but if it ends in "yes" repeat 1, 2, 3, and 4 above, and so on. The goal is to get a ratio of 1 to 2 "yes" to "no" lines from a file in such a way that keeps the order of the lines in output. An abstraction away from this so that any ratio of "yes" to "no" lines could be printed while keeping the order of the original lines would be great. Please show us what code you have written, and in what way it fails to meet your expectations. Your specification is IMHO a nice piece of pseudocode which could translate to Python fairly easily! What do we do at steps 4ff if the line does not end in "yes" or "no"? If you have not written any code make a stab at it. You could start by asking "how in Python does one": open a file? iterate (loop)? get the next line from a file? test for equality? examine the end of a string? -- Bob Gailer Chapel Hill NC 919-636-4239 ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
[Tutor] Working with lines from file and printing to another keeping sequential order
Dear Tutors, I have a file from which I want to extract lines that end in certain strings and print to a second file. More specifically, I want to: 1) iterate over each line in the file, and if it ends in "yes", print it. 2) move to the line following the one described in #1 above, and if it ends in, "no" print it. 3) move to third line, and if it ends in "no", print it. 4) move to fourth line, and if it ends in "no" discard it, but if it ends in "yes" repeat 1, 2, and 3 above. 5) move to fifth line, and if it ends in "no" discard it, but if it ends in "yes" repeat 1, 2, 3, and 4 above, and so on. The goal is to get a ratio of 1 to 2 "yes" to "no" lines from a file in such a way that keeps the order of the lines in output. An abstraction away from this so that any ratio of "yes" to "no" lines could be printed while keeping the order of the original lines would be great. I am new to Python and could not solve the problem. Your help is appreciated. Cheers, --dan ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor