[Tutor] This is driving my crazy! My file hasn't been corrupted
Steven D'Aprano
steve at pearwood.info
Sun Aug 31 21:19:06 CEST 2014
On Sun, Aug 31, 2014 at 09:31:25AM -0700, Richard Dillon wrote:
> My text file has five numbers, 1-5
> I don't what the problem is.
You'll probably find out if you ask Python to show you what is actually
causing the problem.
> I've written the file using Word (saved as .txt ) as well as TextEdit
> Python 3.4.1 on a Mac
>
> Here's the code:
>
> # Richard Dillon
>
> # This program reads data from a .txt file and calculates a total
> # data in text file: 1,2,3,4 and 5 for a total of 15
> # error message: Non-numeric data found in the file
>
> def main():
> total = 0.0
> try:
> infile = open('/Users/richarddillon/Desktop/numbers.txt', 'r')
> for line in infile:
> amount = float(line)
> total += amount
> infile.close()
> print(format(total, ',.2f'))
> except IOError:
> print('An error occured trying to read the file.')
You don't know that it is a read error. Look at the try block: you do
SEVEN different things:
- open a file
- read the file
- convert lines of text into floats
- add numbers together
- close the file
- call the format function
- print some string.
All of them could *in principle* raise IOError, although in practice
only three of them are serious candidates. If you have an IOError, how
do you know whether it was *opening*, *reading* or *closing* the file
that failed?
(Yes, closing files can fail.)
Lesson 1: never protect too much by a single try...except block.
Lesson 2: never catch any error that you don't know how to recover from.
If you *don't* catch the IOError, Python will print the full exception,
which will show you exactly what failed (say, opening the file), the
error code, and the error message.
> except ValueError:
> print('Non-numeric data found in the file.')
Again, there are seven things which could theoretically raise
ValueError, although this time only one of them is likely to. Never the
less, the same rule applies: don't protect too much with a try block. In
this case, this is much more useful:
infile = open('/Users/richarddillon/Desktop/numbers.txt', 'r')
for line in infile:
try:
amount = float(line)
except ValueError:
print(repr(line))
raise
total += amount
infile.close()
print(format(total, ',.2f'))
The call to repr will convert any weird invisible characters to
backslash escapes so you can see them. But I suspect what you will see
is nothing weirder than a blank line:
py> line = '\n' # blank line
py> float(line)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: could not convert string to float:
> except:
> print('An error occured.')
Oh, well that explains everything. "An error occurred." With all that
diagnostic information, debugging will be so easy!
Not.
Seriously, don't do that. If an error occurs, Python gives you a heap of
information to make it easy to debug. You collect that information,
flush it down the toilet, and replace it with an innane and meaningless
generic message like "An error occurred".
--
Steven
More information about the Tutor
mailing list