\documentclass[../../book.tex]{subfiles}
\graphicspath{{\subfix{.}}}
\begin{document}

\chapter{Control Structures}
\label{FlowControl}
\setcounter{section}{-1}  % Start subsections from 0

It is often helpful to have a computer make your life easier or faster by doing math for you, or doing a set of tasks for you, as in the case of using arrays, but the real power of programming starts when the program can make its own decisions on what to do and when to do it without the programmer having to anticipate exactly what needs to happen in exactly what order. Consider how you interact with your computer---which does not know which application you will open at any given time. Being able to handle a wide-range of inputs in an arbitrary order allows us to move from writing simple scripts that perform a list of instructions to writing general purpose software that can be used by different users with different goals and data.  In this section, we will first introduce you to the concepts underlying the process of decision making in computer code, and then we will discuss specific control structures that you will use to lay out the decision making process.

\section{Getting Yes or No Answers: Comparisons and Boolean Logic}
\label{Sec:T:FlowControl:ComparisonsAndBoolean}
\setcounter{subsection}{-1}  % Start subsections from 0

Remembering that computers only actually operate based off of 1s and 0s or True/False values, we first have to ask, how can they make decisions?  How can we approach questions in which there may be more than two possible answers, or processes that could yield more than two outcomes?

A useful way to think about designing a computer decision making process is to turn it into a series of questions like, ``if some specific condition is met, then do these instructions.''  This breaks every decision down to a question with a Yes/No or True/False answer.  Most of the decision making structures used by computer programs have this basic question at their core.  It is the job of programmers to design and order these questions to get the behavior that we want.

\subsection{Comparison Statements Compare Two Values}
\label{Sec:T:FlowControl:ComparisonStatements}

Comparison statements are the questions that we design to give True/False answers to feed decision making processes.  Comparison statements will look familiar to you from earlier math classes, but they are not limited to only numbers and there are more ways to compare data in programs than you learned in algebra or calculus.

Comparison statements usually involve two values and a comparison operation, taking the form

\begin{lstlisting}
(Data) A <comparison operation> (Data) B
\end{lstlisting}
and they can be used in assignment operations in much the same way as other mathematical statements, like
\begin{lstlisting}
Result = (Data) A <comparison operation> (Data) B
\end{lstlisting}
where \lstinline{Result} is a variable that will hold a boolean value.  This usage implies that the outcome of a comparison operation is always either \lstinline{True} or \lstinline{False}.  

Examples of comparison operations from mathematics, are ``is greater than'' ($>$), ``is less than or equal to'' ($\leq$), or even ``is equal to'' ($=$). Note that, in this context, we are not assigning something to be equal to something else, but rather asking \textit{if} it is; sometimes this is denoted ``is equivalent to'' to avoid this confusion.  The symbols used to represent these operations are similarly familiar, but note that the computer has a hard time figuring out context and thus, in programming, \lstinline{==} is typically used to denote ``test if these two values are equal,'' while \lstinline{=} is the assignment operator.  The syntax for these statements is then conveniently natural: \lstinline{A >= B} can be simply read as ``A is greater than or equal to B?'' where the comparison statement implicitly ends with a question mark.  The response from the computer is then one of the two options: \lstinline{True} or \lstinline{False}.  Like any other statement, if you type this code into the Python command prompt, the result is output to the standard output, usually the line after the command prompt.

One straightforward comparison operator with which you may not be familiar is ``is not equal to,'' which in Python is denoted \lstinline{!=} and simply behaves the opposite of ``is equal to.''  Another is ``is in the collection,'' which tests to see if a given value is in a given collection (list, set, tuple, etc.).  This comparison returns \lstinline{True} if the value is in the collection, and \lstinline{False} if it is not.


\subsection{Complex Comparisons can be Evaluated using Boolean Logic}
\label{Sec:T:FlowControl:CombineComparisons}

The basic comparison statements above only allow the comparison of two values, but we often find ourselves needing to come up with more complex tests.  The solution to this problem is much like the one we know from evaluating complex arithmetic expressions (which also deal with two values at a time): we evaluate one comparison statement to produce a result, and replace that comparison statement with the result of the evaluation and continue until there is no comparison operator left.  Thinking about arithmetic, we know that we can simplify $(1 + 2) \times (3 + 4)$ as follows:
\begin{gather*}
(1 + 2) \times (3 + 4) \\
3 \times (3 + 4) \\
3 \times 7 \\
21   
\end{gather*}
Now, all we need is a form of arithmetic that works on boolean statements and we are set.  Luckily for us, mathematicians have worked this out long ago.

Let's consider a contrived example:  we have some solvents in the lab, but only two of them (methanol and water) can be used for a specific reaction.  If we want our program to test if the solvent we have in our hands is one of these two, we (as humans) might think ``solvent is equal to methanol or water.''  However, this will not work in Python (nor most other languages). The problem is that this single statement is actually three distinct comparisons and, when programming, we need to explicitly state all three comparisons. So, we can write ``solvent is equal to methanol or solvent is equal to water.'' If you are struggling to see how this is three comparisons, then realize that `or' is also a comparison operator.  

This is how boolean algebra is constructed.  We only have two possible values, \lstinline{True} and false, and we need to break down our work into simple statements that can return these values. 

These two values can only be related so many ways: they could be the same and both true, they could be the same and both false, or one could be \lstinline{True} and the other false.  A number of different boolean operators can thus be devised to compare the two values, with a general form
\begin{lstlisting}
Result = Boolean Value A <boolean operator> Boolean Value B
\end{lstlisting}
The most common ones that you will encounter are \lstinline{and} and \lstinline{or}.  \lstinline{and} evaluates to \lstinline{True} only when both values in the expression are True, and \lstinline{False} for all other cases.  \lstinline{or} evaluates to \lstinline{True} whenever \textit{at least one} value is \lstinline{True} (including when both are).

\begin{table}[ht]
\centering
\caption{Truth Table for \lstinline{and}}
\label{tab:FlowControl:AndTruth}
\begin{tabular}{|c|c|c|}
\hline
$A$ & $B$ & $A$ AND $B$ \\
\hline
False& False& False\\
\hline
False& True& True\\
\hline
True& False& True\\
\hline
True& True& True\\
\hline
\end{tabular}
\end{table}

\begin{table}[ht]
\centering
\caption{Truth Table for \lstinline{or}}
\label{tab:FlowControl:OrTruth}
\begin{tabular}{|c|c|c|}
\hline
$A$ & $B$ & $A$ OR $B$ \\
\hline
False& False& False\\
\hline
False& True& True\\
\hline
True& False& True\\
\hline
True& True& True\\
\hline
\end{tabular}
\end{table}

With one other operation, we can perform any comparison we want: \lstinline{not}, which is an operation only on one value that converts it to the opposite value (\lstinline{not True} evaluates to \lstinline{False} and vice versa).  These three operations allow us to generate arbitrarily complex comparison statements, for instance 
\begin{lstlisting}
pH > 7.0 and I > 1.0
\end{lstlisting}
returns \lstinline{True} only when pH is greater than 7.0 \textit{and} I is greater than 1.0, and \lstinline{False} in all other circumstances.  We can break this down to see how the statement is evaluated.  Suppose \lstinline{pH = 7.4} and \lstinline{I = 2.2}:
\begin{gather*}
7.4 > 7.0 \texttt{ and } 2.2 > 1.0 \\
True \texttt{ and } 2.2 > 1.0 \\
True \texttt{ and } True \\
True
\end{gather*}
Suppose instead that \texttt{I = 0.5}:
\begin{gather*}
7.4 > 7.0 \texttt{ and } 0.5 > 1.0 \\
True \texttt{ and } 0.5 > 1.0 \\
True \texttt{ and } False \\
False
\end{gather*}
Meanwhile,
\begin{lstlisting}
pH > 7.0 or I > 1.0
\end{lstlisting}
returns \lstinline{True} when pH is greater than 7.0 \textit{or} I is greater than 1.0, as well as when pH is greater than 7.0 \textit{and} I is greater than 1.0.  For the last example:
\begin{gather*}
7.4 > 7.0 \texttt{ or } 0.5 > 1.0 \\
True \texttt{ or } 0.5 > 1.0 \\
True \texttt{ or } False \\
True
\end{gather*}

It is important to control the order in which the individual operations are executed in complex comparison statements.  There is a systematic set of rules for this, similar to algebra (remember PEMDAS?).  In every day use, it is good practice to use parentheses to make your statements clearer to a human reading your code and to avoid the possibility of errors, particularly as your statements become more complex.  Suppose we add a condition to the first example so that we now want to do something not only if pH is greater than 7.0 and I is greater than 1.0, but also if pH is greater than 10.0 regardless of I.  The code for this comparison statement would look like
\begin{lstlisting}
(pH > 7.0 and I > 1.0) or pH > 10.0
\end{lstlisting}
We don't necessarily need the parentheses here, but it makes it much easier to figure out quickly what is going on.

\section{Conditionals: Choosing Between Two or More Options}
\setcounter{subsection}{-1}  % Start subsections from 0

Now that we know how to design tests, we are ready to use them to tell the computer how to make decisions and what to do after these decisions are made.  There are several common decision structures, which can basically be broken down into two categories: conditionals, which execute different sets of instructions depending on the results of a comparison, and loops, which execute instructions over and over until a specific comparison statement is met.  First, we will discuss specific implementations of the former.

\subsection{\texttt{if}: Do Something or Don't Do It}
\label{Sec:T:FlowControl:If}

The simplest flow control statement that we have at our disposal is the \lstinline{if} statement (sometimes called "if-then" statements): ``\lstinline{if <comparison statement evaluates to True>}, then do these instructions."  If the comparison statement ends up being \lstinline{False}, those instructions are not executed.  Figure \ref{fig:FlowControl:If-Then} demonstrates this process in the form of a flowchart.  In Python, this control structure is expressed as follows:

\begin{wrapfigure}[10]{lt}{.4\textwidth}
\includegraphics[width=.32\textwidth]{ChapTechnical/FlowControl/Figures/If-Then.pdf}
\caption{A flowchart depicting the operation of an \lstinline{if} statement.}
\label{fig:FlowControl:If-Then}
\end{wrapfigure}

\begin{lstlisting}
pH = input('What is the pH of your solution?')

if (pH <= 2.0):
	print('Wear rubber gloves and a face shield, that is a strong acid!')

#<rest of code>
\end{lstlisting}
Note that the indentation following the \lstinline{if} statement indicates the code to be executed if the comparison statement evaluates to \lstinline{True} (sometimes called the `then' part of an `if-then' statement).

\subsection{\texttt{if-else}: Do One of Two Things}
\label{Sec:T:FlowControl:IfThenElse}

\begin{wrapfigure}[8]{H}{.4\textwidth}
\includegraphics[width=.32\textwidth]{ChapTechnical/FlowControl/Figures/If-Then-Else.pdf}
\caption{A flowchart depicting the operation of an \lstinline{if-else} statement.}
\label{fig:FlowControl:If-Then-Else}
\end{wrapfigure}

Sometimes we will want to run some other code if the comparison in the if statement ends up being false, as shown diagrammatically in Figure \ref{fig:FlowControl:If-Then-Else}.  In this case, we can add an \lstinline{else:} command at the end of the indented block of code that is supposed to be run if the comparison is true.  The code for such a statement looks like this:
\begin{lstlisting}
pH = input('What is the pH of your solution?')

if (pH < 7.0):
	print('Your solution is acidic')
else:
	print('Your solution is basic')

#<rest of code>
\end{lstlisting}
Note here that the code to be executed if the comparison is \lstinline{False} is also indented in its own block, while the rest of the code removes this indent.

\subsection{\texttt{if-elif}: Do One of Many Things}
\label{Sec:T:FlowControl:IfElif}

We may still want to handle more possibilities than we can with just the \lstinline{then:} and \lstinline{else:} cases.  The intuitive way to do this is just to put another \lstinline{if} statement inside the code block of the \lstinline{else:} case:
\begin{lstlisting}
pH = input('What is the pH of your solution?')

if (pH < 7.0):
	print('Your solution is acidic')
else:
	if (pH > 7.0):
		print('Your solution is basic')
	else:
		print('Your solution is neutral')

#<rest of code>
\end{lstlisting}
This is straightforward but not ideal:
\begin{lstlisting}
pH = input('What is the pH of your solution?')

if (pH < 3.0):
	print('Your solution is strongly acidic')
else:
	if (pH < 7.0):
		print('Your solution is acidic')
	else:
		if (pH == 7.0):
			print('Your solution is neutral')
		else:
			if (pH < 11.0):
				print('Your solution is basic')
			else:
				print('Your solution is strongly basic')

#<rest of code>
\end{lstlisting}
There are a few things to worry about here.
\begin{enumerate}
	\item The code is harder than it needs to be to read.  Your eyes have to search to find each ensuing comparison, you are running out of horizontal space on each ensuing line because of the need for whitespace, and it is generally ugly.
	\item While the code as written works, we have to be careful about the comparisons we choose.  If, for whatever reason we had chosen a different order, we could see unexpected behavior.
	\item The code assumes without checking that the user actually entered a number and that the number was in a reasonable range for pH values.
\end{enumerate}

\begin{wrapfigure}[6]{H}{.33\textwidth}
\includegraphics[width=.32\textwidth]{ChapTechnical/FlowControl/Figures/If-Then-Elif.pdf}
\caption{A flowchart depicting the operation of an \lstinline{if-elif} statement.}
\label{fig:FlowControl:If-Then-Elif}
\end{wrapfigure}

With regard to point 1, a shorthand notation exists to make the code cleaner: combining the \lstinline{else} and the next \lstinline{if} into \lstinline{elif}.  The flowchart for a \lstinline{if-elif} statement is shown in Figure \ref{fig:FlowControl:If-Then-Elif}
\begin{lstlisting}
pH = input('What is the pH of your solution?')

if (pH < 3.0):
	print('Your solution is strongly acidic')
elif (pH < 7.0):
	print('Your solution is acidic')
elif (pH == 7.0):
	print('Your solution is neutral')
elif (pH < 11.0):
	print('Your solution is basic')
else:
	print('Your solution is strongly basic')

#<rest of code>
\end{lstlisting}
This code certainly looks nicer and it is much quicker to figure out how the different cases are actually different.

\subsection{Possible Pitfalls of Conditionals}

With regard to point 2, consider if we simply reversed the order of the first two comparisons:
\begin{lstlisting}
pH = input('What is the pH of your solution?')

if (pH < 7.0):
	print('Your solution is acidic')
elif (pH < 3.0):
	print('Your solution is strongly acidic')
elif (pH == 7.0):
	print('Your solution is neutral')
elif (pH < 11.0):
	print('Your solution is basic')
else:
	print('Your solution is strongly basic')

#<rest of code>
\end{lstlisting}
This \textit{looks} like it should do the same thing, but if the user inputs \lstinline{2.0} when prompted, the response will be \lstinline{'Your solution is acidic'}, not the expected \lstinline{'Your solution is strongly acidic'}.  This example illustrates a common problem in nested \lstinline{if} statements: the order in which the comparisons are executed can matter.  It is best to be as specific as possible when creating your comparison statements.  For instance, we can avoid the order of the statements mattering by comparing to specific ranges:
\begin{lstlisting}
pH = input('What is the pH of your solution?')

if (pH < 3.0):
	print('Your solution is strongly acidic')
elif (pH < 7.0 and pH >= 3.0):
	print('Your solution is acidic')
elif (pH == 7.0):
	print('Your solution is neutral')
elif (pH <= 11.0 and pH > 7.0):
	print('Your solution is basic')
elif (pH > 11.0):
	print('Your solution is strongly basic')

#<rest of code>
\end{lstlisting}
This code now has a specific range for each possible \textit{numerical} value of pH, and will execute as expected regardless of the order of the comparison statements.

In the last modification of the code, we also note that comparing the input to a range for each possibility also required removal of the \lstinline{else} statement.  This is also good practice for this kind of application of the \lstinline{if-elif} construct, and leaves the \lstinline{else} outcome available to use as a potential way to simply handle user input errors.  We could further modify the last example:
\begin{lstlisting}
pH = input('What is the pH of your solution?')

if (pH < 3.0) and pH >= -10.0:
	print('Your solution is strongly acidic')
elif (pH < 7.0 and pH >= 3.0):
	print('Your solution is acidic')
elif (pH == 7.0):
	print('Your solution is neutral')
elif (pH > 7.0 and pH <= 11.0):
	print('Your solution is basic')
elif (pH > 11.0 and pH <= 20):
	print('Your solution is strongly basic')
else:
	print('That is a crazy pH value.  Either you made a typo, or you should write a paper on that ASAP!')

#<rest of code>
\end{lstlisting}

\subsection{When to use \texttt{if-elif} vs. several \texttt{if} Statements}

It is important to realize that an if-else or if-elif statement will only execute \textit{one} possible pathway: the first comparison statement that it comes to that evaluates to \lstinline{True}.  No other pathway after that will execute, even if its comparison statement also evaluates to True.  Often this is the desired behavior, but not always.  Suppose, for instance, that we wanted to identify the hazards associated with a particular chemical.  If we only used an if-elif statement, the first hazard that we come across causes that statement to run and no other ones, subsequently continuing the program.  However, chemicals can certainly have more than one hazard, and thus this would yield incorrect output of this program.  In this circumstance, you should use a series of \lstinline{if} statements: each hazard would be tested, and each one that the chemical satisfies will cause the code specific to that hazard to execute, as expected.

\section{Loops: Doing the Same Operations Over and Over}
\setcounter{subsection}{-1}  % Start subsections from 0

When humans do the same thing over and over again, they get bored and may make mistakes.  Computers have no trouble doing things over and over and doing them perfectly each time.  In fact, this is one of the things at which they excel.

Loops are the control structures that allow you to tell the computer to do repetitive tasks.  It might be tempting to simply copy and paste the code we want to repeat until we get the desired number of repetitions, but there are a few flaws with this approach: (1) if you need to make a change to the repeated code, you have to change it in every instance, and (2) you have to know how many repetitions should run, and if that number changes, you have to change the code.  It would be better, then to only tell the computer what to do in one repetition, and then either tell it how many repetitions to do, or how to decide for itself when to stop repeating.  There are two basic types of loops to handle these tasks.

\subsection{General Remarks on Loops}

Regardless of the type of loop, there are a few common things we need to know.  First (in Python), the loop is denoted by a statement that tells the computer how to determine how many times to run the loop, followed by a colon (:).  Next, an indented block of code tells the computer what instructions to run for each repetition of the loop, where a repetition of the loop is known as an \cite{iteration}.  The computer will run these commands in order until there are no more lines of code at the same level of indentation, at which point it will decide whether to stop iterating and move on to the rest of your code, or it will go back to the first line of the indented black and start the next iteration.  You will commonly find people saying ``iterating through the loop," to describe the process of going from one iteration to the next.

Loops can utilize \cite{nesting}, meaning that there is a loop within a loop.  This can be useful for dealing with 2D or higher dimensional data such as images or matricies, in which each $x$ and $y$ pair of values must be addressed independently.  For instance, in a case with two nested loops, for each iteration of the outer loop, the inner loop will run all of its iterations in a row.  At the end of the iterations of the inner loop, the outer loop will move on to its next iteration and the inner loop will begin again.  Always be careful with nested loops, since the number of iterations of the nested loops grows as the product of the number of iterations of the individual loops!

In almost all cases, if you update variables defined outside of the loop in any given iteration, that variable will retain its value for the next iterations until you change it again.  

\subsection{For Loops: Do the Same Set of Instructions a Fixed Number of Times}
\label{Sec:T:FlowControl:For}
\setcounter{subsubsection}{-1}  % Start subsections from 0

\begin{wrapfigure}[14]{H}{.33\textwidth}
\includegraphics[width=.32\textwidth]{ChapTechnical/FlowControl/Figures/For.pdf}
\caption{A flowchart depicting the operation of a for loop.}
\label{fig:FlowControl:For}
\end{wrapfigure}

For loops are a type of loop that iterates a set number of times.  In Python (but not in many other languages), we do not directly tell the for loop how many times to iterate.  Instead, we provide it with a variable of a type that is iterable,\footnote{See Chapter \ref{DataTypes} for details.} and the for loop runs one time for each element of this iterable variable.  Python provides a specific syntax to do this:
\begin{lstlisting}
for <temp variale holding element> in <collection>:
	<code to repeat>
\end{lstlisting}
What is happening here is that Python takes a look at your iterable variable to see how many elements are in it --- from that it will determine the number of iterations.  Then, the for loop will iterate one time for each element in the iterable variable, in the order that they arise in the iterable variable.  For the purposes of the code to repeat, that element will be referred to as whatever variable name you give in the \lstinline{<temp variable holding element} position of the for statement.  If you perform an operation within an iteration that changes the value of this element, those changes are reflected in the iterable variable.  When the loop moves from one iteration to the next, the value in this temporary variable is replaced by the value of the next element in the iterable variable.
\begin{lstlisting}
for pH in pH_array:
    if pH > 7.0:
        print('Sample is basic')
    elif ph < 7.0:
        print('Sample is acidic')
    else:
        print('Sample is neutral')
\end{lstlisting}
Sometimes, we don't specifically want to iterate over the elements of an iterable like a list, but rather to do something a set number of times or to know which iteration we are doing.  In this case, we can create an iterable that just contains the iteration number using the \lstinline{range} type,\footnote{For more on this data type see Chapter \ref{DataTypes}.} which produces an iterable containing the integers 1, 2, 3, ...  We can then use this \lstinline{range} variable as the iterable variable, and thus our variable holding the value of the iterable variable for each element is simply the iteration number.
\begin{lstlisting}
for i in range(len(x)-1):
    delta_x[i] = x[i+1] - x[i]
\end{lstlisting}
Note that this is not necessarily the best way to do this!

\subsubsection{\texttt{enumerate}: get the iteration number and a list element}

Sometimes, in each iteration we want to know \textit{both} the iteration number and the current element of the iterable variable.  For this, we can use the \lstinline{enumerate} type, which returns a tuple like (<iteration number>, <current element of iterable variable>) for each iteration.  We could achieve similar results by simply iterating over a \lstinline{range} and then using the current iteration number as the index of an iterable variable, but the \lstinline{enumerate} type makes this simpler and more readable.  See Section \ref{Accessing_the_number_of_times_a_loop_has_iterated_using_enumerate} for some example uses.

\subsubsection{\texttt{zip}: iterate elements from multiple lists together}

\begin{wrapfigure}[17]{r}{.33\textwidth}
\includegraphics[width=.32\textwidth]{ChapTechnical/FlowControl/Figures/While.pdf}
\caption{A flowchart depicting the operation of a while loop.}
\label{fig:FlowControl:While}
\end{wrapfigure}

Similarly, we sometimes would like to iterate over two or more different iterable variables, like the $x$- and $y$-coordinates of some data.  We can do this with a \lstinline{zip} type, which is similar to \lstinline{enumerate} but it returns a tuple containing the current elements of two or more iterable variables.  Again, we could achieve the same essential functionality by iterating over a \lstinline{range} and indexing each iterable variable, this is easier.  See Section \ref{Synchronizing_iteration_through_multiple_collections_using_zip} for some example uses.

\subsection{While Loops: Do the Same Set of Instructions Repeatedly until a Condition is Met}
\label{Sec:T:FlowControl:While}

For loops are great when there is a straightforward way to determine the number times a loop should iterate, and while this is generally preferable, it is not always possible.  In these cases, we can use a \lstinline{while} loop instead.  A \lstinline{while} loop statement contains a conditional test, and the loop will continue to iterate as long as this test evaluates to \lstinline{True}.  Notably, if the conditional test is not \lstinline{True} when the while loop is first encountered, it will not run at all.  If the conditional test becomes \lstinline{True} in the middle of an iteration, that iteration will complete before the loop executes.  \newpage

\begin{lstlisting}
data = []
stop = False
while stop is not True:
    pH = input('Enter the pH, or "stop" to stop.')
    if pH == "stop":
        stop = True
    else:
        data.append(pH)
\end{lstlisting}
While useful, \lstinline{while} loops have two major disadvantages.  First, they are slower than \lstinline{for} loops because Python doesn't have a way to know how many times they will iterate.  Secondly, and more importantly, it is possible (easy, even) to create a \lstinline{while} loop that \textit{never} ends:
\begin{lstlisting}
counter = 0

while counter == 0:
	print(counter)
\end{lstlisting}
Since \lstinline{counter} never changes, each time an iteration ends, the conditional test \lstinline{counter == 0} will always be true.  


\subsection{\lstinline{with}: letting Python take care of boring stuff for you}

In coding, there are many things that you have to just do that don't actually move you towards a solution to a problem.  To the extent that a language reduces the number of these things, it will likely make you more productive.  The \lstinline{with} structure is one instance of Python relieving you of tedium.

The most common scenario in which you will encounter \lstinline{with} is reading or writing data from/to a file.  A typical code that reads arbitrary data from a file looks like this:
\begin{lstlisting}
file_to_read = open(<filename.txt>)
<code to read and parse input>
file_to_read.close()
\end{lstlisting}
Using \lstinline{with}, this is somewhat simplified:
\begin{lstlisting}
with open(<filename.txt>) as file_to_read:
	<code to read and parse input>
\end{lstlisting}
This may not seem much better, but there are two advantages here: first, Python will figure out when you need to close the file.  This can be useful for codes that do more complex file I/O.  Secondly, and more importantly, sometimes your code will create an error and stop executing before you have a chance to close the file.  If this happens, the file could remain open, preventing another program from using or changing it, or it could become corrupted, causing the important data stored in it to be no longer usable.  The \lstinline{with} statement will notice when the code in its code block throws an error and will still close your file for you, preventing most of these unfortunate situations.  Thus, it is almost always better to let \lstinline{with} handle file opening and closing for you.

\subsection{\texttt{try}: keep your code executing even after an error occurs}
Sometimes (often), your code will have one of two errors: a logic error, in which the code runs as intended but does something that you do not expect, and a runtime error, in which your code tries to do something improper, or that is impossible.  The latter of these will raise an \textbf{exception}, which is what happens when Python basically doesn't know what to do.  When exceptions occur, Python stops trying to execute the line of code that it is working on, and produces a \textbf{traceback} with a history of your code's execution and a terse description of the problem that caused it to stop.  More details on errors in Python can be found in Section \ref{Errors}, but for our purposes here, the most important one is that an exception is an object that contains descriptive information that helps you determine what the problem was.

Not all exceptions are equally alarming and you might wish that your code would keep running, even if there was an error.  Suppose that you ask a user to input a number that you intend to use to do math, but they instead input a letter.  As soon as you try to do math with this letter, your program will raise an exception:

\begin{pyin}
number = input('Please type a number to be squared: ')
\end{pyin}
\begin{pyout}
Please type a number to be squared: k
\end{pyout}
\begin{pyin}
number ** 2
\end{pyin}
\begin{pyout}
Traceback (most recent call last):

  Cell In[4], line 1
  
    number **2


TypeError: unsupported operand type(s) for ** or pow(): 'str' and 'int'
\end{pyout}

The last line tells you what the exception was, in this case, a \textbf{TypeError}.  However, this is not a catastrophe, and certainly no reason that we would want our code to stop.  It would be better to just tell the user that they messed up and ask them to try again.  This way, we won't lose any of our previous work, and we won't require the user to start over again.  We will also be able to give the user clear feedback on what they did wrong, so that they won't (hopefully) do it again.  The \lstinline{try} statement is Python's way to make this easy for us.

The structure of a \lstinline{try} statement is somewhat complex, and not all of it is required.  In its simplest form, it looks something like:
\begin{lstlisting}
number = input('Please type a number to be squared: ')
    try:
        number ** 2

    except TypeError:
	print('You did not type a valid number!)
\end{lstlisting}
The \lstinline{try} statement is required.  The code in the code \cite{block} of the \lstinline{try} statement (ideally one line) will be executed regardless.  If this code executes without raising an exception, then the code in the \lstinline{except} block is ignored.  However, if the code in the \lstinline{try} \cite{block} raises a \lstinline{TypeError} exception, then Python will execute the code in the \lstinline{except} code block.

In cases like this, just handling the error is not very helpful.  Yes, the code continued to execute, but if any other code later in the program needs \textit{number} to be a number, it will also fail.  It would be better to not just tell the user that they messed up, but also to allow them an opportunity to fix it.  This can be done with a while loop:
\begin{lstlisting}
input_okay = False
while input_okay == False:
    number = input('Please type a number to be squared: ')
    try:
	square = number ** 2
    except TypeError:
        print(f'{number} is not a valid number type.  Please try again.')
    else:
        input_okay = True

\end{lstlisting}

Here the \lstinline{else} statement is intuitive: if no exception is raised, then everything went fine and we can exit the \lstinline{while} loop.

\lstinline{try} structures also include a \lstinline{finally} block, which will run regardless of what happens in the \lstinline{try-except-else} blocks.  This segment is useful for showing the results of the code in the \lstinline{try} block or cleaning up opened files/streams etc.  For instance, we could add the following to our last example:

\begin{lstlisting}
    finally:
        print(f'The square of {number} is {square}.')
\end{lstlisting}

Adding this to the end will ensure that we output the final answer, and that it happens as part of the control structure. 

\end{document}