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

\setcounter{secnumdepth}{3}



\begin{document}


\chapter{Simplifying Repetitive Calculations}
\label{Chap:N:00ExpDes}
% reaction optimization
\setcounter{section}{-1}  % Start sections from 0

\input{prereqs/00aExpDes_prereqs} %prereqs go here

\newpage
\section{Problem}
\setcounter{subsection}{-1}  % Start subsections from 0

You recently developed a new aqueous catalyst that relies on a proton transfer step.  Obviously, the efficacy of the catalyst will depend on the p$H$ of the solution relative to the p$K_a$ of the catalyst.  However, you are also concerned that the p$K_a$ of the catalyst will, in turn, depend on the ionic strength of the solution. This suggests you need to run multiple titration experiments, each  conducted under a different (but constant) ionic strength. 

While you are excited to run these experiments and lay the groundwork for your first paper, it will take some work. Fortunately, your lab has a 24 plate reader that can measure the p$H$ of the solutions.  This means that you could run multiple experiments at once, where you could use the 4 rows for different constant ionic strengths and the 6 wells in each row for different p$H$s. Each well's condition could be made by mixing together different amounts of stock solutions. Deciding you will titrate with HCl, you produce the following sketch of the experiment:

\begin{figure}[H]
    \centering
    \includegraphics{ChapNarrative/00aExpDes/Figures/EmptyWellPlate.png}
    \caption{Schematic of a 24 well plate, showing the desired changes in chemical composition. }
    \label{fig:ExpDes:WellPlate}
\end{figure}

   
Though the plate reader will save you measurement time, it also  means that you need to calculate all 24 conditions and keep track of them. You mention to \first that you are excited to do the experiment but are not looking forward to doing these tedious calculations and double checking them. This is particularly true since your advisor has a habit of changing their mind regarding the exact limits of reaction---and each time the limits change you will need to recalculate the conditions. 
 
You know that you could set up a spreadsheet to do this in Microsoft Excel, but the fact that you wanted to maintain a constant volume across the experiments means that the formulas in Excel become cumbersome and it will be hard to use the spreadsheet while you're actually making the solutions. You'd rather just have a checklist of what goes in each well so that you can be sure you won't make a mistake and have to repeat the experiment.

You are talking about this in lab on morning and \first mentions that this really hasn't been a problem for them since they learned to code.  Intrigued, you ask what they mean. They say that coding is a perfect tool for these repetitive tasks---it has reduced their mistakes \textit{and} improved their life in lab. They say that you could write a simple program that would calculate everything you need and could adapt to whatever limits your advisor decides they want that day. They say that it should take only two lunch hours to get you to the point you can solve this problem. 

They point out that the very \textit{first} time you implement this solution might take longer than calculating by hand once, but that you will have generated a general tool that can be used again and again.  So, the more frequently your advisor changes their mind, the more time you will save in the long run. 

You realize that this could reclaim \textit{years} of your life. You agree to meet over lunch, and \first tells you to bring your laptop with you. 

%
% SOLUTION
\section{Solution}
\setcounter{subsection}{-1}  % Start subsections from 0

When the first lunchtime comes, you walk into the break room, and \first is waiting.  The solution to your problem, they explain, will be achieved by outlining the constraints of the experiment, expressing them in terms of calculations that you would normally do on a calculator, and then writing a bit of code that will do these calculations automatically for you. You will do so by storing information about your stock solutions and required final concentrations in the computer and then telling it how to calculate the volumes of each stock solution to add to the well.  This first lunch hour, they want to get you to the point you can do this for a single well. Even this will show you how using the code can save you time over using a calculator or Microsoft Excel. Then, in the the next lunch hour, they will show you how to adapt this to the rest of the wells in a straightforward manner.  This all sounds great to you, so you sit down and open your laptop.



\subsection{Giving your computer instructions using Python commands}
\label{Giving_your_computer_instructions_using_Python_commands}

``The most basic thing to understand'' \First starts, ``Is that programming is a set of instructions for the computer and, at its heart, a computer is not much more more than a calculator with memory. This means your code is going to be a set of instructions, but that these instructions are ultimately turned into numbers. So, you need a way to take language that \textit{humans} understand (\textit{i.e.,} words) and translate them into language that your \textit{computer} understands (\textit{i.e.,} numbers). When someone talks about programming languages, they are referring to how this translation is accomplished.'' 

``Each coding language includes a program that performs this translation. The most basic task in coding is to write your instructions in a way that the translating program can understand.'' The structure and terminology required for these instructions to be understood by the translating program is called the \cite{syntax}, and the appearance of this syntax is one of the most obvious differences between languages.  That is, the exact same instructions written in two languages will look very different. 

% \begin{wrapfigure}{r}{.5\textwidth}
%     \begin{mdframed}
%         \textbf{Note On Installing Python}
%         \noindent We strongly recommend following the procedure outlined on the companion website for this book, \website, to obtain the full functionality that will be covered in this book.  There are many ways to get something that will work, but you will avoid annoyance and get some extra capability installing Python our way!
%     \end{mdframed}
% \end{wrapfigure}

``I like the Python language," \First says, "because its syntax is easy to learn and understand and there are a huge number of tools for chemistry that can be used with it. There are a lot of ways to install Python on your computer, but I recommend starting 
by installing basic Python from \href{https://www.python.org/}{https://www.python.org/}.
%with the Anaconda Distribution, which simplifies management of Python and its extensions.''
\footnote{We strongly recommend following the procedure outlined on the companion website for this book, \website, to obtain the full functionality that will be covered in this book.  There are many ways to get something that will work, but you will avoid annoyance and get some extra capability installing Python our way!}

``Once Python 
%Anaconda 
is installed, the simplest thing you can do is to open 
%it, open an ``anaconda prompt" (Windows) or ``terminal," (Macs) and type \lstinline{idle}.  This opens up 
Python's Integrated Development and Learning Environment (IDLE),\footnote{If you are having trouble, visit the website for this book (\website) for help.} which allows you to type Python commands and start calculating things."

Opening IDLE, you are presented with a window that looks something like what is shown in Figure \ref{fig:ExpDes:IDLE} \First explains that this box is sometimes called a \cite{shell} or a \cite{console}. You can enter commands and then press enter and the computer will read them and try to execute them. In this case, you are going to input Python commands, and the \cite{Python_interpreter} program is going to try to execute them. 

\begin{figure}[H]
    \centering
    \includegraphics[width = 4in]{ChapNarrative/00aExpDes/Figures/IDLE.png}
    \caption{Screenshot of the IDLE interface for Python in the Windows operating system. This is one way to use Python interactively. You can enter commands with proper Python \cite{syntax}, and they will be executed.}
    \label{fig:ExpDes:IDLE}
\end{figure}



% computer = calculator
\subsection{Having Python do basic math by evaluating mathematical expressions}
\label{Having_Python_do_basic_math_by_evaluating_mathematical_expressions}

``Remember how I said the computer is a calculator?'' \First begins. ``Try adding 2 and 3.  You can type it into the command prompt, denoted by \texttt{>>>}.''

You look at \first{} but they just raise their eyebrows and wait. So, you tentatively type:
\begin{pyin}
2+3
\end{pyin}
and press enter.  Immediately, a new line appears with:
\begin{pyout}
5
\end{pyout}

``Great! This is the first line of code that you have ever written!  What you typed into the command prompt is a mathematical \cite{expression}, using the \cite{operator} `+'. Python reads the expression on the input line (represented in this book by light gray, and preceded by \lstinline{>>>}), carries out all the operations specified by operators, and prints out the result on an `output line' (represented in this book by darker gray).  Now what if you wanted to multiply them?''  Here, you think a bit, but remember that other programs, like Excel, use `\textasteriskcentered{}' to indicate multiplication and so you try that. 

\begin{pyin}
2*3
\end{pyin}
\begin{pyout}
6
\end{pyout}

``Ok, now, how about division?  What if you divide 2 by 3?''

\begin{pyin}
2/3
\end{pyin}
\begin{pyout}
0.6666666666666666
\end{pyout}

``Ok,'' \first says ``This is working just like a calculator.  You know that 2/3 is not a rational number---that it will keep repeating forever.  But a \textit{calculator} has a limited display, so it just writes 0.666... until it runs out of display room.  The computer is similar to this.  It has a lot more display room than your typical calculator, but each number does require some storage in the computer, and the computer does not have infinite storage.  So it has to eventually stop writing numbers. We will talk about how to control the representation of numbers later.  Another thing you will run into is this..." they say while typing:
\begin{pyin}
.01/.1
\end{pyin}
\begin{pyout}
0.09999999999999999
\end{pyout}
``We know that the answer should be 0.1, but actually, the computer doesn't know what 0.1 is. The problem is, again, that the computer has a limited amount of storage, and so it cannot store all of the real numbers---which would take an infinite amount of storage.  Thus, the computer works with only a limited subset of real numbers and 0.1 isn't one of them.  It is up to you to realize that 0.09999999999999999 is as close as Python will come to the correct answer.  This concept is called \cite{numerical_precision} and in almost all cases, you will find that the precision of Python is close enough for your needs.  You might have a strong desire to  make the output look nicer, but if you can wait just a bit, we will get to that.  For now,  realize that as soon as you move away from situations where all the numbers involved are whole numbers, your answers will typically be \textit{very} close to correct but not \textit{exactly} correct.

``Now, there will be other things that are a bit different from a calculator or Excel. For instance, what if you want to calculate two to the third power? In Excel, the \cite{operator} for exponent is \lstinline{^}, and many calculators use the same symbol. In Python this operator is is `\textasteriskcentered{}\textasteriskcentered{}':"
\begin{pyin}
2**3
\end{pyin}
\begin{pyout}
8
\end{pyout}
You can see that the output is what we expect for raising 2 to the third power.  Thus, this is the same operator as \lstinline{^}, Python just uses a different \cite{syntax} than Microsoft Excel or your calculator.



\subsection{Accessing capabilities beyond basic math using functions}
\label{Accessing_capabilities_beyond_basic_math_using_functions}

"Now," \first says, "you can probably think of lots of different symbols for doing math, but sometimes programs don't have them all. Since we are considering similarities and differences with Microsoft Excel, consider taking the absolute value of a number.  If you wanted to take the absolute value of a number in Excel, you use the absolute value \cite{function} using the command \texttt{abs(-2)}.  It turns out that, Python happens to use the exact same idea and notation: \lstinline{abs()}."

\begin{pyin}
abs(-2)
\end{pyin}
\begin{pyout}
2
\end{pyout}
``And here, we have introduced a new bit of \cite{syntax}. We have taken a value we want to operate on, and placed it between two parenthesis, preceded by a name.''

``In Python, the term for the the command with the parentheses is a \cite{function}, while the number that we place between the parentheses an \cite{argument}.  Functions can evaluate to values in the same way as mathematical expressions can be evaluated to yield a single value.  In this case, it evaluated to the value of `\lstinline{2}', but not all functions evaluate to values.  Functions can also be written to accept any number of arguments---including no arguments. The \lstinline{abs()} function expects a single argument.  But we can consider a different function---one that can accept either one or two arguments: \lstinline{round()}.''

``Invoking the code in a function is referred to as \cite{call}ing the function.  To start with, we include, only a single argument in the function call: the number to be rounded.  Once called, the function evaluates to the argument value, rounded to a whole number.''

\begin{pyin}
round(3.14159)
\end{pyin}
\begin{pyout}
3
\end{pyout}
\begin{pyin}
round(3.5)
\end{pyin}
\begin{pyout}
4
\end{pyout}
\begin{pyin}
round(4.5)
\end{pyin}
\begin{pyout}
4
\end{pyout}

``Take a close look at these last two examples,' \First says, pointing at their computer's monitor, ``you might be surprised that both numbers were rounded to 4.  This is probably not how you were taught to round. Most people in the USA were taught to round up, when presented with a 5 at the decimal place where they are rounding. However, Python uses a different rule, known as `bankers' rounding. Because always rounding a 5 upwards will tend to bias in reported statistics for measurements, a rule is created to eliminate this bias. If the digit before the 5 is odd, we round up.  If the data before the 5 is even, we round down. Though this may look strange, it produces a result that, in the long term, has less bias.''


``We can exercise greater control over the behavior of the \lstinline{round()} function by using another argument. This second argument comes after the number we wish to round, has a specific name, and in this case, tells the function the number of decimal places to keep after rounding.''

 
\begin{pyin}
round(3.14159, ndigits = 2)
\end{pyin}
\begin{pyout}
3.14
\end{pyout}
\begin{pyin}
round(1.61803, ndigits = 3)
\end{pyin}
\begin{pyout}
1.618
\end{pyout}

This could be used to solve the issue we encountered above with \cite{numerical_precision} and the answer to 0.01 divided by 0.1.  For instance, if we wanted we could use the following

\begin{pyin}
round(0.01/0.1, ndigits = 1)
\end{pyin}
\begin{pyout}
0.1
\end{pyout}

``And so now we are getting the answer \textit{displayed} as we expect, but there are two things to realize here. First, the answer the computer calculated for 0.01/0.1 was not 0.1. We we saw that before (Section \ref{Having_Python_do_basic_math_by_evaluating_mathematical_expressions}).  We have asked it to round to give the answer we expect... so really we are just asking for the answer to a precision of 1 decimal place. This is a technical point, and it is, but it is worth keeping in mind. Second, you will notice that we did math \textit{within} an argument passed to a function.  That is, we specified a mathematical operation, and this was evaluated, and then the result of this evaluation was used as the argument. This is our first hint that, when coding, we are going to be able to combine many different operations in a single line of code!


``One more important thing about function arguments---you notice that we always need to supply a value for the number that we are rounding, but we don't always have to supply the digits to round to.  
We say that the former is an required argument that is often referred to as a \cite{positional_argument}, while the latter is an optional argument that is often called a \cite{keyword_argument}. Positional arguments are arguments without which the function cannot run. When you call the function, all required arguments must have values. However, for keyword arguments, the function has a default value that it will use, if you do not pass a value for it.  In the case of round, \lstinline{ndigits} uses the default value that essentially acts as if it were 0---meaning that the number will be rounded to its integer value.

``Another thing that we see above is that we don't always need to use the construction \lstinline{ndigits = <value>}. In the last input line, we simply gave the value we wanted. This is the behavior of positional arguments, and the order in which they are passed determines how they are used in the function. However, we can also use the name of the keyword argument that we wish to assign the value to, and this is what we were doing when we used \lstinline{ndigits = <value>}.  All things being equal, it is much clearer to just use the keyword, so that's what I always do.''

%The latter is an example of optional arguments, called \cite{keyword_argument}s in Python, which are different than the required \cite{positional_argument}.  Positional arguments are arguments without which the function can not run.  When you call the function, all of the positional arguments need to have values, and their order is critical for the function to execute correctly.  Keyword arguments are different: they have default values, so if you don't specify them, then the function just assumes that they are the default.  For \lstinline{round()}, the default number of digits is just zero unless you specify them.  

``All of this might seem a bit overwhelming at first, and there is certainly a lot of terminology to learn.  But Python also has some built-in functions to help. If you want to know what the required and optional arguments of a function are, the easiest way to do it is to type \lstinline{help(<name of function>)}, where \lstinline{<name of function>} is just the name of the function.  In this case, we could type:"
\begin{pyin}
help(round)
\end{pyin}
\begin{lstlisting}
Help on built-in function round in module builtins:

round(number, ndigits=None)
    Round a number to a given precision in decimal digits.

    The return value is an integer if ndigits is omitted or None.  Otherwise
    the return value has the same type as the number.  ndigits may be negative.
\end{lstlisting}
``Let's have a look at this output.''

``Line 1 just tells you what you asked for.  It gives you the name of the function, and where it is located.  In this case \lstinline{builtins} indicates this is part of the base Python.''

``Line 3 is the start of the function---what is called the function `signature'. We see the name of the function, and then information between parentheses. These are the things that the arguments get passed to---basically \cite{variable}s within the function. The technical name for this is \cite{parameters}. So, parameters exist in the function (as variable names) and arguments are the values that are passed (assigned) to them, when you \cite{call} a function. In this case, we see that there is a parameter \lstinline{number}, and a parameter \lstinline{ndigits}.  The \lstinline{ndigits} parameter is also followed by an assignment (\lstinline{=None})\footnote{A thing to note here: the default value is actually \lstinline{None}, not 0. \lstinline{None} is the value specific to a \cite{data_type} in Python. You don't need to know more about this yet, but if you are curious, this is discussed in the chapter on data types (Chapter \ref{DataTypes}.}, which is the default value used, if no value is passed as an argument. The parameter \lstinline{number} does not have this assignment, and so has no default value.  This is why \lstinline{number} is a required argument and \lstinline{ndigits} is an optional argument in the function call.''

``The rest of the lines gives details about how the function works and what values it will \cite{return}. For instance, look at the very end of Line 7.  This states that \lstinline{ndigits} can accept a negative number!  But it doesn't say what this does, so let us see!''

%``In this case, the first argument (number) is a positional argument, while the ndigits is a keyword argument, identified by the use of the `=' sign.''\footnote{There are more kinds of arguments, and you can read about them in the technical chapter on Functions.  However, we do not need to know about them yet.}

%``Another interesting behavior of \lstinline{round()} is that you can also provide negative numbers, which will produce integers that are rounded to the specified number of digits before the decimal.'' 
\begin{pyin}
round(42, ndigits = -1)
\end{pyin}
\begin{pyout}
40
\end{pyout}
\begin{pyin}
round(180.156, ndigits = -2)
\end{pyin}
\begin{pyout}
200.0
\end{pyout}
``So, you can see that negative values passed to \lstinline{ndigits} will result in integers that are rounded to the specified number of digits before the decimal.''

``This could be a useful way to show significant figures, but be careful---as you can see in the last example, when rounding a number with a decimal place to negative decimal places, the number will still contain a decimal place. This might lead to confusion regarding significant figures. There are ways to solve this,'' \First says. ``But that is going to have to wait until our next lunch.''

%``One more thing---sometimes you will see people use keyword arguments as positional arguments.  You can do this if you provide arguments to the keyword in the order that they are defined in the function definition without naming the keyword, but \textit{this can get you in trouble}, so I don't recommend doing it.  It is a little more typing to include the keyword but it makes your code easier to read and less likely to have an error!"

``For now, let's start using this cool calculator for some chemistry!''


%
% change circle area to volume from concentration
%
\subsection{Clarifying how your code works with comments}
\label{Clarifying_how_your_code_works_with_comments}

``Even now, you already know enough to calculate chemically-relevant things like the number of molecules present in 1 g of water.  You also already know how to do this on paper; it would look like:''
\begin{align*}
    \textrm{\# of molecules of water} = 1 \textrm{ g} \left(\frac{1 \textrm{ mole}}{18 \textrm{ g}}\right)\left(\frac{6.022\times 10^{23} \textrm{ molecules}}{1 \textrm{ mole}}\right)
\end{align*}
``We can translate these numbers and mathematical operations directly to code, with one important difference: \textit{Python does not know about units by default.} Like your calculator, it just does math on numbers and you will have to keep track of units yourself. Keeping this in mind, we can calculate the number of molecules in 1 g of water:''

\begin{pyin}
1*1/18.02*6.022*10**23
\end{pyin}
\begin{pyout}
3.341842397336293e+22
\end{pyout}

``It is important to talk about how the answer is formatted. We input Avogadro's number using the sort of scientific notation that most scientists are taught---the general format <\#>$\times10^{<\#>}$.  However, even though we might expect our final answer to also be formatted using this same notation, Python represented it differently." Instead of using `*10**<\#\#>' for the order of magnitude, it used `e<\#\#>,' which saved some room, and might even be easier to read.\footnote{This is sometimes referred to as \cite{e_notation}.}  A \textit{critical} point here is that there are no spaces between the digits and the `e.' 

``And, remember, Python doesn't include any units in the answer. But \textit{we} know units are  important. Rather than needing to always remember what the units are, we can we can leave ourselves notes about this using \cite{comment}s. In Python, we can add a comment to any line using `\#' and then adding text after it. Once a comment is started, that will be the last thing on the line.  In other words, if you want the line to have both \cite{executable_instructions} and comments, the comments need to come last.'' \First leans over and does the typing this time:

\begin{pyin}
1*1/18.02 # final answer in mols
\end{pyin}
\begin{pyout}
0.05549389567147614
\end{pyout}

``You see three things here. This is the same format that Python output last time. 
First, the comment is a different color from the numbers, which are also different colors from the mathematical operator symbols you supplied (like multiplication, \textasteriskcentered{}). They say this is called \cite{syntax_highlighting} and is meant to make it easier to read code. 
Second, I have added a comment to the end of the expression.  
Third, the output is the same, but we now have a record that the units were molecules.'' 

''You could also make a line entirely a comment." They also lean over and type: 
\begin{pyin}
# We want to calculate number of molecules in 1 g water.
\end{pyin}
\begin{pyin}
1 * 1 / 18.02 * 6.022e23 # final answer in units of molecules
\end{pyin}
\begin{pyout}
3.341842397336293e+22
\end{pyout}

\First stops here and says that there are again three things they want you to notice. 
First, the line that was entirely a comment was run, but it didn't result in an output. 
Second, I  used the e notation for the order of magnitude. 
Finally, they point out that, though you may not have noticed, they added spaces between several of the numbers and the operations.  They say that Python largely ignores spaces \textit{between} numbers and operators in an expression and so you can add in these space to help increase the readability of the code---but it is \textit{critical} to not add a space between the number and `e' when you are using this to add an order of magnitude, because this represents a single number only when they are given together without spaces.

``There are other rules for using spaces, but I will help you learn them as you go."

``Before we move on, there's one more thing,'' \first says. ``Everything we have been doing so far is evaluating \cite{expression}s, where expressions are basically a complete set of instructions.  In our case, the result the evaluation was printed below our input line, and this is the default behavior in Python.  In other words, unless we go out of our way to direct the result to something else, it just goes to the command line output.\footnote{This is not actually always the case, but for this moment in time, we will pretend it is. Later in this chapter, we will learn a different way to ensure this always happens---the \texttt{print()} function.}  However, there are other options. Above (Section \ref{Accessing_capabilities_beyond_basic_math_using_functions}), we passed the result of the expression 0.01/0.1 to the \lstinline{round()} \cite{function}. Another option is that we can transfer the result to the computer's \cite{memory}, so that we can use it later.'' 

% Memory
\subsection{Temporarily storing data using variables}
\label{Temporarily_storing_data_using_variables}
%
%  Memory becomes the desired moles and/or stock concentration 
%

``Up to this point, you may not really see the major advantage of using coding. You may be asking yourself why not just use a calculator?'' \First says. However, they point out that the computer has better \cite{memory} than a calculator, and this can be very useful.  For instance, what if you didn't want to type out the value of Avogadro's number ($N_A$) all the time? You can give it a name, and then use that name. This is known as creating a \cite{variable}, which is a name that you can use in your code to avoid having to keep track of the value yourself.  You can pick almost any name you want, as long as you follow a few rules, such as the name cannot start with a number.\footnote{If you want to know the full set of rules, you can read technical Section \ref{Sec:T:Computers:Storing_Data_in_Memory}.}  For our variable, \lstinline{N_A} might be a nice choice, since it looks a bit like $N_A$. Using sensible and descriptive names is good practice. Your future self will definitely be grateful that your past self did so.''

\begin{pyin}
N_A = 6.022e23
\end{pyin}
\begin{pyin}
N_A
\end{pyin}
\begin{pyout}
6.022e+23
\end{pyout}

``On the first input line, you created a \cite{variable} called `\lstinline{N_A}' and \cite{assign}ed it a value of \lstinline{6.022e23} using the assignment \cite{operator} (\lstinline{=}). The number \lstinline{6.022e23} is not a variable, it is the actual value that you want to use in the expression, and this turns out to be known as a \cite{literal}.  Literals are not stored and have to be retyped every time."

``This assignment \cite{statement} does not result in an output, because the assignment operator (\lstinline{=}) redirects the result of evaluating the \cite{expression} (on the right side of the equals sign) from the output to instead be stored by the \lstinline{N_A}. However, in the next input line, you ask for the value of the variable \lstinline{N_A}.  Now, Python evaluates the expression `\lstinline{N_A},' and passes the result (\lstinline{6.022e23}) to the output."

``Rather than passing the value of the variable to the output, we can pass it to an operator, like this:''

\begin{pyin}
N_A * 1 * 1 / 18.02 
\end{pyin}
\begin{pyout}
3.3418423973362933e+22
\end{pyout}

``Here, multiple things happened in a single line. First, \lstinline{N_A} was first evaluated effectively replacing the variable with its value. Then, the leftmost multiplication was evaluated. The value resulting from that evaluation was used in the next multiplication. That multiplication was evaluated and \textit{it's} values was used in the division.  Finally, the division operation was evaluated and the result was displayed in the output line."

``We can also take the result of expressions with variables in them and assign the result to a variable. For instance:"
\begin{pyin}
N_water = N_A * 1 * 1 / 18.02 
\end{pyin}
``Then, asking for the value of of \lstinline{N_water} will return the value we saw above:"
\begin{pyin}
N_water
\end{pyin}
\begin{pyout}
3.3418423973362933e+22
\end{pyout}

``It is worth noting something about the order of all these operations. Essentially, the math follows standard order of operations\footnote{That you probably learned as PEMDAS - parentheses, exponent, multiplication, division, addition, subtraction.}. But in Python, the part of the expression to the right of the equals sign is evaluated first, and then passed to the assignment operator (`='), which then assigns the value to the variable \lstinline{N_water}."

``Whew! That is a lot of detail,'' \first says, ``and not anything we need to talk about over and over again, but it does show that all Python is doing is evaluating expressions and then passing results along. Coding is basically planning out expressions and describing how their results are passed around. And variables are going to play a key role in how we manage all of that.''

``You can use variables for anything you would like the computer to remember, like holding the value of the number of grams you have or the molecular mass of water."

\begin{pyin}
g_water = 1
\end{pyin}
\begin{pyin}
MW_water = 18.01528 # g/mol
\end{pyin}
\begin{pyin}
g_water / MW_water * N_A
\end{pyin}
\begin{pyout}
3.3427179594211138e+22
\end{pyout}

``There is a point worth making here. The number 18.01528 might look funny as the mass of water, but it shows yet another advantage of coding and computer \cite{memory}: since we can save a value and use it over and over again, we don't waste time typing all those decimal places over and over, letting use as high precision as we like quite easily."

``Now imagine we had a different amount of water.  We can simply change the value of the \lstinline{g_water} variable."

\begin{pyin}
g_water = 4.3121
\end{pyin}
``We could just type out the whole expression again, but we can actually do something much faster, as we will see next!"

\subsection{Accessing a history of code you have executed in the console}
\label{Accessing_a_history_of_code_you_have_executed_in_the_console}

``So far, we have just been typing out everything we want to write. But the \cite{console} keeps a record of what we have already typed, so that if we want to repeat a previous command---or modify a small part of a previous command--- we can save some time by accessing this record.''

``If you are ready to type a command into the console, you can instead press the up arrow key on your keyboard. The cursor will then move through commands you already entered, from the most recent to the farthest back---moving up through the IDLE display.  If you move the cursor to the line that reads "\lstinline{g_water / MW_water * N_A} and press enter, this will place those commands on the input line, and if you press enter again, it will repeat the calculation.  However, between the first time we entered these commands, and now, we have changed the value of the \lstinline{g_water} \cite{variable}. This time, the expression will use the new value for \lstinline{g_water}, and will give you the following result:''

\begin{pyout}
1.4414134112819785e+23
\end{pyout}

``A variable can only have a single value at a time.  If we reassign the value of a variable, we can only access the current value.''

``Okay,'' \First says, ``We are not \textit{quite} in a place to completely solve your original problem, but we are in a place to start making progress.  For instance, we can create variables to store your stock concentrations so that you don't have to remember them, like this:"
\begin{pyin}
conc_stock_cat = 0.1 # M
conc_stock_HCl = 6.0 # M
conc_stock_NaCl = 3.0 # M
\end{pyin}
``We can also store the final volume in a different variable:"
\begin{pyin}
vol_final = 1.0 # mL
\end{pyin}
``Now you never have to think about that again!  Next, we need to figure out the math that we need to do and translate that to code.  We can calculate how much we will need using the $M_1V_1 = M_2V_2$ approach:"
\begin{align*}
V_2 = \frac{M_1V_1}{M_2}
\end{align*}
``If you were to do this on a calculator and you wanted the answer in mL, you would compute:"
\begin{align*}
    V_{\textrm{stock catalyst}} = \frac{\textrm{0.01 mol catalyst}}{\text{1 L}}\left(\textrm{0.001 L final volume}\right)\frac{\textrm{1 L stock solution}}{\textrm{0.1 mole catalyst}}\left(\frac{\textrm{1000 mL}}{\textrm{1 L}}\right)
\end{align*}
``We can translate this equation into Python code by replacing the math variables with Python variables.  Let's say you want the final catalyst concentration to be 0.01 M, the final HCl concentration to be 0.006 M, and the ionic strength to be 0.02 M.  Let's go ahead and make those variables too."
\begin{pyin}
conc_cat = 0.01 # M
\end{pyin}
\begin{pyin}
conc_HCl_final = 0.006 # M
\end{pyin}
\begin{pyin}
I = 0.02 # M
\end{pyin}
``You could get the volume of stock catalyst solution needed by:"
\begin{pyin}
conc_cat * vol_final / conc_stock_cat # mL
\end{pyin}
\begin{pyout}
0.09999999999999999
\end{pyout}
``If you are paying close attention, you will notice that the code we typed in does not exactly map onto the solution we outlined above. In particular, we are missing the part where we multiply by 0.001 L fo final volume and then the final conversion between L and mL.  The reason for this is that these two steps cancel out, so as long as we leave them \textit{both} out we will still get the correct final answer. This also means that we had three calculations that we did not ask Python to perform, and this speeds up the calculation. Of course, here, the difference would not be noticeable.  But if you were going to repeat simple calculations a billion times or more (as you will find yourself doing surprisingly often), you might start to notice the difference. So, simplifying the number of steps can be good, as long as you can justify it.'' 


``Since the calculation is so similar for HCl, we'll just use the up arrow to select the previous line, press Enter, and then edit the line to replace \lstinline{con_cat} and \lstinline{conc_stock_cat} with \lstinline{conc_HCl_final} and \lstinline{conc_stock_HCl}, respectively:"
\begin{pyin}
conc_HCl_final * vol_final / conc_stock_HCl # mL
\end{pyin}
\begin{pyout}
0.001
\end{pyout}
``Ionic strength is only a little more complicated.  You calculated the ionic strength as"
\begin{align*}
I = \frac{1}{2}\left([H^+] + [Cl^-] + [Na^+] + [Cl^-]\right)
\end{align*}
``so you can get the volume of NaCl stock solution needed by"
\begin{align*}
V_{NaCl}^{\text{stock}} = \frac{(I-[HCl])*V_{\text{sol'n}}}{[NaCl]_{\text{stock}}}
\end{align*}
``So we just type"
\begin{pyin}
(I - conc_HCl_final) * vol_final / conc_stock_NaCl # mL
\end{pyin}
``The last question is how much water you need to make up the total volume.  We need to calculate"
\begin{align*}
V_{\text{water}} = V_{\text{sol'n}} - V_{\text{cat}} - V_{\text{HCl}} - V_{\text{NaCl}}
\end{align*}
``This would be easy if we stored all of the results we already got as variables, otherwise we have to either write them down or recalculate them.  We can go back and type"
\begin{pyin}
vol_cat = conc_cat_final * vol_final / conc_stock_cat # mL
\end{pyin}
\begin{pyin}
vol_HCl = conc_HCl_final * vol_final / conc_stock_HCl # mL
\end{pyin}
``which then allows us to do this:"
\begin{pyin}
vol_NaCl = (I - conc_HCl_final) * vol_final / conc_stock_NaCl # mL
\end{pyin}
\begin{pyin}
vol_water = vol_final - vol_cat - vol_HCl - vol_NaCl # mL
\end{pyin}
\begin{pyin}
vol_water
\end{pyin}
\begin{pyout}
0.8943333333333333
\end{pyout}
``This is convenient, it would still be nice to be able to output numbers in context, with units attached to them, so let's talk about using text in Python."

%
% Handling text
%
\subsection{Expressing data as readable text using strings}
\label{Expressing_data_as_readable_text_using_strings}

``Even though Python doesn't know the units associated with the numbers, \textit{we} do. So we can add them to the answer if we like. When we want to give Python text (like letters, words, and numerals) instead of code and numbers, we place the text between apostrophes (\lstinline{'}), quotation marks (\lstinline{"}), triple apostrophes (\lstinline{'''}), or triple sets of quotation marks \lstinline{"""}). This lets Python know that we are dealing with text, rather than numbers or code. From Python's perspective, numbers and text are different kinds of data, or different \cite{data_type}s. The technical term for textual data is a \cite{string}. We can create these strings and assign them to \cite{variable}s:"

\begin{pyin}
greeting = `Hello there.'
\end{pyin}
\begin{pyin}
greeting
\end{pyin}
\begin{pyout}
`Hello there.'
\end{pyout}

``Here you can see that Python indicates that the value output is a string by placing it between apostrophes. Of course, you might not want to see the apostrophes when Python writes out the string, and this can be done by using the \lstinline{print()} \cite{function}. This function takes 1 or more arguments and outputs the value of the \cite{argument} to the standard output, which is in this case the output in our \cite{console} window (the thing we have been seeing as the output). 
%For now, you can think of a \textbf{function} as a bit like a variable that holds a set of instructions rather than values.  Because it only contains instructions, it does not know about any of the specific variables that you have defined or the data stored in them. When you \ul{call} these instructions by using the name of the function, you need to provide it with the data that you want it to operate on by including the data you want to perform these operations on between parentheses. We call the data between the parentheses the \textbf{arguments} of the \textbf{function}.  \lstinline{print()} contains instructions to output the value of the \ul{argument} to the standard output, which is in this case the output in our \ul{console} window. 

\begin{pyin}
print(greeting)
\end{pyin}
\begin{pyout}
Hello there.
\end{pyout}

You can see the difference is that Python has output the value assigned to the variable \lstinline{greeting} (Hello there.), without an indication of the type of data this is (\textit{i.e.}, there are no bracketing apostrophes). 

``Of course, we can also provide data types besides strings as arguments to the \lstinline{print()} function. For instance, we could use one of the variables that has numbers associated with it."

\begin{pyin}
print(MW_water)
\end{pyin}

\begin{pyout}
18.01528
\end{pyout}

``Another thing that is useful about \lstinline{print()} is that it can accept multiple arguments, as long as we separate them by commas.  It will then display each one sequentially, separated by a space."

% if we want f-strings
%One super convenient feature of strings is that you can tell a string to evaluate \underline{expressions}, and then include the result. This is done using \textbf{f-strings}--- called this because you prefix the start of the string with the letter `f.'  Then you indicate the variable you want to use between two curly brackets `{}'. For instance, imagine you wanted to report the number of water molecules we had, but with units, you could do the following:

\begin{pyin}
water_molecules = g_water / MW_water * N_A
\end{pyin}

\begin{pyin}
print(water_molecules, 'molecules of water.')
\end{pyin}

\begin{pyout}
1.4414134112819785e+e23 molecules of water.
\end{pyout}

``Suppose we wanted this output to be on two different lines.  If we type them separately, then this happens"
\begin{pyin}
print('Molecules of water:')
\end{pyin}
\begin{pyout}
Molecules of water:
\end{pyout}
\begin{pyin}
print(water_molecules)
\end{pyin}
\begin{pyout}
1.4414134112819785e+e23
\end{pyout}
``But the outputs are now broken by a line of input, which isn't great. Luckily, we can make one print statement that prints multiple lines of text:"
\begin{pyin}
print('Molecules of water:\n', water_molecules)
\end{pyin}
\begin{multiout}
Molecules of water:
1.4414134112819785e+e23
\end{multiout}

``Here, We used \lstinline{\n} in our string, and this really gets to the heart of how computers see text.\footnote{If you want to read more about how text works in detail, see Technical Chapter \ref{Text}.  The information is not needed for this chapter, but we point it out in case you are interested. } The computer has no concept of paragraphs. Even though it is automatic for us to end a paragraph and start a new line, we have to \textit{tell} the computer where to do this.  We do this by using a symbol to indicate this.  The symbol is the \cite{newline_character} and, in Python, it is \lstinline{\n}.  So, we are using this character to make the output more readable.  There are many other such characters that specify formatting, with the other one you will likely need being tab: \lstinline{\t}.''


``So you can see that we get the output we wanted. The next time we meet, we will talk about how to format this even more. For today, let's end by looking at everything we have done so far and talk about how to tie it all up so it is easy to use."

% %f-strings
% \subsection{Using f-strings to insert dynamic data into strings}
% \label{Sec:N:00aExpDes:f-strings}

% \First glances at her watch and says, "Ok, I have time to teach you one more thing: a better way to include data in strings, which will help you when you are annotating your plots."

% It is going to be convenient to tell people the results of our fit using strings. But since we also have uncertainty in our fit we would like to include that. Ideally, would be nice to write a sentence like "<center value> +/- <uncertainty>". In our program, <center> and <uncertainty> will be held in variables. We do have a way to print this, using a construction like \lstinline{print(<center value>, " +/- ", <uncertainty>)}, but there are two problems with this solution.  First, it is a bit cumbersome to write and read.  Second, this doesn't actually produce a string, so this construction provides no way to pass the sentence we want to any other function, like Plotly's \lstinline{add_annotation()}. 

% "There are several ways to solve the problem of getting a string object with values from variables, but I think the best option are using \textbf{f-strings}.  These are strings, but we place an \lstinline{f} prior to the first set of quotation marks. We can use this to produce a 'normal' string:"

% \begin{pyin}
%  f"Hi"
% \end{pyin}
% \begin{pyout}
% 'Hi'
% \end{pyout}
% But we can also place variable names between curly brackets (\{\}) and the variables will be evaluated. 
% \begin{pyin}
% pi = 3.14159
% \end{pyin}
% \begin{pyin}
% f"A nice approximation of pi is {pi}."
% \end{pyin}
% \begin{pyout}
% 'A nice approximation of pi is 3.14159.'
% \end{pyout}
% Actually, \textbf{f-strings} do more than this, since really what is happening is that any Python statement we place between the curly brackets is evaluated and the value included in the string. 
% \begin{pyin}
% f"10 / 3 is {10/3}."
% \end{pyin}
% \begin{pyout}
% '10 / 3 is 3.3333333333333335.'
% \end{pyout}
% As you can imagine, \textbf{f-strings }can be a very powerful way to place values inside of strings. 



% % formatting numbers
% \subsection{Formatting numbers in strings}
% \label{Sec:N:00aExpDes:FormatNumbersInStrings}

% If we are going to be placing numeric values inside of strings, then it is going to quickly become important to understand how to format these values.  For instance, imagine you had 10 g of a chemical you wanted to equally divide up between 7 vials. You could use f-strings to provide a nice statement.

% \begin{pyin}
% f"Place {10/7} grams in each vial."
% \end{pyin}
% \begin{pyout}
% 'Place 1.4285714285714286 grams in each vial.'
% \end{pyout}
% Which is not a great output, because it is hard to read, you likely do not have a balance that reads with attogram precision, and even if you did, there is no need for such precision. Instead, weighing to 1 mg might be sufficient, so we only need to report this to 3 decimal places. We can format the string, by placing a colon (:) after the value and then formatting instructions before the end of the curly brackets. 

% \begin{pyin}
% f"Place {10/7:.3f} grams in each vial."
% \end{pyin}
% \begin{pyout}
% 'Place 1.429 grams in each vial.'
% \end{pyout}
% Where the number has even been rounded. 

% In this usage, the 0.3 means that you want 3 decimal places, and the 'f' indicates that this should be formatted as a standard float. There are other options where we can ask for scientific notation, engineering notation, etc.  More information can be found in the technical Chapter \ref{Text}. 

% Now, we can create a nice looking output for your results!  You type,
% \begin{pyin}
% print(f'{vol_cat:5.3f} mL cat, {vol_HCl:5.3f} mL HCl, {vol_NaCl:5.3f} mL NaCl, {vol_water:5.3f} mL water.')
% \end{pyin}
% and get the satisfying result
% \begin{pyout}
% 0.100 mL cat, 0.001 mL HCl, 0.005 mL NaCl, 0.894 mL water
% \end{pyout}
% This is basically the solution that you want, so you say, ``Now, all I have to do is change the concentrations that I want and I can just rerun the lines of code to calculate the volumes without really typing any more code."  \first says, ``You could, but it would be annoying to keep having to run the lines of code over and over.  It turns out that you can group them all into one single line of code to make this even faster!"

\subsection{Avoiding repetitive typing by making your own functions}
\label{Avoiding_repetitive_typing_by_making_your_own_functions}

``You have already used a couple of \cite{function}s that are built in to Python: \lstinline{print()} and \lstinline{round()}. These functions allow you to easily accomplish common tasks.  Essentially, you can think of them as taking a series of instructions that accomplish this task and bundling them together, so that you only need to write out the name of the function, rather than all the instructions. This is certainly very convenient! And wouldn't it be nice if you  had a function that did this for the amounts of stock solution you need to add for your experiment?''

``Well, you are in luck! While Python may not automatically include such a function, you can make your own functions that do basically anything that you can code up! To do so, you simply take code you write and then define a function to use it.  Then, you can just \cite{call} the function, and the code you wrote is hidden away inside of it so that only Python has to deal with it.  Functions have four basic parts:"\footnote{A more complete discussion of how functions work can be found in the technical chapter on functions (Chapter \ref{ch:functions}.} 
\begin{itemize}
    \item A name---function names need to follow the same conventions as variable names.\footnote{See Section \ref{Sec:T:Computers:Storing_Data_in_Memory}.}
    \item Zero or more \cite{parameter}s that define the data that the function will use.  These hold that values that are passed as arguments.
    \item The code in the function---this needs to be indented to make it clear that the code belongs to the function instead of the rest of the code.  Indentation is one type of \cite{white_space}, used to tell Python how code should be executed.  For any function, all of the contiguous lines of code after a function definition that have the same indentation are interpreted to be part of the code inside the function.  The first line of code where there is no longer indentation is  outside of the function and is the signal to the \cite{Python_interpreter} that the code is no longer part of the function.  As you will see later, there are reasons why you will need to use additional indents to specify more complex code inside of functions, but this is enough for now.
    \item The value(s) that the function will \cite{return} when executed. Sometimes there are no values returned, and this is fine.  Remember when we used \lstinline{round()}?  The rounded value was the value that was returned from that function when it was evaluated.  
\end{itemize}
``When Python evaluates the line of code with the function call, it will evaluate the code in the function and then replace the function call with the returned value."

``Using the IDLE (as we have so far), you \textit{could} choose to create a function by typing the function into the \cite{console}, line-by-line.  However, a \textit{much} simpler way is to create a file that contains the code we want to use and then read the code from this file. If you click File-->New File in IDLE, you will get a new window to define your function."

\First types into the IDLE text editor:
\lstinputlisting{../../Distribution/Code by Chapter/Ch00 - Simplifying Repetitive Calculations/calcPlateVols.py}
and saves the file as calcPlateVols.py.

``Let's talk through this code line by line."
\begin{footnotesize}
\begin{itemize}
    \item [1--3:] We use \cite{comment}s to let people know what this code does and how to use it. The first comment explains what the code does.  The next two give the assumptions the code makes. 

    \item [4:] This line in blank. Though not required, using blank lines can increase the readability of the code. We often use them to indicate separation of tasks. 
    
    \item [5:] The definition of the \cite{function} starts with the \lstinline{def} \cite{keyword}, which tells Python that what follows is the name of the function and that the lines that follow will have the instructions that comprise the working of the function. The name of the function is the name that you will need to type in Python when you want to use the function, like ``print" for the \lstinline{print()} function or ``round" for the \lstinline{round()} function.  After that, you have parentheses, and everything between the parentheses is a \cite{parameter}... the names of the \cite{variable}s inside the function that \cite{argument}s will be \cite{pass}ed to when the function is \cite{call}ed.  This is like how you provided values to the \lstinline{round()} function.  In the case of this function, you can type \lstinline{calcPlateVols(.01, .006, .02)} and in the function, there will be three variables: 
    \lstinline{conc_cat} (holding the value 0.01),
    \lstinline{conc_HCl} (holding the value 0.006), and 
    \lstinline{conc_NaCl} (holding the value 0.02).  We will set the final volume of the wells, \lstinline{vol_final}, to be a \cite{keyword_argument}.  This allows us to set a default value for the volume (in this case 1mL), but also allow the user to easily change the value when the function is called. 

    \item [7:] Another comment to tell us what this part of the function does.

    \item  [8--10:] Here we are defining variables to hold the concentrations of our stock solutions, just like we did when using the interpreter. This type of usage is known as \cite{hard_coding}, because we cannot change the values without changing the code. A more general usage would be to add these as keyword parameters in the function definition, with these default values assigned. However, since this was a quick tool for a specific situation, and you commonly use these stock concentrations, they are hard-coded. 

    \item [12:] Another comment to tell us what this part of the function does. It is good practice to leave comments that help a user understand the steps you are trying to accomplish.

    \item [13--15:] Now we can compute the volumes of stock solutions needed the same way as we did earlier in this chapter.

    \item [17:] Another comment, because we are now moving on to a new step in our solution.

    \item [18:] We're calculating the volume of water needed.

    \item [20--23:] This is a series of print statements to output the resulting arrays in human-readable form.  Each one prints two lines, one that has a checkbox and a description of the solution to be added, and a second that prints the volume that needs to be added. Even though the print statement is on a single line, it will output two lines, because we are using the newline character, \lstinline{\n}.
\end{itemize}
\end{footnotesize}

``Now, when you run this code by clicking Run-->Run Module, Python will step through this code line by line and run each line in the interpreter.  When it is finished, Python will now know that there is a new function and how it should behave.  So, we can use it like any other function:"
\begin{pyin}
calcPlateVols(.01, .006, .02)
\end{pyin}
\begin{multiout}
[ ] catalyst solution (mL)
 0.09999999999999999
[ ] HCl (mL)
 0.001
[ ] NaCl (mL)
 0.004666666666666667
[ ] water (mL)
 0.8943333333333333
\end{multiout}

\begin{wrapfigure}{r}{0.5\textwidth}
    \begin{mdframed}
\textbf{The Python Kernel}\\
Each session of Python involves the `kernel.'
The Python Kernel is the core execution environment that runs Python code in interactive computing environments like the IDLE. The kernel is what keeps track of variable names, variable values, defined functions, and so on. If you close IDLE, this closes the kernel. The reason to mention this is that, if you close IDLE, and then open it and immediately try to run \lstinline{calcPlateVols()} you will get an \cite{error} message:\\
\lstinline{NameError: name 'calcPlateVols' is not defined}\\
which indicates that Python does not know what this function is.  You must first run the code that defines the function, before you can use it. 
\end{mdframed}
\end{wrapfigure}

``Now, you just have to press the up key and enter to copy the last line into the input, change whichever concentration you want to, press enter again to run it, and get a new calculation! You can use this to calculate the value for all the wells in your experiment.''



``In my experience'' \first says, ``this is \textit{already} better than using a calculator or Excel, but if we learn one more concept, we can make these calculations even easier.  Like, we can apply this function to every well of your 24 well plate.  And if we plan it out correctly, we could use the same approach for a 96 well plate, or a plate of any size!"

\First glances at her watch and says, ``But I have to get back to the lab to finish up an experiment, we can pick this up tomorrow at lunch!''

Given the amount you have learned in only this hour, you can hardly wait.

\hrule
\input{Exercises/Chapter 00 Simplifying Repetitive Calculations}
\hrule

\end{document}
