<filename>Labs/Introduction/Exceptions/Exceptions.tex
\lab{Exceptions and File I/O}{Exceptions and File I/O}
\label{lab:Exceptions}
\objective{
In Python, an \emph{exception} is an error detected during execution.
Exceptions are important for regulating program usage and for correctly reporting problems to the programmer and end user.
Understanding exceptions allows us to safely read data from and export data to external files, and being able to read from and write to files is important to analyzing data and communicating results.
In this lab we present exception syntax and file interaction protocols.
}

\section*{Exceptions} % =======================================================

Every programming language has a formal way of indicating and handling errors.
In Python, we raise and handle \emph{exceptions}.
Some of the more common exceptions are listed below, along with the kinds of problems that they typically indicate.
%
\begin{table}[H]
\centering
\begin{tabular}{r|l}
    Exception & Indication \\ \hline
    \li{AttributeError} & An attribute reference or assignment failed.\\
    % \li{ImportError} & An \li{import} statement failed.\\
    \li{IndexError} & A sequence subscript was out of range.\\
    \li{NameError} & A local or global name was not found.\\
    \li{SyntaxError} & The parser encountered a syntax error.\\
    \li{TypeError} & An operation or function was applied to an object of \\ &inappropriate type.\\
    \li{ValueError} & An operation or function received an argument that had \\ & the right type but an inappropriate value.\\
    % \li{ZeroDivisionError} & The second argument of a division or modulo operation \\ & was zero.
\end{tabular}
\end{table}
%
\begin{lstlisting}
>>> print(x)
<<Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'x' is not defined>>

>>> [1, 2, 3].fly()
<<Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'list' object has no attribute 'fly'>>
\end{lstlisting}

See \url{https://docs.python.org/2/library/exceptions.html} for the complete list of Python's built-in exception classes.

\subsection*{Raising Exceptions} % --------------------------------------------

Many exceptions, like the ones demonstrated above, are due to coding mistakes and typos.
Exceptions can also be used intentionally to indicate a problem to the user or programmer.
To create an exception, use the keyword \li{raise}, followed by the name of the exception class.
As soon as an exception is raised, the program stops running unless the exception is handled properly.

Exception objects can be initialized with any number of arguments.
These arguments are stored as a tuple attribute called \li{args}, which serves as the string representation of the object.
We typically provide a single string detailing the reasons for the error.

\begin{lstlisting}
# Raise a generic exception, without an error message.
>>> if 7 is not 7.0:
...     raise Exception
...
<<Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
Exception>>

# Now raise a more specific exception, with an error message included.
>>> for x in range(10):
...     if x > 5:
...         raise ValueError("'x' should not exceed 5.")
...     print(x),
...
0 1 2 3 4 5
<<Traceback (most recent call last):
  File "<stdin>", line 3, in <module>
ValueError: 'x' should not exceed 5.>>
\end{lstlisting}

\begin{problem} % Raising Exceptions during magic trick.
Consider the following arithmetic ``magic'' trick.
\begin{enumerate}
    \item Choose a 3-digit number where the first and last digits differ by 2 or more (for example, $123$).
    \label{magic-trick-step-1}
    \item Reverse this number by reading it backwards ($321$).
    \item Calculate the positive difference of these numbers ($321 - 123 = 198$).
    \item Add the reverse of the result to itself ($198 + 891 = 1089$).
\end{enumerate}
The result of the last step will \emph{always} be $1089$, regardless of the original number chosen in step \ref{magic-trick-step-1} (can you explain why?).

The following function prompts the user for input at each step of the magic trick, but does not check that the user's inputs are correct.
\newpage
\begin{lstlisting}
def arithmagic():
    step_1 = raw_input("Enter a 3-digit number where the first and last "
                                           "digits differ by 2 or more: ")
    step_2 = raw_input("Enter the reverse of the first number, obtained "
                                              "by reading it backwards: ")
    step_3 = raw_input("Enter the positive difference of these numbers: ")
    step_4 = raw_input("Enter the reverse of the previous result: ")
    print str(step_3) + " + " + str(step_4) + " = 1089 (ta-da!)"
\end{lstlisting}

Modify \li{arithmagic()} so that it verifies the user's input at each step.
Raise a \li{ValueError} with an informative error message if any of the following occur:
\begin{enumerate}
\item The first number (\li{step_1}) is not a 3-digit number.
\item The first number's first and last digits differ by less than $2$.
\item The second number (\li{step_2}) is not the reverse of the first number.
\item The third number (\li{step_3}) is not the positive difference of the first two numbers.
\item The fourth number (\li{step_4}) is not the reverse of the third number.
\end{enumerate}
%
(Hint: \li{raw_input()} always returns a string, so each variable is a string initially. Use \li{int()} to cast the variables as integers when necessary. The built-in function \li{abs()} may also be useful.)

\end{problem}

\subsection*{Handling Exceptions} % -------------------------------------------

To prevent an exception from halting the program, it must be handled by
placing the problematic lines of code in a \li{try} block.
An \li{except} block then follows.

\begin{lstlisting}
# The 'try' block should hold any lines of code that might raise an exception.
>>> try:
...     raise Exception("for no reason")
...     print "No exception raised"
... # The 'except' block is executed when an exception is raised.
... except Exception as e:
...     print "Exception raised", e
...
<<Exception raised for no reason>>
>>> # The program then continues on.
\end{lstlisting}

In this example, the name \li{e} represents the exception within the except block.
Printing \li{e} displays its error message.

\begin{comment}
We could also raise the exception again with the syntax \li{raise e} or just \li{raise}.

\begin{lstlisting}
>>> try:
...     raise Exception("for no reason")
... except Exception as e:
...     print "Exception raised", e
...     e.args = ("BECAUSE MATH!!",)        # Assign 'e' a new error message.
...     raise e                             # Raise the exception again.
...
Exception raised for no reason
<<Traceback (most recent call last):
  File "<stdin>", line 6, in <module>
Exception: BECAUSE MATH!!>>
\end{lstlisting}
\end{comment}

\newpage

The try-except control flow can be expanded with two other blocks.
The flow proceeds as follows:

\begin{enumerate}
\item The \li{try} block is executed until an exception is raised, if at all.

\item An \li{except} statement specifying the same kind of exception that was raised in the try block ``catches'' the exception, and the block is then executed.
There may be multiple except blocks following a single try block (similiar to having several \li{elif} statements following a single \li{if} statement), and a single except statement may specify multiple kinds of exceptions to catch.

\item The optional \li{else} block is executed if an exception was \emph{not} raised in the try block.
Thus either an except block or the else block is executed, but not both.

\item Lastly, the optional \li{finally} block is always executed if it is included.
\end{enumerate}

% Note that a try block must always be followed by at least one except or finally block.

\begin{lstlisting}
>>> try:
...     raise ValueError("The house is on fire!")
... # Check for multiple kinds of exceptions using parentheses.
... except (ValueError, TypeError) as e:
...     house_on_fire = True
... else:                           # Skipped due to the exception.
...     house_on_fire = False
... finally:
...     print "The house is on fire:", house_on_fire
...
<<The house is on fire: True>>

>>> try:
...     house_on_fire = False
... except Exception as e:
...     house_on_fire = True
... else:                           # Executed because there was no exception.
...     print "The house is probably okay."
... finally:
...     print "The house is on fire:", house_on_fire
...
<<The house is probably okay.
The house is on fire: False>>
\end{lstlisting}

The code in the \li{finally} block is \emph{always} executed, even if a \li{return} statement or an uncaught exception occurs in any block following the try statement.

\begin{lstlisting}
>>> try:
...     raise ValueError("The house is on fire!")
... finally:                        # Executes before the error is reported.
...     print "The house may be on fire."
...
<<The house may be on fire.
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
ValueError: The house is on fire!>>
\end{lstlisting}

See \url{https://docs.python.org/2/tutorial/errors.html} for more examples.

\begin{problem} % Problem: Catch a KeyboardInterrupt to stop a random walk.
A \emph{random walk} is a path created by a series of random steps.
% Random walks are used in many applications, including molecular movement, image segmentation, and (somewhat disturbingly) stock market prices.
The following function simulates a random walk where at every step, we either step forward (adding $1$ to the total) or backward (adding $-1$).

\begin{lstlisting}
from random import choice

def random_walk(max_iters=1e12):
    walk = 0
    direction = [1, -1]
    for i in xrange(int(max_iters)):
        walk += choice(direction)
    return walk
\end{lstlisting}

A \li{KeyboardInterrupt} is a special exception that can be triggered at any time by entering \li{ctrl c} (on most systems) in the keyboard.
% A \li{KeyboardInterrupt} is usually used to manually escape faulty code that runs forever, but it can also be used to intentionally truncate a process.
Modify \li{random_walk()} so that if the user raises a \li{KeyboardInterrupt}, the function handles the exception and prints ``Process interrupted at iteration $i$''.
If no \li{KeyboardInterrupt} is raised, print ``Process completed''.
In both cases, return \li{walk} as before.
\end{problem}

\begin{info} % Exception Hierarchy
The built-in Python exceptions are organized into a class hierarchy.
This can lead to some confusing behavior.

\begin{lstlisting}
>>> try:
...     raise ValueError("This is a ValueError!")
... except StandardError as e:
...     print(e)
...
<<This is a ValueError!>>                       # The exception was caught.

>>> try:
...     raise StandardError("This is a StandardError!")
... except ValueError as e:
...     print(e)
...
<<Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
StandardError: This is a StandardError!>>     # The exception wasn't caught!
\end{lstlisting}

It turns out that the \li{ValueError} class inherits from the \li{StandardError} class.
Thus a \li{ValueError} \emph{is} a \li{StandardError}, so the first except statement was able to catch the exception, but a \li{StandardError} is \emph{not} a \li{ValueError}, so the second except statement could not catch the exception.

The complete exception class hierarchy is documented at \url{https://docs.python.org/2/library/exceptions.html#exception-hierarchy}.
\end{info}

\begin{comment}
\begin{warn} % Don't use except by itself; specify an exception class.
An \li{except} statement by itself catches \emph{any} exception raised in the corresponding try block, but this approach can mistakenly mask unexpected errors.
Consider the following function, which intends to avoid dividing by zero.

\begin{lstlisting}
>>> def divider(x, y):
...     try:
...         return x / float(yy)
...     except:
...         print("y must not equal zero!")
...
>>> divider(2, 3)
<<y must not equal zero!>>
\end{lstlisting}

Because \li{y} is misspelled as \li{yy}, a \li{NameError} is always raised in the try block.
Always specify the kinds of exceptions you expect to encounter.

\begin{lstlisting}
>>> def divider(x, y):
...     try:
...         return x / float(yy)
...     except ZeroDivisionError:
...         print("y must not equal zero!")
...
>>> divider(2, 3)
<<Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in divider
NameError: global name 'yy' is not defined>>    # Now we can see the mistake.
\end{lstlisting}
\end{warn}
\end{comment}

\section*{File Input and Output} % ============================================

Python has a useful \li{file} object that acts as an interface to all kinds of different file streams.
The built-in function \li{open()} creates a file object.
It accepts the name of the file to open and an editing mode.
The mode determines the kind of access to use when opening the file.
There are three common options:
%
\begin{description}
\item \li{'r'}: \textbf{read}.
This is the default mode.
The file must already exist.
\item \li{'w'}: \textbf{write}.
This mode creates the file if it doesn't already exist and \textcolor{red}{\textbf{overwrites everything}} in the file if it does already exist. %(wake up and pay attention to this)
\item \li{'a'}: \textbf{append}.
New data is written to the end of the file.
This mode also creates a new file if it doesn't already exist.
\end{description}

\begin{lstlisting}
>>> myfile = open("in.txt", 'r')        # Open 'in.txt' with read-only access.
>>> print(myfile.read())                # Print the contents of the file.
Hello World!                            # (it's a really small file.)
>>> myfile.close()                      # Close the file connection.
\end{lstlisting}


\subsection*{The With Statement} % --------------------------------------------

An \li{IOError} indicates that some input or output operation has failed.
If a file cannot be opened for any reason, an \li{IOError} is raised and the file object is not initialized.
A simple \li{try}-\li{finally} control flow can ensure that a file stream is closed safely.

The \li{with} statement provides an alternative method for safely opening and closing files.
Use \li{with open(<filename>, <mode>) as <alias>:} to create an indented block in which the file is open and available under the specified alias.
At the end of the block, the file is automatically closed.
This is the preferred file-reading method when a file only needs to be accessed briefly.
The more flexible \li{try}-\li{finally} approach is typically better for working with several file streams at once.

\begin{lstlisting}
>>> myfile = open("in.txt", 'r')        # Open 'in.txt' with read-only access.
>>> try:
...     contents = myfile.readlines()   # Read in the content by line.
... finally:
...     myfile.close()                  # Explicitly close the file.

# Equivalently, use a 'with' statement to take care of errors.
>>> with open("in.txt", 'r') as myfile: # Open 'in.txt' with read-only access.
...    contents = myfile.readlines()    # Read in the content by line.
...                                     # The file is closed automatically.
\end{lstlisting}

In both cases, if the file \texttt{in.txt} does not exist in the current directory, an \li{IOError} will be raised.
However, errors in the \li{try} or \li{with} blocks will not prevent the file from being safely closed.

\newpage

\subsection*{Reading and Writing} % -------------------------------------------

Open file objects have an implicit \emph{cursor} that determines the location in the file to read from or write to.
After the entire file has been read once, either the file must be closed and reopened, or the cursor must be reset to the beginning of the file with \li{seek(0)} before it can be read again.

Some of more important file object attributes and methods are listed below.

\begin{table}[H]
\begin{tabular}{r|l}
Attribute & \multicolumn{1}{c}{Description} \\
\hline
\li{closed} & \li{True} if the object is closed.\\
\li{mode} & The access mode used to open the file object.\\
\li{name} & The name of the file.\\ \\
Method & \multicolumn{1}{c}{Description}\\
\hline
\li{close()} & Close the connection to the file.\\%Flush any delayed writes
% \li{flush()} & Flush the internal I/O buffer.\\
% \li{<<next()>>} & Read the next value.\\
\li{read()} & Read a given number of bytes; with no input, read the entire file.\\
\li{readline()} & Read a line of the file, including the newline character at the end.\\
\li{readlines()} & Call \li{readline()} repeatedly and return a list of the resulting lines.\\
\li{seek()} & Move the cursor to a new position.\\
\li{tell()} & Report the current position of the cursor.\\
\li{write()} & Write a single string to the file (spaces are \emph{not} added).\\
\li{writelines()} & Write a list of strings to the file (newline characters are \emph{not} added).\\
\end{tabular}
\end{table}

Only strings can be written to files; to write a non-string type, first cast it as a string with \li{str()}.
Be mindful of spaces and newlines to separate the data.

\begin{lstlisting}
>>> with open("out.txt", 'w') as outfile:   # Open 'out.txt' for writing.
...     for i in xrange(10):
...         outfile.write(str(i**2)+' ')    # Write some strings (and spaces).
...
>>> outfile.closed                          # The file is closed automatically.
True
\end{lstlisting}

Executing this code replaces whatever used to be in \texttt{out.txt} (whether or not it existed previously) with the following:

\begin{lstlisting}
0 1 4 9 16 25 36 49 64 81
\end{lstlisting}

\begin{problem} % ContentFilter.__init__().
Define a class called \li{ContentFilter}.
Implement the constructor so that it accepts the name of a file to be read.
%
\begin{enumerate}
\item If the filename argument is not a string, raise a \li{TypeError}.

(Hint: The built-in functions \li{type()} and \li{isinstance()} may be useful.)

\item Read the file and store its name and contents as attributes
(store the contents as a single string).
Securely close the file stream.
\end{enumerate}
\end{problem}

\section*{String Formatting} % ================================================

Python's \li{str} type class has several useful methods for parsing and formatting strings.
They are particularly useful for processing data from a source file and for preparing data to be written to an external file.

\begin{table}[H]
\begin{tabular}{r|l}
Method & \multicolumn{1}{c}{Returns} \\ \hline
\li{count()} & The number of times a given substring occurs within the string.\\
\li{find()} & The lowest index where a given substring is found.\\
\li{isalpha()} & \li{True} if all characters in the string are alphabetic (a, b, c, \ldots).\\
\li{isdigit()} & \li{True} if all characters in the string are digits (0, 1, 2, \ldots).\\
\li{isspace()} & \li{True} if all characters in the string are whitespace (\li{" "}, \li{'\\t'}, \li{'\\n'}).\\
% \li{capitalize()} & A copy of the string with only its first character capitalized. \\
\li{join()} & The concatenation of the strings in a given iterable with a\\&specified separator between entries.\\
\li{lower()} & A copy of the string converted to lowercase. \\
\li{upper()} & A copy of the string converted to uppercase. \\
\li{replace()} & A copy of the string with occurrences of a given substring\\&replaced by a different specified substring.\\
\li{split()} & A list of segments of the string, using a given character or string \\
 & as a delimiter.\\
\li{strip()} & A copy of the string with leading and trailing whitespace removed. \\
\end{tabular}
\end{table}

The \li{join()} method translates a list of strings into a single string by concatenating the entries of the list and placing the principal string between the entries.
Conversely, \li{split()} translates the principal string into a list of substrings, with the separation determined by the a single input.

\begin{lstlisting}
# str.join() puts the string between the entries of a list.
>>> words = ["state", "of", "the", "art"]
>>> "-".join(words)
<<'state-of-the-art'>>

>>> " o_O ".join(words)
<<'state o_O of o_O the o_O art'>>

# str.split() creates a list out of a string, given a delimiter.
>>> "One fish\nTwo fish\nRed fish\nBlue fish\n".split('\n')
<<['One fish', 'Two fish', 'Red fish', 'Blue fish', '']>>

# If no delimiter is provided, the string is split by its whitespace characters.
>>> "One fish\nTwo fish\nRed fish\nBlue fish\n".split()
<<['One', 'fish', 'Two', 'fish', 'Red', 'fish', 'Blue', 'fish']>>
\end{lstlisting}

Can you tell the difference between the following routines?

\begin{lstlisting}
>>> with open("in.txt", 'r') as myfile:
...     contents = myfile.readlines()
...
>>> with open("in.txt", 'r') as myfile:
...     contents = myfile.read().split('\n')
\end{lstlisting}

\begin{problem} % ContentFilter methods.
Add the following methods to the \li{ContentFilter} class for writing the contents of the original file to new files.
Each method should accept a the name of a file to write to and a keyword argument \li{mode} that specifies the file access mode, defaulting to \li{'w'}.
If \li{mode} is not either \li{'w'} or \li{'a'}, raise a \li{ValueError} with an informative message.

\begin{enumerate}
\item \li{uniform()}: write the data to the outfile with uniform case. Include an additional keyword argument \li{case} that defaults to \li{"upper"}.

If \li{case="upper"}, write the data in upper case.
If \li{case="lower"}, write the data in lower case.
If \li{case} is not one of these two values, raise a \li{ValueError}.

\item \li{reverse()}: write the data to the outfile in reverse order. Include an additional keyword argument \li{unit} that defaults to \li{"line"}.

If \li{unit="word"}, reverse the ordering of the words in each line, but write the lines in the same order as the original file.
If \li{unit="word"}, reverse the ordering of the lines, but do not change the ordering of the words on each individual line.
If \li{unit} is not one of these two values, raise a \li{ValueError}.

\item \li{transpose()}: write a ``transposed'' version of the data to the outfile.
That is, write the first word of each line of the data to the first line of the new file, the second word of each line of the data to the second line of the new file, and so on.
\end{enumerate}

Also implement the \li{__str__()} magic method so that printing a \li{ContentFilter} object yields the following output:
\begin{lstlisting}
<<Source file:              <filename>
Total characters:         <The total number of characters in the file>
Alphabetic characters:    <The number of letters>
Numerical characters:     <The number of digits>
Whitespace characters:    <The number of spaces, tabs, and newlines>
Number of lines:          <The number of lines>>>
\end{lstlisting}

\begin{comment}
Examples:

\begin{lstlisting}
# example.txt
a b c
d e f
\end{lstlisting}

\begin{lstlisting}
>>> cf = ContentFilter("example.txt")

>>> cf.uniform("uniform.txt", mode='w', case="upper")
>>> cf.uniform("uniform.txt", mode='a', case="lower")

>>> cf.reverse("reverse.txt", mode='w', unit="word")
>>> cf.reverse("reverse.txt", mode='a', unit="line")

>>> cf.transpose("transpose.txt", mode='w')
\end{lstlisting}

\begin{lstlisting}
# uniform.txt
A B C
D E F
a b c
d e f
\end{lstlisting}

\begin{lstlisting}
# reverse.txt
c b a
f e d
d e f
a b c
\end{lstlisting}

\begin{lstlisting}
a d
b e
c f
\end{lstlisting}
\end{comment}

\end{problem}

\newpage

\section*{Additional Material} % ==============================================

\subsection*{Custom Exception Classes} % --------------------------------------

Custom exceptions can be defined by writing a class that inherits from some existing exception class.
The generic \li{Exception} class is typically the parent class of choice.

\begin{lstlisting}
>>> class TooHardError(Exception):
...     pass
...
>>> raise TooHardError("This lab is impossible!")
<<Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
__main__.TooHardError: This lab is impossible!>>
\end{lstlisting}

This may seem like a trivial extension of the \li{Exception} class, but it is useful to do because the interpreter never automatically raises a \li{TooHardError}.
Any \li{TooHardError} must have originated from a hand-written \li{raise} command, making it easier to identify the exact source of the problem.

\subsection*{Assertions} % ----------------------------------------------------

An \li{AssertionError} is a special exception that is used primarily for software testing.
The \li{assert} statement is a shortcut for testing the truthfulness of an expression and raising an \li{AssertionError}.

\begin{lstlisting}
>>> assert <expression>, <message>

# Equivalently...
>>> if not <expression>:
...     raise AssertionError(<message>)
...
\end{lstlisting}

\begin{comment} % This is only a feature in Python 3 (TODO).
\subsection*{Chaining Exceptions} % -------------------------------------------
\begin{lstlisting}
>>> try:
>>>     raise ValueError("First Exception")
>>> except ValueError as e:
>>>     raise TypeError("Second Exception") from e
\end{lstlisting}
This syntax makes it possible to see where an error originated from and to ``pass it up'' to the next process.
\end{comment}

\begin{comment}
\subsection*{Buffering} % -----------------------------------------------------
The {open()} function also accepts a third argument that specifies buffering size.
% TODO: Details about file.flush(), the buffer argument for open(), and reading large files.
\end{comment}

\subsection*{The CSV Module} % ------------------------------------------------

The CSV format (comma separated value) is a common file format for spreadsheets and grid-like data.
The \li{csv} module in the standard library contains functions that work in conjunction with the built-in \li{file} object to read from or write to CSV files.
See \url{https://docs.python.org/2/library/csv.html} for details.

\newpage

\subsection*{More String Formatting} % ----------------------------------------

Concatenating string values with non-string values is often cumbersome and tedious.
Consider the problem of printing a simple date:

\begin{lstlisting}
>>> day, month, year = 14, "March", 2015
>>> print("Is today " + str(day) + str(month) + ", " + str(year) + "?")
Is today 14 March, 2015?
\end{lstlisting}

The \li{str} class's \li{<<format()>>} method makes it easier to insert non-string values into the middle of a string.
Write the desired output in its entirety, replacing non-string values with curly braces \li{\{\}}.
Then use the \li{<<format()>>} method, entering each replaced value in order.

\begin{lstlisting}
>>> print("Is today {} {}, {}?".<<format>>(day, month, year))
Is today 14 March, 2015?
\end{lstlisting}

This method is extremely flexible and provides many convenient ways to format string output nicely.
Suppose, for example, that we would like to visualize the progress that a program is making through a loop.
The following code prints out a simple status bar.

\begin{lstlisting}
>>> from sys import stdout

>>> iters = int(1e7)
>>> chunk = iters // 20
>>> for i in xrange(iters):
...     print("\r[{:<20}] i = {}".<<format>>('='*((i//chunk)+1), i)),
...     stdout.flush()
...
\end{lstlisting}

Here the string \li{"\\r[\{:<20\}]"} used in conjunction with the \li{<<format()>>} method tells the cursor to go back to the beginning of the line, print an opening bracket, then print the first argument of \li{<<format()>>} left-aligned with at least $20$ total spaces before printing the closing bracket.
The comma after the print command suppresses the automatic newline character, keeping the output of each individual print statement on the same line.
Finally, \li{sys.stdout.flush()} flushes the internal buffer so that the status bar is printed in real time.

Of course, printing at each iteration dramatically slows down the progression through the loop.
How does the following code solve that problem?

\begin{lstlisting}
>>> for i in xrange(iters):
...     if not i % chunk:
...         print "\r[{:<20}] i = {}".<<format>>('='*((i//chunk)+1), i),
...         stdout.flush()
...
\end{lstlisting}

See \url{https://docs.python.org/2/library/string.html\#format-string-syntax} for more examples and specific syntax for using \li{str.<<format()>>}.
