26

I'm writing a script that logs errors from another program and restarts the program where it left off when it encounters an error. For whatever reasons, the developers of this program didn't feel it necessary to put this functionality into their program by default.

Anyways, the program takes an input file, parses it, and creates an output file. The input file is in a specific format:

UI - 26474845 TI - the title (can be any number of lines) AB - the abstract (can also be any number of lines) 

When the program throws an error, it gives you the reference information you need to track the error - namely, the UI, which section (title or abstract), and the line number relative to the beginning of the title or abstract. I want to log the offending sentences from the input file with a function that takes the reference number and the file, finds the sentence, and logs it. The best way I could think of doing it involves moving forward through the file a specific number of times (namely, n times, where n is the line number relative to the beginning of the seciton). The way that seemed to make sense to do this is:

i = 1 while i <= lineNumber: print original.readline() i += 1 

I don't see how this would make me lose data, but Python thinks it would, and says ValueError: Mixing iteration and read methods would lose data. Does anyone know how to do this properly?

1
  • 3
    -1: Code missing from the snippet. There's probably a "for something in original:" missing from the code shown. Commented May 5, 2009 at 19:59

4 Answers 4

50

You get the ValueError because your code probably has for line in original: in addition to original.readline(). An easy solution which fixes the problem without making your program slower or consume more memory is changing

for line in original: ... 

to

while True: line = original.readline() if not line: break ... 
Sign up to request clarification or add additional context in comments.

2 Comments

You hit the nail on the head - I was using for, as well as while. This was the quickest fix. Thanks, and thanks for everyone else's responses as well.
But whats the problem??, Why not to use for
12

Use for and enumerate.

Example:

for line_num, line in enumerate(file): if line_num < cut_off: print line 

NOTE: This assumes you are already cleaning up your file handles, etc.

Also, the takewhile function could prove useful if you prefer a more functional flavor.

Comments

0

Assuming you need only one line, this could be of help

import itertools def getline(fobj, line_no): "Return a (1-based) line from a file object" return itertools.islice(fobj, line_no-1, line_no).next() # 1-based! >>> print getline(open("/etc/passwd", "r"), 4) 'adm:x:3:4:adm:/var/adm:/bin/false\n' 

You might want to catch StopIteration errors (if the file has less lines).

Comments

-1

Here's a version without the ugly while True pattern and without other modules:

for line in iter(original.readline, ''): if …: # to the beginning of the title or abstract for i in range(lineNumber): print original.readline(), break 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.