Python: Input-Output¶
Interacting with the User¶
The simplest kind of interaction with the user is to ask a question (given as a string) and read back the answer (also as a string).
The raw_input()
function allows to do it.
Returns | Function | Meaning |
---|---|---|
str |
raw_input([str]) |
Asks a question to the user, returns the answer |
Example. Let’s ask the user a simple question:
answer = raw_input("write three space-separated words: ")
print answer
print type(answer)
Here the answer
variable contains the user answer. It is always a
string; the user decides its actual value.
Now, let’s check if the user answered with exactly three words:
words = answer.split()
print "you wrote", len(words), "words"
reaction_to = {
True: "Nice!",
False: "You can do better than that."
}
print reaction_to[len(words) == 3]
Example. Let’s ask the user:
answer = raw_input("write two numbers: ")
print answer
print type(answer)
Let’s print the sum of the two numbers provided by the user. Note that, since
the value returned by raw_input()
is always a string, we have to
first split into words, and then convert the words into (say) floats:
words = answer.split()
n = float(words[0])
m = float(words[1])
print "the sum is", n + m
Of course, if the user can not be split into two words, or if those words do not represent valid float values, the code above will not work.
Reading and Writing Text Files¶
In order to access the contents of a file (let’s assume a text file for
simplicity), we need to first create a handle to it. This can be done
with the open()
function (see below).
Warning
A handle is simply an object that refers to a given file.
It does not contain any of the file data, but it can be used together with other methods, to read and write from the file it refers to.
Returns | Function | Meaning |
---|---|---|
file |
open(str, [str]) |
Get a handle to a file |
str |
file.read() |
Read all the file as a single string |
list-of-str |
file.readlines() |
Read all lines of the file as a list of strings |
str |
file.readline() |
Read one line of the file as a string |
None |
file.write(str) |
Write one string to the file |
– | file.close() |
Close the file (= flushes changes to disk) |
open()
allows to get a handle to a file.
The first argument to open()
is the path of the file we want to open.
The second argument is optional. It tells open()
how we intend to
use the file: for reading, for writing, etc.
These are the available access modes:
"r"
: we want to read from the file. This is the default mode."w"
: we want to write to the file, overwriting its contents."a"
: we want to write to the file, appending to the existing contents.
Mode flags can be combined. For instance:
"rw"
: we want to read and write (in “overwrite” mode)."ra"
: we want to read and write (in “append” mode).
Once you are done with a file (either reading or writing), make sure
to call the close()
method to finalize your operations.
Example. Let’s open a file in read-only mode:
handle = open("data/aatable", "r")
print type(handle)
Once we have the file handle, we can read the contents of the file:
As a single, big string:
all_contents = handle.read() print all_contents
read()
makes sense if your file is small enough (i.e. it fits into the RAM) and it is not structured as a sequence of lines separated by newline characters.Some files fit this description (they are pretty rare, tho).
As a list of lines (strings):
lines = handle.readlines() print lines
readlines()
makes sense if your file is small enough and it is structured as a collection of lines.FASTA files are an example of such files.
One line at a time, sequentially, from the first onwards:
line = handle.readline() print line line = handle.readline() print line # etc.
readline()
makes sense for very large files, because you can read one line at a time, without saturating the machine.
Given that the handle has been opened in read-only mode (that is, "r"
)
we can not write to it:
>>> handle.write("something something")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IOError: File not open for writing
# ^^^^^^^^^^^^^^^^^^^^^^^^^
# Python complains about it!
Warning
Internally, Python keeps track of which lines of a file
have already been read. (This is used to implement the
readline()
method, for instance.)
Once a line has been read, it can not be read from the same file handle.
This limitation affects all three methods: read()
,
readlines()
and readline()
.
For instance:
handle = open("data/aatable")
# No line has been read yet, so
lines = handle.readlines()
print len(lines)
# I just read *all* of the lines; no unread
# line is left
whats_left = handle.readlines()
print len(whats_left)
# Here Python did *not* read anything, because
# there were no lines left to read!
Example. Let’s see how to write to a file. We have to open a
file handle in write mode (either "w"
or "a"
):
# Open a file for writing
handle = open("result.txt", "w")
# TODO: write a long and complex calculation whose
# result is 42
result = 42
# In order to write the result (which is an int) to the
# file, we have to convert it to a string. Let's also
# add a newline character, so that the result fills a
# whole line.
handle.write(str(result))
# Make sure that our writes are written to disk.
handle.close()
And that’s it.
Warning
Forgetting to close a file opened in read-only mode is not too harmful.
(It is only harmful if you keep opening files and end up with more open files than the Operating System allows. Yes, there is a limit.)
However, forgetting to explicitly close files opened in
write mode (either "w"
, "a"
or any other combination
including them) can have serious consequences.
The reason is that writes to files are not immediately
written to disk, for efficiency. Instead, they are stored
in memory until Python decides to write them to the actual
file. close()
is a way to tell Python to flush the
changes to the file.
Intuitively, this means that if you don’t call close()
and the program quits (because of an error, for instance),
then your changes are not written to the file.
Example. We ask the user the path to a file (it does not matter whether it already exists or not), and then what to write in it:
path = raw_input("give me a path: ")
text = raw_input("give me the contents: ")
handle = open(path, "w")
handle.write("the user replied " + text)
handle.close()
Quiz: what happens if you execute this code twice on the same file?
Now, let’s open the same file, but for reading, and read its contents:
other_handle = open(path, "r")
all_contents = other_handle.read()
other_handle.close()
print "I found:"
print all_contents
print "in the file at", path