Week 11

File Input and Output and Tables

Author:Christopher Haynes
Email:chaynes@indiana.edu
Affiliation:Indiana University
Course:BL CSCI A201
Date:2008-03-27
Copyright © 2008, Christopher Haynes—all rights reserved.

Contents

Oncourse Resources

Algorithm for using practice and review problems

  1. Print the solution (in the Oncourse resources)
  2. Cover it with a piece of paper
  3. See if you can guess the next line of a function body
  4. Expose the next line to see if you were right or if you need a hint
  5. Repeat until done with printout

Sharing Demo

>>> x1 = 3
>>> x2 = x1
>>> x2
3
>>> x1 = 4
>>> x1
4
>>> x2
3
>>> lst1 = [3]
>>> lst2 = lst1
>>> lst2
[3]
>>> lst1.append(5)
>>> lst1
[3, 5]
>>> lst2
[3, 5]
>>> lst3 = [0] * 3
>>> lst3
[0, 0, 0]
>>> lst3[1] += 1
>>> lst3
[0, 1, 0]
>>> lst4 = [[]] * 3
>>> lst4
[[], [], []]
>>> lst4[1].append(3)
>>> lst4
[[3], [3], [3]]

List sharing: what's going on

Picturing aliasing

What's in a file?

Why have files?

How fast, or slow?

Example: get_file

def get_file(file_name):
    """Return the contents of the file in a string.

    >>> print get_file('stats_data.txt')
    1
    3
    2
    <BLANKLINE>
    >>>
    """
    infile = file(file_name, 'r')
    text = infile.read()
    infile.close()
    return text

File objects and opening files

Opening files in Python

Closing files

File object read methods

File object write and close methods

"The file" can mean several things

Example: iu_addresses

def iu_addresses(in_file_name, out_file_name):
    """Read a file containing one user id per line and output a file
    containing on each line the corresponding IU email address, obtained by
    appending @indiana.edu to the user id. Whitespace is stripped from user
    ids.

    >>> print file('userids.txt').read()
    jcleese
    tgilliam
    gchapman
    <BLANKLINE>
    >>> iu_addresses('userids.txt', 'iuaddresses.txt')
    >>> print file('iuaddresses.txt').read()
    jcleese@indiana.edu
    tgilliam@indiana.edu
    gchapman@indiana.edu
    <BLANKLINE>
    >>>
    """
    in_file = file(in_file_name, 'r')
    out_file = file(out_file_name, 'w')
    while True:
        line = in_file.readline()
        if line == '': # EOF
            break
        out_file.write(line.strip() + '@indiana.edu\n')
    in_file.close()
    out_file.close()

It is Ok to not close files in tests

clicker A file must be opened before you can

  1. read it
  2. write it
  3. both A and B
  4. neither A or B

Answer: C

clicker The file write method message is sent to

  1. a string that names a file
  2. a file object
  3. both of the above
  4. none of the above: write is a function, not a method

Answer: B

clicker Using the basic file methods it is possible to

  1. open a file, both read and write it, and then close it
  2. write a list of numbers directly to a file (without converting the list to a string)
  3. write many lines to a file with one method call
  4. all of the above
  5. none of the above

Answer: C

clicker If your program runs a long time, but uses a file for only a short time, and you fail to close it, what might happen?

  1. some data written to the file is lost when the system crashes
  2. another program that tries to use the file cannot do so
  3. a program tries to open a file and cannot because of an operating system limit
  4. all of the above
  5. none of the above

Answer: D

Exercise: remove_blank_lines

def remove_blank_lines(in_file_name, out_file_name):
    """Copy the input file to the output file, removing all lines containing only
    whitespace.
    """
    #.
    #.
    #.
    #.
    #.
    #.
    #.
    #.
    #.
    #.

Solution: remove_blank_lines

def remove_blank_lines(in_file_name, out_file_name):
    """Copy the input file to the output file, removing all lines containing only
    whitespace.
    """
    in_file = file(in_file_name, 'r')
    out_file = file(out_file_name, 'w')
    while True:
        line = in_file.readline()
        if line == '': # EOF
            break
        if line.strip() != '':
            out_file.write(line)
    in_file.close()
    out_file.close()

Exercise: file_replace

def file_replace(in_file_name, out_file_name, old, new):
    """Copy the input file to the output file, replacing all occurrances of the
    string old with the string new.
    """
    # Hint: use the file read() and string replace(old, new) methods
    #.
    #.
    #.
    #.
    #.
    #.
    #.

Solution: file_replace

def file_replace(in_file_name, out_file_name, old, new):
    """Copy the input file to the output file, replacing all occurrances of the
    string old with the string new.
    """
    # Hint: use the file read() and string replace(old, new) methods
    in_file = file(in_file_name, 'r')
    text = in_file.read()
    in_file.close()
    out_file = file(out_file_name, 'w')
    text = text.replace(old, new)
    out_file.write(text)
    out_file.close()

Tables

Tables in Python

Inventory table example

Comma-separated-value format

Exercise: write_csv_table

def write_csv_table(table, file_name):
    """Write the contents of the table to the file in comma-separated
    format. The table is a list of lists values, where the string representation
    of each value is assumed to contain no comma or quote characters.

    >>> write_csv_table([[1, 2], ['a string', 'another string']], 'table.csv')
    >>> print get_file('table.csv')
    1,2
    a string,another string
    <BLANKLINE>
    >>>
    """
    #.
    #.
    #.
    #.
    #.
    #.
    #.
    #.
    #.
    #.
    #.
    #.
    #.
    #.
    #.

Solution: write_csv_table

def write_csv_table(table, file_name):
    """Write the contents of the table to the file in comma-separated
    format. The table is a list of lists values, where the string representation
    of each value is assumed to contain no comma or quote characters.

    >>> write_csv_table([[1, 2], ['a string', 'another string']], 'table.csv')
    >>> print get_file('table.csv')
    1,2
    a string,another string
    <BLANKLINE>
    >>>
    """
    file_object = file(file_name, 'w')
    row_index = 0
    while row_index < len(table):
        row = table[row_index]
        # accumulate a row
        s = ''
        column_index = 0
        while column_index < len(row):
            s = s + str(row[column_index])
            if column_index < len(row) - 1:
                s = s + ','
            column_index = column_index + 1
        file_object.write(s + '\n')
        row_index = row_index + 1
    file_object.close()

clicker If the documentation of a function says that it returns something, then its body

  1. must have at least one return statement
  2. may or may not have a return statement, depending on whether it uses print
  3. needs a return statement only if it returns from somewhere other than the end of the function body

Answer: A

clicker If the documentation of a function says (or implies one way or another) that it mutates a data structure, and does not say that it returns anything, then its body

  1. must contain a return statement
  2. needs a return statement only if it needs to exit from somewhere other than the end of the function body
  3. may use a return statement only if it does not include an expression, or the expression's value is None
  4. may not contain a return statement
  5. B and C

Answer: E

clicker If the documentation of a function says that it does something with "corresponding" elements of two or more sequences, and you are not using recursion, you know that its implementation requires

  1. a while loop
  2. a for loop
  3. an indexed loop
  4. a post-test loop
  5. a while True loop
  6. none of the above

Answer: C

clicker What is the result of evaluating 'abc'['a' : 'b']

  1. 'ab'
  2. 'a'
  3. Syntax error
  4. Runtime error

Answer: D

clicker Which of the following returns [1, 2] ?

  1. [1].append(2)
  2. [1].append([2])
  3. [1] + [2]
  4. [1] + 2
  5. A or C

Answer: C