==================== 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 "", line 1, in 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