File Reading/Writing and Try/Except |
|
Simple File Reading
Suppose you have a file called
"fred.txt" which contains the following 3 lines:
To be, or not to be,
That's really not the question,
Nor the answer.
You want to read the file and
end up with all of the text in a single string variable named "harry".
Assuming that your program and "fred.txt" are in the same directory, and
you have permission to read the file... then
# open the file, creating a "file handle" and use that handle
# to read the data into a string variable
f = open('fred.txt','r')
harry = f.read()
# now, close the file handle
f.close()
... will do the trick. Now, harry
looks like this:
"To be, or not to be,\nThat's really
not the question,\nNor the answer."
You can now split harry into a list of
lines, and process the lines individually. Or, instead, split it
immediately into a list of words, and process those words...
lines = harry.split('\n')
words = harry.split()
|
Simple File Writing
Suppose our job was to write the
contents of "fred.txt" into a new file called "george.txt", but with the
lines in reverse order... So...
# read lines in:
f = open('fred.txt','r')
harry = f.read()
f.close()
# separate into lines
lines = harry.split('\n')
# open the file "george.txt" for writing
ron = open('george.txt','w')
# write out the lines in reverse order
for aline in lines[::-1]:
ron.write(aline+'\n')
# had to add the "\n" to each line because it was
# swallowed by the .split('\n') above
# must close the file
ron.close()
|
What can possibly go wrong??
Lots. For instance:
- Suppose there is no "fred.txt" file?
- It's not in the
current directory, but rather somewhere else in the file system?
- The file is here and available but your program does not have the
permission to read it?
So this is an operation that might fail, and if
so, might crash your program. While that's not terrible, if you're
creating a program for yourself. But it is terrible, if you're
creating a program to be used by other people.
Suppose that you've created a program, to
be used by other people who interact with it and provide it with the
name of a file to work on. You don't want the program to crash if
the user requests a file that can't be read for any of the reasonsn
mentioned above. In this situation, the program will print an
obscure error message to the user who will not be able to interpret it,
and stop. You, as the programmer, want to have some control over
this situation.
Enter the try/except keywords...
|
try/except
Suppose you want the program to recover if it
can't read a file that the user has provided. You want it to
simply print an understandable instruction to the user and try again.
Here's an example:
while True:
# get the name of a file from the
user...
thefile = input('Name of file (or
"quit" to exit): ')
if thefile == 'quit':
print('Program
terminating...')
break
# get out of the while loop
try:
# try these 3 commands. If any fail,
go to except
f =
open(thefile,'r')
print(f.read())
f.close()
# now skip the except block because
this worked
except:
# we're
here because some command failed in the
# try block (probably the open())
print('Could
not read:',thefile)
file_attempts += 1
# bottom of while loop, go back
to top
print('Total file attempts: ',file_attempts)
Explanation:
"input()" is a function that takes a string as a prompt, and prints that
prompt on the screen and waits for and captures the user's typed
response, and returns that as a string.
"try:" starts a block of indented code with commands that might fail and
Python will attempt to execute that code. If all of the commands
in that indented code block (before the "except:" statement) execute
without a problem, then the "except:" code block is skipped, and then
the program will continue after that.
If an error occurs anywhere in the "try:" code block, then Python
immediately jumps to the "except:" block of code and executes the
commands in that block. And then Python goes on to the commands
after the "except:" block of indented code.
|
More on exceptions
The "except:" block, in the example above,
will catch all types of errors that occur in the "try:" block. But
you may want to tell the user of the program just what kind of error
occured. Was it because the file didn't exist, or because the
program didn't have permission to read it, etc.? Python will tell
you if you want...
Instead of the simple "except:" statement, here's a more complicated one
that captures the error message that Python would have printed on the
screen, and now you can print it yourself, in a nicer form. And the
program doesn't crash.
try:
blah, blah, blah...
except Exception as voldy:
print('There was a error: ', voldy)
print('so, you might want to try again')
|
What if the file isn't "there"?
This is the same problem that we
would have on the command-line, when looking for a file that might not
be there. We could navigate around the file system and use
commands like "cd" and "pwd" and "ls" to look around. Then, once we've
found the missing file (possibly we were in the wrong place looking for
it), we'll then be able to open it.
One can do all this in Python after importing the "os" library:
import os
Unix command |
Python method |
pwd |
os.getcwd() |
cd directoryname |
os.chdir(directoryname) |
ls |
os.listdir() |
ls directoryname |
os.listdir(directoryname) |
Imagine this small directory/file area:
/temp
introcs (a directory)
sample.csv (a file)
demo (a directory)
fred.txt (a file)
george.txt (a file)
import os
print(os.getcwd())
c:\temp\introcs
(if on Windows)
/temp/introcs
(if
Mac or Unix)
print(os.listdir())
['demo', 'sample.csv']
print(os.listdir('demo'))
['fred.txt', 'george.txt']
os.chdir('demo')
print(os.getcwd())
c:\temp\introcs\demo
(if on
Windows)
/temp/introcs/demo
(if on Mac or Unix) |
Converting strings to numbers with
Try/Except
This is a string: "475.8" It has 5
characters.
This is a number: 475.8. You can add and multiply it.
Python has 2 functions "int()" and "float()" that will convert a string
representation of a number into a number. Like so:
a = int('-47')
b = float('475.8')
However, if you give the function int() a string that cannot be
converted into a integer, like "a4" or "fred" or even "4.5", then Python
will crash with an error. That's true of float() as well -- it
will fail on "7.8qt", for instance.
Can you tell ahead of time whether to give a string to one of these
functions?
Yes, by using Try/Except. You can build functions that will tell you
whether you can convert a string into an integer or a floating point
number.
def
IsAnInteger(somestring):
try:
a = int(somestring)
return True
except:
return False
def IsAFloat(somestring):
try:
a = float(somestring)
return True
except:
return False
|