\documentclass{article}
\newsavebox{\oldepsilon}
\savebox{\oldepsilon}{\ensuremath{\epsilon}}
\usepackage[minionint,mathlf,textlf]{MinionPro} % To gussy up a bit
\renewcommand*{\epsilon}{\usebox{\oldepsilon}}
\usepackage[margin=1in]{geometry}
\usepackage{graphicx} % For .eps inclusion
%\usepackage{indentfirst} % Controls indentation
\usepackage[compact]{titlesec} % For regulating spacing before section titles
\usepackage{adjustbox} % For vertically-aligned side-by-side minipages
\usepackage{array, amsmath,  mhchem}
\usepackage{hyper ref}
\usepackage{courier, subcaption}
\usepackage{multirow, color}
\usepackage[autolinebreaks,framed,numbered]{mcode}

\usepackage{float}
\restylefloat{table}

\pagenumbering{gobble}
\setlength\parindent{0 cm}
\renewcommand{\arraystretch}{1.2}
\begin{document}
\large

\section*{Positive feedback}

All systems that exhibit bistability implement positive feedback. In the mutual repression example, this positive feedback is indirect: protein X increases its own production rate by alleviating repression from Y. The result is that $X$ causes its own \textit{derepression} -- a form of positive feedback.\\

It's possible to make a bistable switch from a single transcription factor by utilizing positive feedback. Suppose X is a transcriptional activator with a maximum expression rate $\alpha$ and degradation rate $\beta$. As previously, the general expression for the rate of change in $x$ is:

\[ \frac{dx}{dt} = \alpha h(x) - \beta x \]

where $0<h(x)<1$. We'll assume that $x$ binds its own promoter and that production of $x$ scales with the likelihood that $x$ is bound there, which in turn is determined by a Hill curve:

\[ h(x) = \frac{x^n}{K + x^n} \rightarrow  \frac{x^n}{1 + x^n} \textrm{  on appropriate choice of units for [X]} \]

Then the equation for our system is:

\[ \frac{dx}{dt} = \frac{\alpha x^n}{1 + x^n} - \beta x \]

The fixed points of this system satisfy:

\[ x = \frac{\alpha x^{n}/\beta }{1 + x^{n}} \]

By plotting both the left-hand and right-hand side on one axis, we can see that when $n=1$ and the right-hand side is hyperbolic, then there are two intersections, one at the origin and another at a positive value of x. Only the right-most fixed point is stable.\\

If the right-hand side has a sigmoidal shape (i.e. $n>1$), then it is possible to have one, two, or three points of intersection. Notice that as we increase $\alpha/\beta$ from a low value, where we have only one intersection at the origin, a new fixed point appears ``out of the clear blue sky" at a positive value of $x$. This point is half-stable and quickly gives way to two fixed points, one of which is stable and the other unstable. This is called a \textit{saddle-node} (or sometimes, ``blue sky") bifurcation.

\begin{figure}[htp] \centering{
\includegraphics[width=1 \textwidth]{pfb1.pdf}}
\caption{Illustration of the emergence of a new fixed point as $\alpha/\beta$ increases. Hill coefficient $n=2$.} \label{fig:pfb}
\end{figure}

At this point it may be tempting to conclude that we are done analyzing this system, but as $\alpha/\beta$ continues to increase, the middle fixed point slides arbitrarily close to the origin so that (assuming any noise is present) the origin becomes functionally unstable. (Bifurcation diagram.) Systems of this type exhibit hysteresis (review this term).

\section*{The lac operon}

Bistable switches like this one were among the first identified in real biological systems. Bacterial cells use it to switch between two gene expression states based on the food sources available. \textit{E. coli}, for example, are capable of using lactose (a sugar in milk) as a carbon source. To do this, they must invest energy in making transporters that carry lactose (LacY) into the cell as well as enzymes (LacZ) that break lactose into its component simple sugars, glucose and galactose. LacZ and LacY proteins are not useful the vast majority of the time, since lactose is not bacteria's preferred carbon source. However, when lactose is present, the cell must be able to turn on these genes. How does the cell achieve this?\\

In bacteria, genes of related function are often transcribed together on the same mRNA (i.e. in an \textit{operon}). This means that their expression is regulated by the same promoter. \textit{lacZ} and \textit{lacY} are part of the \textit{lac} operon, which is regulated by a transcriptional repressor called LacI. LacI is bound to the \textit{lac} operon's promoter most of the time, so that these genes are not expressed. (You may recall that LacI was the first example we used when discussing how transcription factors can bind cooperatively when there are multiple nearby sites.) However, when lactose is present inside the cell, it can bind to LacI and cause this repressor to fall of the \textit{lac} promoter, allowing LacZ and LacY to be expressed. The lac operon system uses a repressor: does it display positive feedback, and if so, can we shoehorn it into our model?\\

The positive feedback in this system is the result of the lactose transporter, LacY. Suppose a bacterial cell has been growing for a long time in medium without lactose, so that very little LacZ or LacY are being expressed. We add a little lactose to the medium: what happens? With no LacY present, the lactose is impeded from entering the cell. We must add a high enough concentration of lactose that it is able to ``seep in" before LacI is inhibited and LacZ/Y get expressed. Now LacY will let more lactose into the cell, so more and more LacY will be expressed. Similarly, if we start at a high concentration of lactose and decrease, the \textit{lac} operon will tend to maintain its expression until [lactose] is very low. (Draw the hysteresis and compare to the positive feedback above.)\\

This is all well and good, but is the Hill equation an appropriate production term for [LacY], i.e.

\[ \frac{d\left[ \textrm{LacY}\right]}{dt} = \alpha h \left( \left[ \textrm{LacY} \right] \right) - \beta \left[ \textrm{LacY} \right]  \stackrel{?}{=} \frac{\alpha \left[ \textrm{LacY}\right]^n}{1 + \left[ \textrm{LacY}\right]^n} - \beta \left[ \textrm{LacY}\right]\]

The easiest way to understand this is to interpret the production term for LacY as a function of the concentration of active repressor, which in turn depends on how much lactose is being admitted by the cell (i.e. [LacY] and [lactose]).\\

We'll assume, as we did on Friday, that the production function $h$ has domain $[0,1]$. It will be one when none of the repressor is active and zero when all of the repressor is bound, hence:

\[ h \left( \left[ \textrm{LacY} \right] \right) = 1 - P\left( \textrm{LacI is bound }\right) =  \frac{K_i}{K_i + \left[\textrm{LacI}_{\textrm{active}} \right]} \]

Technically we would be well within our rights to assume that this binding of LacI to its operator is cooperative. We know that LacI is a tetramer and that it has multiple binding sites in/near the \textit{lac} operon's promoter. (Recall that we used it in the ball-and-cup analogy earlier in the course.) However we will see that this cooperativity in LacI binding is not essential for bistability in the lactose response. \\

What fraction of LacI is active? LacI is a tetramer that becomes inactivated when lactose\footnote{Technically it is not lactose that inhibits the repressor, but rather one of its metabolic derivatives, allolactose.} binds allosterically to any one of its subunits. For an appropriate choice of lactose concentration units,

\begin{eqnarray*}
 \frac{\left[\textrm{LacI}_{\textrm{active}} \right]}{\left[\textrm{LacI}_{\textrm{total}} \right]} & = & P\left( \textrm{lactose not bound to any subunit} \right)\\
 & = & \left[ P\left( \textrm{lactose not bound to one subunit} \right) \right]^4\\
  & = & \left( \frac{K_r}{K_r + \left[ \textrm{lactose}_{\textrm{int}} \right]} \right)^4
  \end{eqnarray*}

The subscript indicates the \textit{internal} concentration of lactose. To understand what the internal concentration of lactose will be, we consider how fast lactose is entering the cell and how fast it is being consumed:

\begin{eqnarray*}
 \frac{d \left[ \textrm{lactose}_{\textrm{int}} \right]}{dt} & = & \frac{k_{\textrm{cat}} \left[ \textrm{LacY} \right]  \left[ \textrm{lactose}_{\textrm{ext}} \right]}{K_m +  \left[ \textrm{lactose}_{\textrm{ext}} \right]} - \beta_s  \left[ \textrm{lactose}_{\textrm{int}} \right]\\
 & \approx & \frac{k_{\textrm{cat}}}{K_m} \left[ \textrm{LacY} \right]  \left[ \textrm{lactose}_{\textrm{ext}} \right] - \beta_s  \left[ \textrm{lactose}_{\textrm{int}} \right]
 \end{eqnarray*}

 Here we have used an approximation that $\left[ \textrm{lactose}_{\textrm{ext}} \right] \ll K_m$, i.e., LacY is operating in its first-order regime. If we assume that the internal concentration of lactose is at quasi-steady-state, then we have [lactose$_{\textrm{int}}$] as a function of [LacY] and [lactose$_{\textrm{ext}}$]:

 \begin{eqnarray*}
 \left[ \textrm{lactose}_{\textrm{int}} \right] & = & \frac{k_{\textrm{cat}}}{\beta_s K_m} \left[ \textrm{LacY} \right]  \left[ \textrm{lactose}_{\textrm{ext}} \right]\\
 \left[\textrm{LacI}_{\textrm{active}} \right] & = & \left[\textrm{LacI}_{\textrm{total}} \right] \left( \frac{K_r}{K_r + \left[ \textrm{lactose}_{\textrm{int}} \right]} \right)^4\\
& = &  \left[\textrm{LacI}_{\textrm{total}} \right] \left( \frac{K_r}{K_r + \frac{k_{\textrm{cat}}}{\beta_s K_m} \left[ \textrm{LacY} \right]  \left[ \textrm{lactose}_{\textrm{ext}}  \right]} \right)^4\\
h \left( \left[ \textrm{LacY} \right] \right) & = & \frac{K_i}{K_i + \left[\textrm{LacI}_{\textrm{active}} \right]}\\
& = & \frac{K_i}{K_i + \left[\textrm{LacI}_{\textrm{total}} \right] \left( \frac{K_r}{K_r + \frac{k_{\textrm{cat}}}{\beta_s K_m} \left[ \textrm{LacY} \right]  \left[ \textrm{lactose}_{\textrm{ext}}  \right]} \right)^4}\\
& = & \frac{K_i \left( K_r + \frac{k_{\textrm{cat}}}{\beta_s K_m} \left[ \textrm{LacY} \right]  \left[ \textrm{lactose}_{\textrm{ext}}  \right] \right)^4}{K_i \left( K_r + \frac{k_{\textrm{cat}}}{\beta_s K_m} \left[ \textrm{LacY} \right]  \left[ \textrm{lactose}_{\textrm{ext}}  \right] \right)^4 + \left[\textrm{LacI}_{\textrm{total}} \right] K_r^4  }
 \end{eqnarray*}

This is not a Hill function of [LacY]; however, it does have sigmoidal character. Notice that the production level of LacY is never precisely zero, even when there is no external lactose:

\[ \left[ \textrm{lactose}_{\textrm{ext}}  \right] \to 0: \hspace{2 cm} h\left(  \left[\textrm{LacY}\right] \right) \to  \frac{K_i}{K_i + \left[\textrm{LacI}_{\textrm{total}} \right]} \]

It turns out to make a big difference that the intercept is positive. Recall that at any fixed point $ \left[\textrm{LacY}\right]_{s-s}$,

\[  y_1 \equiv \left[ \textrm{LacY} \right]_{ss} = \frac{\alpha}{\beta} h \left( \left[\textrm{LacY}\right]_{ss} \right) \equiv y_2 \]

so that the fixed points occur at intersections of $y_1$ and $y_2$. As we increase [lactose$_{\textrm{ex}}$] from zero, we go from a single intersection (at a low LacY concentration) to two, to three, back to two, and finally to a single steady-state (at a high LacY concentration).  (Draw sample intersections and finally the bifurcation curve.) Unlike when the production term was a Hill function, it is now possible to truly, not just functionally, lose the lower stable state. (Discussion of hysteresis in this system.)\\

Although this is a canonical result in molecular biology (dating to Novick and Weiner's 1957 paper), the system is still under theoretical consideration (see Ozbudak 2004, Santill\'{a}n 2007).\\

\section*{Collins Toggle Switch}

\begin{itemize}

\item Want to build a mutual repression system with a means for switching between the two states.

\item Knew that they needed $n>1$ and $\alpha/\beta$ greater than a threshold value in order to get bistability.

\item ``What I cannot build, I do not understand.'' -- Feynman; unclear whether these simplifications of gene regulation would apply generally.

\item At the time of publication (Gardner 2000), the number of well-characterized repressors, promoters, and RBSes was limited. Needed to try multiple options.

\item The repressors and the promoters that contain their binding sites are:
\begin{itemize}
\item LacI binds to P$_{\textrm{trc2}}$
\item The lambda phage repressor cI (``see-one") binds to P$_{Ls1con}$
\end{itemize}

\item New genetic constructs are often designed and introduced into hosts on plasmids: small (3-10kb) circular pieces of double-stranded DNA.

\item Elements of a bacterial plasmid:

\begin{itemize}
\item Origin of replication (tricks host into amplifying the plasmid as if it were its own genome)
\item Often no explicit means of segregation between daughter cells (relying on high copy number)
\item A marker for selection (e.g. encoding antibiotic resistance, so that only bacteria that maintain a copy of the plasmid can survive in media containing the antiobitic)
\item For each gene, a transcriptional promoter, ribosome binding site (not required in eukaryotes), the gene's open reading frame (i.e. the codons that should actually be translated into amino acids), a stop codon, and a transcriptional terminator.
\item Optionally in bacteria: multiple RBSes and ORFs per transcriptional promoter/terminator (because operons can encode multiple proteins). A similar approach using ``internal ribosome entry sites" sort-of works in eukaryotes where IRESes are well-defined.
\item Ribosomes have a greater affinity for some RBSes than others. One straightforward way to change the production rate of a protein is to swap out the RBS.
\item It is also possible to change a protein's effective expression level by using a temperature-sensitive variant. Essentially these are proteins that contain mutations which place them on the cusp of not folding properly. When the temperature increases above a threshold, they unfold cease to function. (This is true for all proteins, but temperature-sensitive variants undergo this transition at a temperature where most of the organism is still functional.)
\end{itemize}

\item Can add IPTG (isopropyl-$\beta$-D-1-thiogalactopyranoside, an allolactose analog) to make LacI stop binding. Raising the temperature inactivates cI.

\item Difference in off rates explained by mechanism (temperaure-induced instability of cI vs. slow dilution of LacI following IPTG addition)

\end{itemize}
\end{document}

lectures/Lecture 11 - Genetic Switches, Natural and Engineered/lecture 11 notes.tex


%!TEX root = thesis.tex

\chapter{Evaluation}
\label{ch:Evaluation}
The implementation of the I-POMDP framework was evaluated by training a policy for the \emph{``Where's Waldo?''} game described in Chapter \ref{ch:IPOMDP} and comparing the performance of the resulting policy to the performance of a greedy policy, a random policy, and a policy that always focuses on the center of the image.

The policies were trained on a $7 \times 7$ grid where the grid represents the image and each grid location represents a state and an action, i.e. a location where Waldo can be found in and a location the agent can fixate on. The number of actions available to the agent are therefore equal to the number of states, namely $49$.

Both observation models mentioned in Section \ref{sec:ObservationModelImpl} were used to train policies and the default values presented in Section \ref{sec:PolicyTraining} were used in both cases.

\section{Training a Policy Using the Exponential Model}
\label{sec:PolicyExp}
The policy parameters for the policy learned when training with the exponential model for observations can be seen in Figure \ref{fig:ExpPolicyTheta}. This policy favors fixating on locations where the agent's belief is strong, since the values on the diagonal of the policy parameter matrix\footnote{See Section \ref{sec:LogisticPolicies} for an explanation of the policy parameter matrix} are relatively large. An agent using this policy would therefore with a high probability fixate on locations where it beliefs the target is located -- in other words, act greedy.

On both sides of the diagonal we again notice large parameter values, but not as large as on the diagonal itself. This can be interpreted as the second best choice of fixation. Fixating on locations close to the location where the belief is highest will therefore occur with a high probability. This policy could therefore be interpreted as a greedy policy with a slight tendency for curiosity.

\begin{figure}[!htp]
  \centering
  \includegraphics[width=1\textwidth]{figures/exp_policy_theta}
  \caption{The $49 \times 49$ policy parameter matrix $\theta$ trained using the exponential model for observations. \textbf{Left:} Relatively large values on the diagonal, slightly lower values on both sides of the diagonal. \textbf{Right:} The heat map shows clearly the two off-diagonal lines and the relatively large diagonal values.}
  \label{fig:ExpPolicyTheta}
\end{figure}
\FloatBarrier

\noindent
The learning curve for the policy can be seen in Figure \ref{fig:AverageRewardsExp}. It shows that the policy improves fast the first 200 training iterations, as the average rewards in each training iteration get higher and higher (less negative). The policy improvement continues slowly until after around 800 iterations where the learning converges.

\begin{figure}[!htp]
  \centering
  \includegraphics[width=0.5\textwidth]{figures/average_rewards_exp_2x}
  \caption{Average rewards per training iteration while training a policy using the exponential model for observations.}
  \label{fig:AverageRewardsExp}
\end{figure}

\section{Training a Policy Using the Human Eye Model}
The policy parameters for the policy learned when training with the human eye model for observations are very different from the parameters learned in Section \ref{sec:PolicyExp}. Instead of relatively large values on the diagonal, this policy's parameter matrix has less variance in the parameter values but a clear horizontal band of higher values across the middle of it. See Figure \ref{fig:EyePolicyTheta}.

\begin{figure}[!htp]
  \centering
  \includegraphics[width=1\textwidth]{figures/eye_policy_theta}
  \caption{The $49 \times 49$ policy parameter matrix $\theta$ trained using the human eye model for observations. \textbf{Left:} Relatively large values across the middle part of the parameter matrix and low values near the top and bottom. \textbf{Right:} Difference between the smallest and largest values not as evident as for the exponential model. Larger values across the center of the matrix.}
  \label{fig:EyePolicyTheta}
\end{figure}
\FloatBarrier

\noindent
To interpret this policy's parameter matrix we first note that on a $7 \times 7$ grid, location number $25$ would be in the center of the grid. With that in mind we can assume that this policy favors fixating on locations around the center of the image.

\begin{figure}[!htp]
  \centering
  \includegraphics[width=0.5\textwidth]{figures/average_rewards_eye_2x}
  \caption{Average rewards per training iteration while training a policy using the human eye model for observations.}
  \label{fig:AverageRewardsEye}
\end{figure}

\noindent
The learning curve for the policy can be seen in Figure \ref{fig:AverageRewardsEye}. The first thing we notice is that the average rewards per training iteration are higher than during training of the policy in \ref{sec:PolicyExp}. This comes from the fact that the human eye model for observations has a wider field of view than the exponential model, which only sees a small part of the image very clearly.

The policy improves steadily for around 1600 iterations and after that the learning converges.

\section{Performance Comparison}
The performance of both learned policies was compared to the performance of a greedy policy, a random policy, and a policy that always focuses on the center of the image. The comparison was performed by simulating the search for ``Waldo'' with each policy $4,900$ times and recording each time how many fixations it took before the agent's highest belief matched the true location of ``Waldo''.

\subsection{Policy Using an Exponential Model}
All the policies perform similarly for the first 5 fixations, with the trained policy performing slightly better than the others, but after 6 fixations the random policy performs best. The exponential model for observations has a very narrow view and therefore does not fully exploit the potential of the I-POMDP algorithm. For each fixation the agent can only obtain reliable information about the image from the exact location it is fixating on, while the information in the surrounding locations is very noisy. This can make the agent's belief unreliable. As mentioned in Section \ref{sec:PolicyExp} this policy is very similar to the greedy policy and using a greedy policy when the belief is unreliable will result in poor performance. The trained policy is however a stochastic policy and therefore performs better than the greedy policy. The random policy benefits from the fact that it is not dependent on the noisy belief. It should also be noted that a policy that does not fixate on every location will eventually perform worse than random.

The comparison of the policies using the exponential model for observations can be seen in Figure \ref{fig:PolicyComparisonExp}.

\begin{figure}[!htp]
  \centering
  \includegraphics[width=0.5\textwidth]{figures/policy_comparison_exp2}
  \caption{Performance comparison of policies using the exponential model for observations.}
  \label{fig:PolicyComparisonExp}
\end{figure}

\subsection{Policy Using a Human Eye Model}
The human eye model for observations has a wider view than the exponential model and therefore the agent can not only obtain reliable information about the image from the location it fixates on, but also the locations surrounding it. This gives the trained policy an advantage because it exploits the potential of the I-POMDP algorithm. For this reason the trained policy outperforms the other policies as can be seen in Figure \ref{fig:PolicyComparisonEye}.

\begin{figure}[!htp]
  \centering
  \includegraphics[width=0.5\textwidth]{figures/policy_comparison_eye2}
  \caption{Performance comparison of policies using the human eye model for observations.}
  \label{fig:PolicyComparisonEye}
\end{figure}

\noindent
The greedy policy proves to be a poor strategy in this case as well.


\chapter{Python Data Structures}
Data structures are absolutely mandatory to using any programming language effectively. So far, all of our programs have been operating in a very linear matter: our program starts at the top, and it ends at the bottom. Now, we're going to examine some ways that Python can run that aren't linear. In the beginning, it will almost certainly feel useless. Why would we jump around when we can just write the code in the main body of the program? However, trust us, it'll come in handy down the road, and when applied correctly, both classes and functions can save a lot of time when writing complex programs.\par
\section{Functions}
Functions can seem somewhat useless. After all, if we wanted to run the same code, we could just copy and paste it! However, this isn't terribly efficient, and there's something to be said about code cleanliness that makes it easier to read. Functions can keep you from writing the same code over and over again. Think back to loops. Sure, we \textit{could} just copy and paste a certain chunk of code to be run 100 times, but that's a lot of code for something that can be done with literally just one extra line of code. Functions can save you a lot of time when programming by allowing you to essentially reference another chunk of code with a single line of code.\par
The easiest way to think of functions in programming is as functions in algebra. When you first learned about mathematical functions, you were probably told that something goes in and something (probably different) comes out. For example, let's look at the function $y = 2x$. This is pretty simple: the input value $x$ is multiplied by 2, and the output is $y$. If you put in the value 0, then you'll get 0 out, but if you put in anything else, it will be different. The input 4 will yield the output 8. The input 6 will yield the input 12. The input $a$ will yield the output $2a$.\par
Let's consider a more complex function: $y = 2x + 3z - 9$. In this function, we have two coefficients (2 and 3, next to the $x$ and $z$, respectively), a constant (9), and an output ($y$). If we give the values 5 for $x$ and 42 for $z$, we get an output of 125 ($125 = 2 \times 5 + 3 \times 42 - 9$). We could also set a preemptive value for $x$ or $y$, if the user doesn't tell us what $x$ or $z$ should be, like 0. So if we gave only the value 5 for $x$, then we can assume that $z$ should be 0, so we would get an output of 1 ($1 = 2 \times 5 + 3 \times 0 - 9$).\par
Programming functions aren't that dissimilar in principle, but their inner functionality is a little bit more complicated than Algebra I functions. In programming, a function can, but doesn't always have to, take something in. Similarly, a programming function can, but doesn't always, have an output. Unlike math functions, functions in Python do need to have their own unique names.\par
\subsection{Function Definition}
Now that we know what functions are, how can we create them?\par
At their most simple, functions consist of four things: the function name, the arguments, the operations, and the return. Remember in chapter 4.1 how we talked about arguments? Now, we're actually going to use functions and those argument things! In programming, your \newterm[arguments]{function!arguments} are the function's inputs. You can pass in as many arguments as you'll need to construct your function and do what you need. Some functions take in one argument, while others might take in up to 10 or 15 arguments. Going back to our math function, this would be having multiple variables opposite your output. For example, consider the quadratic equation, which takes in three variables.\par
$$
x = \frac{-b \pm \sqrt{b^{2} - 4 \times a \times c}}{2 \times a}
$$
In Python, $a$, $b$, and $c$ would be referred to as parameters. You should make a mental note that parentheses \verb|()| are almost always associated with arguments of a function.\par
There is a difference between arguments and \newterm[parameters]{function!parameters}. Parameters are put into a function's definition, while an argument is the actual value passed in during a function call. So, if we defined $a$, $b$, and $c$ to be our parameters, then the real values 4, 8, and 3 would be the arguments for the parameters. Essentially, you define \textit{parameters} in a function \textit{definition} and \textit{arguments} in a function \textit{call}.\par
Similarly, the $x$ in the quadratic equation above would be the output. In programming, the output of a function is called the \newterm[return value]{functions!return}. It's important that you don't confuse your \textit{return} with the \verb|print()| function. In the past, when we've referred to "output," it's typically meant that we were printing something to the console. However, now we're using "output" to mean something different. It's possible to return a value from a function without printing it.\par
In Python, we need to give each of our functions a name. Giving our functions a name allows us to refer to the functions later. In programming, we typically name our functions using alphabetical characters only, in camel-case. It is unusual to see a function named using symbols, such as dashes or underscores. Like variables, it's important that your functions are named something concise yet descriptive. Use your experience in naming variables to create good function names!\par
The contents of a function can manipulate any of the variables passed in as arguments. Inside of the function, any of the variables that you listed as arguments have already been declared and initialized, so you can just start using them!\par
Let's look at a function definition. In this function, we're going to calculate $x$ from the quadratic formula, as shown above.\par
\begin{lstlisting}[style=pippython]
def quadraticFormula(pol, a, b, c):
  negB = b * -1
  top = 0
  if (pol == "plus"):
    top = negB + sqrt(b**2 - 4 * a * c)
  elif (pol == "minus"):
    top = negB - sqrt(b**2 - 4 * a * c)
  bottom = 2 * a
  x = top / bottom
  return x
\end{lstlisting}
Notice how the first thing in this function is \verb|def|. This lets Python know that we'd like to define a new function. The \verb|def| is short for \textit{definition}, and writing it lets Python know that the next thing is the function's name, followed by the parameters. Our function \verb|quadraticFormula| takes four parameters: the polarity of the top plus/minus (\verb|pol|), $a$ (\verb|a|), $b$ (\verb|b|), and $c$ (\verb|c|). Inside of the function, we're creating a new variable that can't be accessed outside of the function \verb|negB|, which is the negative value of the parameter \verb|b|. Next, our function calculates the top and the bottom of the function. The top uses the polarity parameter to determine whether we should add or subtract the square root. Finally, we divide the top by the bottom and return that value. This function doesn't print anything on its own. Instead, its result needs to be printed by the function call, which we'll get to in the next section.\par
This is also the perfect opportunity to examine how we can use functions inside of other functions. Take a look at the lines that compute \verb|top|. Inside, we see that most of the line is just simple arithmetic, but there's also another function call: \verb|sqrt()|. \verb|sqrt()| is a function in Python that calculates the square root, and we're able to use this function inside of our own function. In Python, we can actually use any function inside of our own functions, including other functions that we've made ourselves. It's even possible to call your own function in a technique called recursion, although this is a technique out of the scope of this book.\par
You can also see in the above code that we're returning \verb|x|, which is a float or an integer. However, we don't need to just return a number; we can return any type of data that we want to, including strings, Boolean values, or compound datatypes, like lists and dictionaries. Let's look at a slightly simpler function that takes in a list as an argument and returns a simple Boolean variable. This function will test whether the list is longer or shorter than 10 elements. If it's longer than 10 elements, it will return \verb|True|, otherwise it will return \verb|False|.
\begin{lstlisting}[style=pippython]
def isLongerThan10(listToTest):
  if (len(listToTest) > 10):
    return True
  else:
    return False
\end{lstlisting}
In the previous example, we can see that our function name is \verb|isLongerThan10| and that it takes one argument \verb|listToTest|. Inside of the function, we see that we're using the variable \verb|listToTest| that came as one of our arguments. We don't need to declare or initialize this variable, as it is an argument to the function that already has a value. Within our function, we're running an \verb|if| statement to determine whether we should return \verb|True| or \verb|False|.\par
When we return a variable from a function, we need to put the return value into a variable in our function call. We'll see how to do this when we learn about function calls in the next section.\par
Functions that return something are called \newterm[returning functions]{functions!return}. It is also possible to create a function that doesn't return anything. Functions that don't return anything are called \newterm[void functions]{functions!void}. When writing a void function, you don't need to specify any return value. The function can still take arguments, but it doesn't have any output. For example, say you wanted to write a function that printed out an ASCII cow.\footnote{Reminder: Watch out for backslashes - you need to escape backslashes by adding another backslash to print just one. Why? Think about what \textbackslash n does.}\par
\begin{lstlisting}
          (__)
          (oo)
   /-------\/
  / |     ||
 *  ||----||
    ^^    ^^
\end{lstlisting}
We could write each print statement out, line-by-line, every time you wanted to print out a cow. This would take some time, though, if we wanted to be able to print out a cow whenever we wanted to. Instead, we could write a void function that prints a cow, but that doesn't return anything. Again, remember that the \verb|print()| function and the return value from a function are two different things.\par
\begin{lstlisting}[style=pippython]
def cow():
  print("          (__)")
  print("          (oo)")
  print("   /-------\\/")
  print("  / |     ||")
  print(" *  ||----||")
  print("    ^^    ^^")
\end{lstlisting}
In the above example, there's not a single \verb|return| statement like we've seen in the previous examples that return floats, integers, or Boolean values. Instead, calling this function will just run the code inside of the function, literally printing a cow to the console.\par
Void functions can also take arguments. Our previous example was named \verb|cow()|, and it only printed a cow, but we could create another function named \verb|animals()| that printed one of three animals, which would be passed in as an argument of type string.\par
\begin{lstlisting}[style=pippython]
def animals(animal):
    if (animal == "cow"):
        print ("          (__)")
        print ("          (oo)")
        print ("   /-------\\/")
        print ("  / |     ||")
        print (" *  ||----||")
        print ("    ^^    ^^")
    elif (animal == "pig"):
        print ("    n..n")
        print ("e___(oo)")
        print ("(____)")
        print ("//  \\\\")
    elif (animal == "fox"):
        print ("|\\_/|,,_____,~~`")
        print ("(.\".)~~     )`~))")
        print (" \\o/\\ /---~\\\\ ~))")
        print ("   _//    _// ~)")
    else:
        print ("Please use argument \"cow\", \"pig\" or \"fox\".")
\end{lstlisting}
As you can see, the \verb|animals()| function takes in one argument \verb|animal|. Again, this function has no return type; it's a void function, even though it takes in an argument.\par
\subsection{Function Calls}
Calling functions is even easier than making them. In fact, you've already called plenty of functions as you've been writing code! Whenever you use \verb|print()|, \verb|input()|, or anything else with parentheses, you're actually calling functions that are already built into Python!\par
You can also call your own functions, once you've written them. Our first example of a void function printed a cow. We can call this function, just like we called the \verb|input()| function without any arguments, since \verb|cow()| takes no arguments.\par
\begin{lstlisting}[style=pippython]
cow()
\end{lstlisting}
\begin{lstlisting}
          (__)
          (oo)
   /-------\/ - moo
  / |     ||
 *  ||----||
    ^^    ^^
\end{lstlisting}
Above, we also created a new function called \verb|animals()|, which takes in a parameter \verb|animal|, which can be either "cow", "pig", or "fox". To call this function, we can just write our function, along with the required argument. For example, for us to print a fox, we can call \verb|animals("fox")|.
\begin{lstlisting}[style=pippython]
animals("fox")
\end{lstlisting}
\begin{lstlisting}
                           |\_/|,,_____,~~`
                           (.".)~~     )`~))
ring-ding-ding-ding-ding  - \o/\ /---~\\ ~))
                              _//    _// ~)
\end{lstlisting}
In this function, we're not returning anything, so we don't need to put the contents of the function return value into a variable. But, what if we are returning something? In this case, we need to do something with the return value. We can either pass it into another function, such as \verb|print()|, or we can put its result into a variable for later use.\par
Consider the following function, which finds the y-value, given a slope, a x-intercept, and a x-value.\par
\begin{lstlisting}[style=pippython]
def linear(m, x, b):
  result = m * x + b
  return result
\end{lstlisting}
We can then call this function, passing in the three arguments specified and either printing them (using them in another function) or storing their result in a variable, since the function does return something.
\begin{lstlisting}[style=pippython]
print(linear(7, 4, 4))
print(linear(3, 6, 8))
result1 = linear(3, 9, 2)
result2 = linear(6, 2, 2)
\end{lstlisting}
\begin{lstlisting}
32
26
\end{lstlisting}
Observe how because the \verb|linear()| function returns something, we must do something with that returned value. However, with the \verb|cow()| or \verb|animals()| function, we cannot do anything except call the function, since it does not return any value. In fact, trying to print or put the result of a void function is syntactically incorrect.\par
\begin{lstlisting}[style=pippython]
# INCORRECT!
print(cow())
# CORRECT
cow()
# INCORRECT
linear(7, 4, 4)
# CORRECT
print(linear(7, 4, 4))
\end{lstlisting}
Some IDEs also have the ability to gather special bits of information from your function definition that can be useful in larger projects. This is typically done inside of a block comment just after the function definition. You should consult with your IDE's developer to learn how your IDE can help you with your function declarations.\par
In Anaconda Spyder, the comment format is as follows. You can have Spyder automatically generate the format of the block comment by typing your opening quotes directly after the function definition.\par
\begin{lstlisting}[style=pippython]
def calculateGrades(grade):
    """
    Calculates the grades of a student and returns the average.

    Parameters
    ----------
    grade : list of integers
        A list of exam scores to be averaged.

    Returns
    -------
    result : float
        The average score of all scores in the list.

    """
    result = sum(grade) / len(grade)
    return result
\end{lstlisting}
While this is a block comment and the Python interpreter won't use anything inside of it, it's easier for you to read. As a bonus, any time you click on a function call in your code and press Ctrl/Cmd + I, Anaconda will show you exactly what arguments you need to pass in its integrated help window! This feature and its specific functionality is specific to Spyder.\footnote{As of Spyder v.4.1.4}\par
Other IDEs might handle the block comment slightly differently. repl.it, a popular online IDE, doesn't prepopulate your block comment with anything, but it will show anything in your block comment if you hover over the function call, so this is a great place to put what this function does, what its parameters are, and what it returns. A simple template is provided for you here, if your IDE doesn't provide you with one.\par
\begin{lstlisting}[style=pippython]
"""
Description: Write a description here for what your function does.
Parameters:
  arg1: (int) Description of the parameter
  arg2: (string) Description of the parameter
Returns:
  returnVar: (float) Description of what the function returns
"""
\end{lstlisting}
If your IDE supports a specific template, it will auto-generate it once you create your block comment after your function definition. So, you can simply define a block comment as the first line of your function. If it is supported, it will be created for you. Otherwise, you can just paste in the template that works the best for you.\par
Like whitespace, it's a good idea to get into the habit of always writing a detailed block comment for each of your functions, including what the function does, what its parameter are, and what it returns. Regardless of what template you use, make sure that you're descriptive in your code.\par
\subsubsection*{Exercise Questions}
These exercise questions cover chapters 7.1.1 and 7.1.2.
\begin{Exercise}
	\Question{What is a function?}
	\Question{What is the difference between a definition and a call?}
	\Question{What are function parameters?}
	\Question{What are function arguments?}
	\Question{What is the difference between a function parameter and argument?}
\end{Exercise}
\begin{Exercise}
	\Question{Is there a keyword to define a function? If so, what is it?}
	\Question{Is there a keyword to call a function? If so, what is it?}
\end{Exercise}
\begin{Exercise}
	\Question{What is a function return?}
	\Question{What is the difference between a function return and a print?}
	\Question{Is it possible for a function to not return anything?}
	\Question{If a function does not return anything, what can we call it?}
\end{Exercise}
\begin{Exercise}
	\Question{In a new Python script, define a function called \texttt{bobross()} that has no parameters and prints the following string: \texttt{I thought today we would make a happy little stream that's just running through the woods here. Here we're limited by the time we have. You can bend rivers. But when I get home, the only thing I have power over is the garbage. Isn't that fantastic that you can create an almighty tree that fast?}}
	\Question{What is the function call for your function? (This isn't a trick question!)}
	\Question{Does your function return anything?}
\end{Exercise}
\begin{Exercise}
	\Question{In a new Python script, define a function called \texttt{got()} that has one parameter \texttt{language}.}
	\Question{If the user passes in the string \texttt{dothraki} as the argument, print \texttt{Shieraki gori ha yeraan!}.\footnote{Dothraki translates to \textit{The stars are charging for you!}.}}
	\Question{If the user passes in the string \texttt{valyrian} as the argument, print \texttt{Skoros morghot vestri?}.\footnote{Valyrian translates to \textit{What do we say to death?}.}}
	\Question{If the user passes in the string \texttt{english} as the argument, print \texttt{Winter is coming.}.}
	\Question{If the user passes in no string or anything other than \texttt{dothraki}, \texttt{valyrian}, or \texttt{english}, print a message that the user's argument is invalid.}
	\Question{Write four function calls: one for each of the languages and one with a nonexistent language.}
\end{Exercise}
\begin{Exercise}
	\Question{In a new Python script, define a function called \texttt{got()} that has one  parameter \texttt{language}.}
	\Question{If the user passes in the string \texttt{dothraki} as the argument, print either \texttt{Yer affesi anna} or \texttt{Me zisosh disse}.\footnote{The Dothraki quotes translate to \textit{You make me itch} and \textit{It's just a flesh wound}, respectively.}}
	\Question{If the user passes in the string \texttt{valyrian} as the argument, print either \texttt{Valar morghulis} or \texttt{Valar dohaeris}.\footnote{The Valyrian translates to \textit{All men must die} and \textit{All men must serve}.}}
	\Question{If the user passes in the string \texttt{english} as the argument, print either \texttt{Our fathers were evil men. All of us here. They left the world worse than they found it. We’re not going to do that. We’re going to leave the world better than we found it.} or \texttt{Give my regards to the Night’s Watch. I’m sure it will be thrilling. And if it’s not, it’s only for life.}.}
	\Question{If the user passes in no string or anything other than \texttt{dothraki}, \texttt{valyrian}, or \texttt{english}, print a message that the user's argument is invalid.}
	\Question{Write four function calls: one for each of the languages and one with a nonexistent language.}
\end{Exercise}
\subsection{Default Parameters}
For many functions, you will have an argument that is processed in that function. In some functions, though, you may want to have a default parameter so you don't have to type in every argument, every single time. Python supports default function parameters when we define our function, and this can be extremely useful for quickly calling commonly used functions.\par
You have already taken advantage of default function arguments when you have called functions in the past, like the \verb|print()| function. You already know how to use the \verb|print()| function: you put a string argument in it and it prints it to the console. But, what if we're concatenating and we want to change what the separator value is? We can \textit{choose} to specify the \verb|sep| argument. What if we want to change how the \verb|print()| function ends a line? We can \textit{choose} to specify the \verb|end| argument. \verb|sep| and \verb|end| have default values that will be used if these arguments are not specified when called. Because of these default arguments, the following two lines are equivalent.\par
\begin{lstlisting}[style=pippython]
print("Cats" + "and dogs", sep = " ", end = "\n")
print("Cats" + "and dogs")
\end{lstlisting}
This means that whenever we need to call the \verb|print()| function, we don't need to write out every single possible argument, only the ones that we want to \verb|change| from the default. When you're writing your own functions, you can also choose default values to be used if the function call doesn't specify the argument. We do this by initializing the variable in the function definition. That is, when we specify an argument when we specify the function's definition, we also initialize a default value for that argument to be used if the function call doesn't specify something else. Consider the following function, which calculates the percentage of faceoffs won, given the number of faceoffs won and the number of faceoffs lost (this could be used to help analyze hockey or lacrosse data).\par
\begin{lstlisting}[style=pippython]
def fopct(fowins, folosses):
	"""
	Calculates faceoff win percentage.

	Parameters
	----------
	fowins : int
		Number of faceoffs won.

	folosses : int
		Number of faceoffs lost.

	Returns
	-------
	float
		The faceoff percentage from 0 to 1.
	"""

	if (fowins + folosses) == 0:
		return 0.0
	else:
		return float(fowins / (fowins + folosses))
\end{lstlisting}
In this function, if we were to not specify either \verb|fowins| or \verb|folosses| when we called the function, the function would error out with a \verb|TypeError|:
\begin{lstlisting}[style=pippython]
print(fopct())
\end{lstlisting}
\begin{lstlisting}[style=none]
TypeError: fopct() missing 2 required positional arguments: 'fowins' and 'folosses'
\end{lstlisting}
Python was \textit{expecting} two arguments in our function call, and since it had no default value, it results in an error. Now, let's redefine this function, but let's initialize \verb|fowins| and \verb|folosses| to 0 in our definition line to assign a default value of 0 to each of these arguments.\par
\begin{lstlisting}[style=pippython]
def fopct(fowins = 0, folosses = 0):
	"""
	Calculates faceoff win percentage.

	Parameters
	----------
	fowins : int
		Number of faceoffs won.

	folosses : int
		Number of faceoffs lost.

	Returns
	-------
	float
		The faceoff percentage from 0 to 1.
	"""

	if (fowins + folosses) == 0:
		return 0.0
	else:
		return float(fowins / (fowins + folosses))
\end{lstlisting}
Now, if we were to not specify either \verb|fowins| or \verb|folosses| when we called the function, the function would use the default values of 0 and 0 for \verb|fowins| and \verb|folosses|, respectively.
\begin{lstlisting}[style=pippython]
print(fopct())
\end{lstlisting}
\begin{lstlisting}[style=none]
0.0
\end{lstlisting}
We don't necessarily need to specify every argument's default. Some arguments might be required, while others are optional with defaults. Consider the following void function.\par
\begin{lstlisting}[style=pippython]
def printfopct(fowins, folosses, player = ""):
	"""
	Prints faceoff win percentage.

	Parameters
	----------
	fowins : int, required
		Number of faceoffs won.

	folosses : int, required
		Number of faceoffs lost.

	player : str, optional
		Player's name as a string.

	Returns
	-------
	None
	"""

	if player == "":
		if (fowins + folosses) == 0:
			print("The player's faceoff percentage is 0.0")
		else:
			print("The player's faceoff percentage is " + str(float(fowins / (fowins + folosses))), sep = "")
	else:
		if (fowins + folosses) == 0:
			print(player + "'s faceoff percentage is 0.0", sep = "")
		else:
			print(player + "'s faceoff percentage is " + str(float(fowins / (fowins + folosses))), sep = "")
\end{lstlisting}
In the above function, if the \verb|player| argument is not specified, the function will use the default value of \verb|""| (an empty string). However, if it is specified, the function will use the value that is passed in.\par
Let's look at some examples of this function in action. First, let's consider if we don't pass in any of the required arguments.\par
\begin{lstlisting}[style=pippython]
printfopct()
\end{lstlisting}
\begin{lstlisting}[style=pippython]
TypeError: printfopct() missing 2 required positional arguments: 'fowins' and 'folosses'
\end{lstlisting}
We still get an error that we're missing required arguments. However, notice how even though we specified three possible arguments, Python is only erroring out on two arguments that are considered required because we never specified a default value in our function's definition. The \verb|player| argument was initialized to \verb|""|, since the argument was never specified.\par
Now, let's consider if we only pass in the required arguments.\par
\begin{lstlisting}[style=pippython]
printfopct(132, 71)
\end{lstlisting}
\begin{lstlisting}[style=none]
The player's faceoff percentage is 0.6502463054187192
\end{lstlisting}
Again, \verb|player| was initialized to \verb|""|, which was used for the remainder of the function, since we didn't specify a value for it in our function call. What if we specify a value for \verb|player|?\par
\begin{lstlisting}[style=pippython]
printfopct(132, 71, "TD Ierlan")
\end{lstlisting}
\begin{lstlisting}[style=none]
TD Ierlan's faceoff percentage is 0.6502463054187192
\end{lstlisting}
In this case, we specified that we don't want to use the default value of \verb|""| for \verb|player| and instead specified our own player name (\verb|"TD Ierlan"|).
\subsubsection*{Exercise Questions}
These exercise questions cover chapter 7.1.3.
\begin{Exercise}
	\Question{What is a default parameter?}
	\Question{How do we define a default parameter in a function definition?}
\end{Exercise}
\begin{Exercise}
	\Question{When calling a function with a default parameter, how do we choose to use the default parameter?}
	\Question{When calling a function with a default parameter, how do we choose to overwrite the default parameter and use our own argument?}
\end{Exercise}
\begin{Exercise}
	\Question{In a new Python script, define a function called \texttt{got()} that has one  parameter \texttt{language}. Set the default parameter for \texttt{language} to \texttt{valyrian}.}
	\Question{If the user passes in the string \texttt{dothraki} as the argument, print either \texttt{Yer affesi anna} or \texttt{Me zisosh disse}.\footnote{The Dothraki quotes translate to \textit{You make me itch} and \textit{It's just a flesh wound}, respectively.}}
	\Question{If the user passes in the string \texttt{valyrian} as the argument, print either \texttt{Valar morghulis} or \texttt{Valar dohaeris}.\footnote{The Valyrian translates to \textit{All men must die} and \textit{All men must serve}.}}
	\Question{If the user passes in the string \texttt{english} as the argument, print either \texttt{Our fathers were evil men. All of us here. They left the world worse than they found it. We’re not going to do that. We’re going to leave the world better than we found it.} or \texttt{Give my regards to the Night’s Watch. I’m sure it will be thrilling. And if it’s not, it’s only for life.}.}
	\Question{If the user passes in anything other than \texttt{dothraki}, \texttt{valyrian}, or \texttt{english}, print a message that the user's argument is invalid.}
	\Question{Write five function calls: one for each of the languages, one with no argument, and one with a nonexistent language.}
\end{Exercise}
\subsection{Positional and Keyword Arguments}
For the past few sections, all of our functions have only had a few arguments at the most. This is pretty easy to keep track of. But now, let's consider a function with lots and lots of arguments. We could have a function with dozens of arguments, some of which are required and others of which are not. This is where positional versus keyword arguments come into play.\par
As their names suggest, positional arguments use the position of the argument in the function call to determine what function parameter they should be representing. Again, consider the \verb|printfopct()| function from the previous section. The function's definition is given below for your convenience.\par
\begin{lstlisting}[style=pippython]
# DO NOT RUN
def printfopct(fowins, folosses, player = ""):
\end{lstlisting}
In this function, we know that the first argument to call is \verb|fowins|, then \verb|folosses|, then \verb|player|, and whenever we've called this before, we've always used this order. But, what if we wanted to change the order? Let's say we wanted to specify the player first? This is where we can use keyword arguments to specify exactly which value is which.\par
\begin{lstlisting}[style=pippython]
printfopct(player = "Max Adler", fowins = 81, folosses = 85)
\end{lstlisting}
\begin{lstlisting}[style=none]
Max Adler's faceoff percentage is 0.4879518072289157
\end{lstlisting}
The function call is still correct, even though we specified the arguments out of order. This is because we specified what value each of the arguments should be. This works for any function, regardless of whether the argument is required or not.\par
You can also mix positional and keyword arguments. You've already done this, actually! Whenever you've called the \verb|print()| function and passed in an optional argument, you've mixed positional and keyword arguments. The \verb|value| argument, which is required, is almost always passed in as a positional argument. We could write
\begin{lstlisting}[style=pippython]
print(value = "Hello, World")
\end{lstlisting}
, but, more often than not, we just write
\begin{lstlisting}[style=pippython]
print("Hello, World")
\end{lstlisting}
However, when we specify an argument like \verb|sep| or \verb|end|, we are specifying a keyword argument right next to a positional argument.\par
\begin{lstlisting}[style=pippython]
print("Hello, World", end = "\n")
\end{lstlisting}
\subsubsection*{Exercise Questions}
These exercise questions cover chapter 7.1.4.
\begin{Exercise}
	\Question{What is a positional argument?}
	\Question{What is a keyword argument?}
	\Question{What is the difference between positional and keyword arguments?}
	\Question{Can you mix positional and keyword arguments in one function call? Provide an example to prove your point.}
\end{Exercise}
\begin{Exercise}
	\Question{Write a function definition for a new function called \texttt{students()}. Leave the body of the function empty.}
	\Question{Edit your function definition to take three arguments: \texttt{print}, \texttt{classroom}, and \texttt{idnum}.}
	\Question{Set the default parameter for \texttt{print} to be \texttt{True}. Set the default parameter for \texttt{classroom} to \texttt{100}, and \texttt{idnum} to be \texttt{0}.}
	\Question{What would happen if you called \texttt{students()} with no arguments? Would there be errors? What behavior would you expect? What would be treated as a positional argument, and what would be treated as a keyword argument?}
	\Question{What would happen if you called \texttt{students()} with the following arguments (given to you as a tuple): \texttt{(True, 100, 3)}? What would be treated as a positional argument, and what would be treated as a keyword argument?}
	\Question{What would happen if you called \texttt{students()} with the following arguments (given to you as a tuple): \texttt{(idnum = 1, True, 101)}? What would be treated as a positional argument, and what would be treated as a keyword argument?}
	\Question{What would happen if you called \texttt{students()} with the following arguments (given to you as a tuple): \texttt{(idnum = 10)}? What would be treated as a positional argument, and what would be treated as a keyword argument?}
	\Question{What would happen if you called \texttt{students()} with the following arguments (given to you as a tuple): \texttt{(idnum = 103, classroom = 10, print = False)}? What would be treated as a positional argument, and what would be treated as a keyword argument?}
\end{Exercise}
\section{Classes}
\warningtext{Do you understand functions?}{If you haven't grasped the concept and application of functions yet, stop reading here. Make sure that you understand functions first, otherwise classes won't make any sense. Learning classes represents a significant jump in abstraction, so knowing how functions work is crucial to approaching classes.}Learning how to effectively use classes will prepare to practice a discipline of programming known as \newterm[object-oriented programming]{object-oriented programming} or \newterm[OOP]{object-oriented programming}. Object-oriented programming falls under the idea of programming composition, and it hinges on the idea that objects can contain other objects. That means that you could put a box inside of another box. Not only could you put a smaller box inside of a bigger box, you could put multiple smaller boxes inside of the larger box. The key behind object-oriented programming is that it allows us to store information together, rather than parsimoniously.\par
Consider how the leap from individual variables to complex datatypes, like dictionaries, enhanced our ability to communicate clearly while writing less code. Further object orientation helps the code's reader understand not only that the information is together, but that they are related. The goal is to help us represent simple information unambiguously and simply.\par
Let's consider how we could store a three-part date with year, month, and day. We could try to store this as a string, but there are lots of different ways to represent a date in a string.
\begin{lstlisting}[style=pippython]
"1980-01-02"
"1980/1/2"
"1/2/80"
\end{lstlisting}
To alleviate this, we could store it in three separate variables.
\begin{lstlisting}[style=pippython]
year = 1970
month = 1
day = 2
\end{lstlisting}
However, this requires us to use two more variables than just storing the information in a single string. We could even try to use a dictionary, but we run into the same representation issue.
\begin{lstlisting}[style=pippython]
date1 = {"year": 1980, "month": 1, "day": 2}
date2 = {"year": 1980, "month": "January", "day": 2}
\end{lstlisting}
Strictly speaking, both of these are correct, but only one would be valid unless we managed to code in every single option. This is where classes come in.
\subsection{Class Definitions and Calls}
Defining a class is the first step of using classes, and it looks shockingly similar to working with functions. Let's take a look at a function definition first. This function calculates a lacrosse faceoff specialist's faceoff win percentage, which is calculated as $n_\text{faceoff wins} / (n_\text{faceoff wins} + n_\text{faceoff losses})$ or $n_\text{faceoff wins}/n_\text{total faceoffs}$.\par
\begin{lstlisting}[style=pippython]
def fopct(fowins, folosses):
	"""
	Calculates faceoff win percentage.

	Parameters
	----------
	fowins : int
		Number of faceoffs won.

	folosses : int
		Number of faceoffs lost.

	Returns
	-------
	float
		The faceoff percentage from 0 to 1.
	"""

	if (fowins + folosses) == 0:
		return 0.0
	else:
		return float(fowins / (fowins + folosses))
\end{lstlisting}
Now, let's look at a class definition that has the above function definition.\par
\begin{lstlisting}[style=pippython]
class Player:
	"""
	A player on a lacrosse team.
	"""

	def fopct(self):
		"""
		Calculates faceoff win percentage.

		Returns
		-------
		float
			The faceoff percentage from 0 to 1.
		"""

		if (self.fowins + self.folosses) == 0:
			return 0.0
		else:
			return float(self.fowins / (self.fowins + self.folosses))
\end{lstlisting}
As you can see, the process of defining classes is remarkably similar to that of functions. We have a keyword (\verb|class|) followed by the name of the class (in this case, \verb|Player|). More importantly, though, we have actually created a new datatype: the \verb|Player| datatype. That's right: creating a class effectively creates a datatype that you can then use much more extensively. Let's say that we were tabulating lots of athlete information; the \verb|Player| datatype that we just created can help us arrange our data within our script much more tidily.\par
Consider the \verb|Player| class above. We can actually create a new object of type \verb|Player| by simply calling the object.\par
\begin{lstlisting}[style=pippython]
ratlisc01 = Player()
\end{lstlisting}
Now, we have an object called \verb|ratlisc01| that we can assign attributes to. \newterm[Attributes]{class!attribute} are characteristics of an object that store information about that object. You can think of an attribute as a variable inside of a variable. For example, the \verb|ratlisc01| object might have some attributes \verb|name|, \verb|gamesplayed|, and \verb|groundballs| that are specific to the player Scott Ratliff.
\begin{lstlisting}[style=pippython]
ratlisc01.name = 'Scott Ratliff'
ratlisc01.gamesplayed = 9
ratlisc01.groundballs = 19
\end{lstlisting}
Since we initialized the \verb|name| attribute for the \verb|ratlisc01| object, we can now call it as if it were a regular variable.
\begin{lstlisting}[style=pippython]
print(ratlisc01.name)
\end{lstlisting}
\begin{lstlisting}[style=pippython]
Scott Ratliff
\end{lstlisting}
The ability to put information inside of classes will allow you to abstract out your programming. By hiding the really gritty stuff and covering it with a tidy facade (essentially what classes allow you to do), you can write incredibly clean and efficient code. More importantly, if we're consistent with our attribute names, it will allow us to get the data for similar objects easily. If we know that we're always creating an attribute \verb|Player.name|, then we know that we can find the player's name in that attribute for an object of type \verb|Player|.
\subsubsection*{Exercise Questions}
These exercise questions cover chapter 7.2.1.
\begin{Exercise}
	\Question{What is a class?}
	\Question{When you create an object of a class, what type is the object?}
\end{Exercise}
\begin{Exercise}
	\Question{What is an attribute?}
	\Question{To call an attribute of an object, what symbol do you use?}
	\Question{What is the difference between a variable and an attribute?}
	\Question{What is the difference between a key and an attribute?}
\end{Exercise}
\begin{Exercise}
	\Question{What is the Python keyword to create a class?}
	\Question{When you create a class in Python, can the class take any parameters like a function can?}
	\Question{How can we determine what is inside of the class?}
\end{Exercise}
\subsection{Class Methods}
You might be thinking to yourself now, "how is this any different from a dictionary?" Well, we can get information on the objects that we create using the \newterm[methods]{class!method} that we write. A class method is a function that is specific to an object and that can access data within that object. For example, in the \verb|Players| class, we have a method called \verb|fopct| which calculates the faceoff win percentage based on faceoff wins and faceoff losses. Let's use that now. First, let's make a new object called \verb|nardejo01| that takes the \verb|Player| class.\par
\begin{lstlisting}[style=pippython]
nardejo01 = Player()
\end{lstlisting}
Now, let's give the object some attributes.\par
\begin{lstlisting}[style=pippython]
nardejo01.name = 'Joe Nardella'
nardejo01.gamesplayed = 9
nardejo01.groundballs = 66
nardejo01.fowins = 127
nardejo01.folosses = 94
\end{lstlisting}
If we wanted to get Joe Nardella's faceoff percentage, we already have his win and loss figures in the object with his information. They're in the \verb|fowins| and \verb|folosses| attributes inside of the \verb|nardejo01| object, so all we need to do is call the method on his object.
\begin{lstlisting}[style=pippython]
print(nardejo01.fopct())
\end{lstlisting}
\begin{lstlisting}[style=none]
0.5746606334841629
\end{lstlisting}
Notice how we didn't need to pass in the \verb|fowins| or \verb|folosses| attributes to the \verb|nardejo01| object. The class method pulls that information from the attribute that we assigned. But how did we tell the method that we wanted to be able to access attributes inside of that method? Take a careful look at the arguments that we passed the method definition.\par
\begin{lstlisting}[style=pippython]
# DO NOT RUN
class Player:
	def fopct(self):
\end{lstlisting}
Instead of giving the method individual arguments, we are instead giving the method access to the entire object and letting the method pick and choose attributes from that object. When we refer to a specific object inside of a method call, we use the \verb|self| keyword. That tells Python that we don't just want \textit{any} player. We specifically want \textit{Joe Nardella}'s faceoff data when we call \verb|fopct()| on the \verb|nardejo01| object. In this situation, \verb|self| is a reflection of the \verb|nardejo01| object within a class object call. More broadly, \verb|self| represents the specific object that the method is being called on.\par
So, if we make a new object for Conor Gaffney, we could call the same \verb|fopct()| on his object representation, and the \verb|fopct()| method would take \textit{his} faceoff attributes.
\begin{lstlisting}[style=pippython]
gaffnco01 = Player()
gaffnco01.name = "Conor Gaffney"
gaffnco01.fowins = 9
gaffnco01.folosses = 14
print(gaffnco01.fopct())
\end{lstlisting}
\begin{lstlisting}[style=none]
0.391304347826087
\end{lstlisting}
When we call \verb|fopct()| on the \verb|gaffnco01| object, \verb|self| is a reflection of \verb|gaffnco01|, and the returned value represents \verb|gaffnco01|'s faceoff percentage.
\subsubsection*{Exercise Questions}
These exercise questions cover chapter 7.2.2.
\begin{Exercise}
	\Question{What is a method?}
	\Question{Where are methods defined for a class?}
	\Question{What is the keyword to create a class method?}
	\Question{What happens if you try to call a class method on an object that the method is not a part of?}
\end{Exercise}
\begin{Exercise}
	\Question{What does \verb|self| do inside of a class method?}
\end{Exercise}
\begin{Exercise}
Consider the object \verb|celery| in the hypothetical \verb|Vegetable| class.
	\Question{What is the type of \verb|celery|?}
	\Question{The \verb|Vegetable| class has a method called \verb|weight()| that takes the weight of a vegetable and prints a string with the weight and the units. How would you call \verb|weight()| on \verb|celery|?}
	\Question{If you called the \verb|weight()| method on \verb|celery|, what keyword refers to the \verb|celery| object inside of the class?}
\end{Exercise}
\begin{Exercise}
	\Question{Define a new class \verb|House|.}
	\Question{Inside of the \verb|House| class, create a new method \verb|address()| that prints the \verb|street| attribute, the \verb|city| attribute, the \verb|state| attribute, and the \verb|zip| attribute, all concatenated together.}
	\Question{Outside of the \verb|House| class, create a new object of type \verb|House| and put the object into a new variable called \verb|whitehouse|.}
	\Question{Assign the \verb|whitehouse| object the following attributes:\\
	\verb|street|: \verb|1600 Pennsylvania Avenue NW|\\
	\verb|city|: \verb|Washington|\\
	\verb|state|: \verb|District of Columbia|\\
	\verb|zip|: \verb|20500|
	}
	\Question{Call the \verb|address()| method on \verb|whitehouse|. What is the output?}
\end{Exercise}
\begin{Exercise}
	\Question{Define a new class \verb|TVShow|.}
	\Question{Inside of the \verb|TVShow| class, create a new method \verb|avgrating()| that takes the \verb|ratings| attribute, which is list of ratings out of five stars and returns the average rating.\footnote{Note that this is a return, not a print.} As a reminder, the average is calculated by summing all of the elements and dividing the sum by the number of elements.}
	\Question{Outside of the \verb|TVShow| class, create a new object of type \verb|TVShow| and put the object into a new variable called \verb|atlanta|.}
	\Question{Create a new attribute for \verb|atlanta| called \verb|ratings| and put in five integers inside of a list into the \verb|ratings| attribute.}
	\Question{Create a new attribute for \verb|atlanta| called \verb|title| and put in \verb|Atlanta| as a string into the \verb|title| attribute.}
	\Question{Create a new object of type \verb|TVShow| and put the object into a new variable called \verb|squidgame|.}
	\Question{Create a new attribute for \verb|squidgame| called \verb|ratings| and put in five integers inside of a list into the \verb|ratings| attribute.}
	\Question{Create a new attribute of \verb|squidgame| called \verb|title| and put in \verb|Squid Game| as a string into the \verb|title| attribute.}
	\Question{Print the \verb|title| attribute from \verb|atlanta| along with its \verb|rating| attribute.}
	\Question{Print the \verb|title| attribute from \verb|squidgame| along with its \verb|rating| attribute.}
\end{Exercise}
\subsection{Class Initialization and Constructors}
Let's consider the \verb|Player| class introduced above. It is printed below for your convenience.
\begin{lstlisting}[style=pippython]
class Player:
	"""
	A player on a lacrosse team.
	"""

	def fopct(self):
		"""
		Calculates faceoff win percentage.

		Returns
		-------
		float
			The faceoff percentage from 0 to 1.
		"""

		if (self.fowins + self.folosses) == 0:
			return 0.0
		else:
			return float(self.fowins / (self.fowins + self.folosses))
\end{lstlisting}
We know that there are at least two attributes in the \verb|Player| class: \verb|Player.fowins| and \verb|Player.folosses|. We can see that we're using these attributes in the \verb|fopct()| method, and if we were to call \verb|fopct()| on an object of the \verb|Player| class that doesn't have these attributes, we'll get an error. For example, consider the \verb|ratlisc01| object that we defined above. Again, object initialization has been provided below for your convenience.\par
\begin{lstlisting}[style=pippython]
ratlisc01.name = 'Scott Ratliff'
ratlisc01.gamesplayed = 9
ratlisc01.groundballs = 19
\end{lstlisting}
Notice how this object doesn't actually have a \verb|fowins| or a \verb|folosses| attribute; we never initialized these attributes, so if we call the \verb|fopct()| method on it, we'll be calling the method on nonexistent attributes.
\begin{lstlisting}[style=pippython]
print(ratlisc01.fopct())
\end{lstlisting}
\begin{lstlisting}[style=none]
Traceback (most recent call last):

  File "ipykernel_12412/2288342692.py", line 1, in <module>
    ratlisc01.fopct()

  File "playerclass.py", line 1, in fopct

AttributeError: 'Player' object has no attribute 'fowins'
\end{lstlisting}
This is somewhat analogous to a \verb|NameError| where a name is not defined. You would get a \verb|NameError| if you tried to call a variable that didn't exist, for example. In this case, we get an \verb|AttributeError| because the \verb|Player| class doesn't have a default for the \verb|fowins| or \verb|folosses| attributes, meaning that these attributes essentially don't exist.\par
Python provides us a way to avoid this by something called class initialization. Class initialization allows us to "set up" an object with defaults every time a new object of that class is initialized. If we wrote a class initialization for our \verb|Player| class, we could set default values for \verb|fowins| and \verb|folosses| so that we would never get an \verb|AttributeError| because of a nonexistent attribute.\par
The process of making a class initialization is called making a constructor in many programming languages.\par
In Python, we create a constructor by using a special method name called \verb|__init__|. The two underscores before and after \verb|init| tell Python that this is a special method that should be run before class initialization is completed. Inside of our class initialization, we can set default values for attributes that we know we'll need, like \verb|fowins| and \verb|folosses|. We can always change these values later, but they need to exist in order to avoid \verb|AttributeError|s. A well-constructed \verb|__init__| method will have one key feature: it will allow us to set those values upon object initialization (when we call \verb|Player()| to make the \verb|Player| object) or set those values later. This is done by setting a default value in the method initialization, and this is called a default constructor. Consider the following initialization inside of the \verb|Player| class.\par
\begin{lstlisting}[style=pippython]
class Player:
	"""
	A player on a lacrosse team.
	"""

	def __init__(self, fowins = 0, folosses = 0):
		self.fowins = fowins
		self.folosses = folosses

	def fopct(self):
		"""
		Calculates faceoff win percentage.

		Returns
		-------
		float
			The faceoff percentage from 0 to 1.
		"""

		if (self.fowins + self.folosses) == 0:
			return 0.0
		else:
			return float(self.fowins / (self.fowins + self.folosses))
\end{lstlisting}
Notice how the parameters in the \verb|__init__| definition are \textit{different} from the class attributes. Sure, the attribute and the variable are named the same, but the \textit{attribute} is specific to the class, while the \textit{variable} is specific to the global class. So, in our initialization function, we actually need to assign the variables from the global class (\verb|fowins| and \verb|folosses|) to the object attributes (\verb|self.fowins| and \verb|self.folosses|).\par
\warningtext{What variable?}{It is important to not confuse your variables in your global class with your object attributes. Whenever you refer to an attribute inside of a class, you need to preface with \texttt{self} to indicate that you're using that particular instantiation. This is like referencing a attribute outside of a class. Just like the \texttt{ratlisc01.name} attribute is different from the variable \texttt{name}, \texttt{self.name} is different from the variable \texttt{name}.}
Now, our \verb|Player| class has a default constructor that will initialize the \verb|fowins| and \verb|folosses| to 0 if they are not set when the object is created. Let's consider the several ways to change these values by creating some more objects. First, let's create an object called \verb|witheja01|, which will be a \verb|Player| object for the player, Jake Withers. For this example, we will not pass any attributes into our class initialization.\par
\begin{lstlisting}[style=pippython]
witheja01 = Player()
print(witheja01.fopct())
\end{lstlisting}
\begin{lstlisting}[style=pippython]
0.0
\end{lstlisting}
When we ran line 1 to create the \verb|Player| object and put it into \verb|witheja01|, the class was created like before, but the \verb|__init__| method was also automatically run, which set the \verb|fowins| and \verb|folosses| attributes to 0. Because we already declared and initialized these attributes to a valid value, we can call the \verb|fopct()| method on the \verb|witheja01| object and get a valid output of 0.0.\par
Now, let's change the attributes in the \verb|witheja01| object.\par
\begin{lstlisting}[style=pippython]
witheja01.name = "Jake Withers"
witheja01.fowins = 117
witheja01.folosses = 98
\end{lstlisting}
Now, when we call the \verb|fopct()| function again, we'll be using the updated values.
\begin{lstlisting}[style=pippython]
print(witheja01.fopct())
\end{lstlisting}
\begin{lstlisting}[style=none]
0.5441860465116279
\end{lstlisting}
Now, let's bypass the default values and just initialize the values when we create the object. We'll create a new object \verb|adlerma01| and initialize the values for \verb|fowins| and \verb|folosses| directly in our object initialization.\par
\begin{lstlisting}[style=pippython]
adlerma01 = Player(fowins = 81, folosses = 87)
print(adlerma01.fopct())
\end{lstlisting}
\begin{lstlisting}[style=none]
0.48214285714285715
\end{lstlisting}
Because we initialized the values according to the names that we defined in our \verb|__init__| function, we can immediately start using these values.\par
We can also change these values just like we changed the values for \verb|witheja01| by reassigning the attribute value. For example, we got the \verb|folosses| attribute wrong - it should be 86, not 87. We can just reassign it, and while we're at it, let's also give \verb|adlerma| a \verb|name| attribute.\par
\begin{lstlisting}[style=pippython]
adlerma01.folosses = 86
adlerma01.name = "Max Adler"
\end{lstlisting}
Now, if we recalculate the faceoff percentage, it should be correct.\par
\begin{lstlisting}[style=pippython]
print(adlerma01.fopct())
\end{lstlisting}
\begin{lstlisting}[style=none]
0.48502994011976047
\end{lstlisting}
\subsubsection*{Exercise Questions}
These exercise questions cover chapter 7.2.3.
\begin{Exercise}
	\Question{What is a default constructor?}
	\Question{What is the Python keyword to create a default constructor?}
	\Question{What symbols surround the keyword that create a default constructor?}
\end{Exercise}
\begin{Exercise}
	\Question{Consider the variable \verb|size| and the attribute \verb|banana.size|. Is \verb|size| referring to the same thing in these two calls? Why or why not?}
	\Question{What type of error might we get if we try to call a nonexistent attribute of a class?}
	\Question{Suppose we create a default constructor for a class, but we don't set any default values for a class attribute that was defined in the constructor. Then, we try to create a new object without defining the attribute in our object creation. That is, we do something like this.
	\begin{lstlisting}[style=pippython]
class ClassName:
	def __init__(self, attribute1):
		self.attribute1 = attribute1
newObject = ClassName()
	\end{lstlisting}
	What happens? Why?}
\end{Exercise}
\begin{Exercise}
	\Question{Define a new class \verb|Food|.}
	\Question{Define a default constructor inside of the \verb|Food| class with the \verb|name| and \verb|calories| attributes. Do not set a default value for either \verb|name| or \verb|calories|.}
	\Question{Create a new object of type \verb|Food| with the \verb|name| attribute \verb|Carrot| and the \verb|calories| attribute \verb|65|, and put the object into a new variable called \verb|carrot|.}
	\Question{Create a new object of type \verb|Food| with the \verb|name| attribute \verb|Banana| and the \verb|calories| attribute \verb|100|, and put the object into a new variable called \verb|banana|.}
	\Question{Attempt to create a new object of type \verb|Food| with the \verb|name| attribute \verb|Soup|, but do not give a \verb|calories| attribute, and put this object into a new variable called \verb|soup|. Do you get an error message? If so, present the error message. If not, what is the value of \verb|calories|?}
\end{Exercise}
\begin{Exercise}
	\Question{Define a new class \verb|Farm|.}
	\Question{Define a default constructor inside of the \verb|Farm| class with the \verb|name| and the \verb|crop| attributes. Set the default crop to be \verb|corn|, but do not set a default for the name.}
	\Question{Without creating a new object, which attribute is required? Which attribute is not required?}
	\Question{Create a new object of type \verb|Farm| inside of the new variable \verb|sunset|. Set the name of the farm to be \verb|Sunset Farms| and set the crop to be \verb|strawberries|.}
	\Question{What is the value of \verb|sunset.name|? Where did this value come from?}
	\Question{What is the value of \verb|sunset.crop|? Where did this value come from?}
	\Question{Create a new object of type \verb|Farm| inside of the new variable \verb|myers|. Set the name of the farm to be \verb|Myers Family Farms|, but do not set the crop.}
	\Question{What is the value of \verb|myers.name|? Where did this value come from?}
	\Question{What is the value of \verb|myers.crop|? Where did this value come from?}
\end{Exercise}
\subsection{Nested Classes}
Python supports something really cool called nested classes. Consider where we have seen nesting before: in loops and conditional statements. For example, we might have the following nested if-then statement.\par
\begin{lstlisting}[style=pippython]
x = 5
if x == 0:
	print("x is zero")
else:
	if (x % 2 == 0):
		print("x is even")
	else:
		print("x is odd")
\end{lstlisting}
\begin{lstlisting}[style=none]
x is odd
\end{lstlisting}
This is a contrived example for the sake of demonstration, but the idea still holds: conditional logic statements in Python can be nested. The same concept holds for Python classes. For example, let's consider the \verb|Player| class from the previous section. It is printed below for your convenience.\par
\begin{lstlisting}[style=pippython]
class Player:
	"""
	A player on a lacrosse team.
	"""

	def fopct(self):
		"""
		Calculates faceoff win percentage.

		Returns
		-------
		float
			The faceoff percentage from 0 to 1.
		"""

		if (self.fowins + self.folosses) == 0:
			return 0.0
		else:
			return float(self.fowins / (self.fowins + self.folosses))
\end{lstlisting}
This class has one method in it that returns the faceoff win percentage. But, let's say we wanted to split the first and last name apart and have a method that put them together. We could just have two separate attributes for first and last name, but we could also make a nested class called \verb|Name| that has its own concatenation method that returns the full name. Consider the following script.
\begin{lstlisting}[style=pippython]
class Player:
	"""
	A player on a lacrosse team.
	"""

	class Name:
		"""
		A name of a person.
		"""
		def __init__(self, first = "", middle = "", last = ""):
			self.first = first
			self.middle = middle
			self.last = last

		def fullname(self):
			"""
			Returns the full name.
			"""
			return str(self.first + " " + self.middle + " " + self.last)

	def __init__(self, fowins = 0, folosses = 0):
			self.fowins = fowins
			self.folosses = folosses

	def fopct(self):
		"""
		Calculates faceoff win percentage.

		Returns
		-------
		float
			The faceoff percentage from 0 to 1.
		"""

		if (self.fowins + self.folosses) == 0:
			return 0.0
		else:
			return float(self.fowins / (self.fowins + self.folosses))
\end{lstlisting}
We still have our \verb|fopct()| method in our class, but we also now have a subclass called \verb|Name| with its own method \verb|fullname()|. Because \verb|fullname()| is nested inside of the \verb|Name| class, it would not be syntactically correct to call the \verb|fullname()| method on \verb|Player|, but we could call it on \verb|Name|. How would this look?\par
Let's consider how we've always seen classes before. When something is an attribute or a method of a class, it's been prefaced by its parent class and a period. This is a one-level nest, but we can have multi-level nests, too, like our updated \verb|Player| class now has. So, let's create a new \verb|Player| object that stores a name inside of the \verb|Player.Name| class.\par
\begin{lstlisting}[style=pippython]
simondr01 = Player()
simondr01.name = Player.Name()
simondr01.name.first = "Drew"
simondr01.name.last = "Simoneau"
simondr01.fowins = 31
simondr01.folosses = 43
\end{lstlisting}
Let's break this down. Line 1 should look very similar by now. We're simply making a new \verb|Player| object and assigning it to the \verb|simondr01| variable. Inside of the \verb|Player| class, there is a subclass called \verb|Name| that has three attributes: \verb|first|, \verb|middle|, and \verb|last|. The \verb|Name| class also has an default constructor that will initialize any empty attribute to an empty string. We have then placed the \verb|Name| object inside of the \verb|name| attribute inside of the \verb|simondr01| object. Then, we assigned the values \verb|"Drew"| and \verb|"Simoneau"| to the \verb|first| and \verb|last| attributes of our \verb|Name| object inside of our \verb|Player| object. Finally, we assign the \verb|fowins| and \verb|folosses| to the \verb|Player| object, just as before.\par
If we want to refer to something inside of the \verb|Player| class (which we'll call the parent class), we can just reference that attribute from the parent class. If we want to refer to something inside of the \verb|Name| class (which we'll call the child class), we can reference that attribute from the child class inside of the parent class.\par
We can call the \verb|fopct()| method, just like before.\par
\begin{lstlisting}[style=pippython]
print(simondr01.fopct())
\end{lstlisting}
\begin{lstlisting}[style=none]
0.4189189189189189
\end{lstlisting}
Now, however, we can call the \verb|fullname()| method on the \verb|Name| class inside of the \verb|Player| class.
\begin{lstlisting}[style=pippython]
print(simondr01.name.first)
print(simondr01.name.last)
print(simondr01.name.fullname())
\end{lstlisting}
\begin{lstlisting}[style=none]
Drew
Simoneau
Drew  Simoneau
\end{lstlisting}
In this chunk, we're calling the \verb|first| and \verb|last| attributes from the \verb|name| class, then we're calling the \verb|fullname()| method from the \verb|name| class. Take note of the two periods to get to the nested class. We have the period in between \verb|simondr01| and \verb|name|, which gets the parent object, and another period in between \verb|name| and \verb|first|, which gets the child object.
\subsubsection*{Exercise Questions}
These exercise questions cover chapter 7.2.4.
\begin{Exercise}
	\Question{What is a nested class?}
	\Question{Give two reasons why we might want to nest a class.}
\end{Exercise}
\begin{Exercise}
	\Question{Define a new class \verb|Car|.}
	\Question{Define a subclass inside of \verb|Car| called \verb|Engine|.}
	\Question{Under the \verb|Engine| class, define a default constructor with the \verb|fuel|, \verb|oil|, \verb|horsepower|, and \verb|liters| attributes. Under the larger \verb|Car| class, define a default constructor with the \verb|year| \verb|make|, \verb|model|, \verb|type|, \verb|occupants|, and \verb|weight| attributes.}
	\Question{Define the following default constructor attribute values.\\
	Inside of \verb|Engine|:\\
	\verb|fuel|: \verb|Regular|\\
	\verb|oil|: \verb|0W-40|\\
	\verb|horsepower|: \verb|0|\\
	\verb|liters|: \verb|0.0|\\
	Inside of \verb|Car|:\\
	\verb|type|: \verb|Sedan|\\
	\verb|occupants|: \verb|4|\\
	\verb|weight|: \verb|3300|\\
	For all other attributes, do not set a default.}
	\Question{Create a new \verb|Car| object and put the object into a new variable called \verb|civic|.}
	\Question{Change the attributes of the \verb|civic| object to the following.\\
	\verb|oil|: \verb|0W-20|\\
	\verb|horsepower|: \verb|158|\\
	\verb|liters|: \verb|1.5|\\
	\verb|year|: \verb|2022|\\
	\verb|make|: \verb|Honda|\\
	\verb|model|: \verb|Civic|\\
	\verb|weight|: \verb|2877|}
	\Question{Define a method inside of \verb|Car| that prints the year, make, and model.}
	\Question{Define a method inside of \verb|Engine| that prints the horsepower and capacity of the engine. Capacity is stored in the \verb|liters| attribute. Make sure to also print the units for horsepower (HP) and capacity (L).}
\end{Exercise}
\section{Functions Versus Methods}
Now that we know what a class method is, how exactly is it different from a regular old function? Sure, on the surface, they look the exact same and they even use the exact same definition syntax! The key to a method is that it is enclosed in a class and that it operates using class attributes as opposed to naive arguments. This means that for many of your class methods, you will never need to include anything other than \verb|self| as an argument, since you'll only ever be accessing class attributes inside of your method.
\section{Security Types (Optional)}
In other programming language classes, there is a concept known as security types. The security type of an object attribute is a measure of how accessible it is to the layer above it. In general, there are three security types: public, private, and undefined. Some languages don't have undefined security types, like C++ or C\#. Other languages do have undefined security types, like Java. The purpose of a private security type is to prevent a programmer from inadvertently modifying or accessing the attribute using naive code methods. \textbf{Private attributes are not inaccessible with the right methods}, only harder to get to. In languages with security types, the programmer typically writes a bridge between a private and a public attribute.\par
In C++, a common language that has public and private security types, the differentiation of whether a member attribute can be accessed from outside the class or not is the difference between public and private members. If a member attribute is accessible from outside of the class, the attribute is considered public, whereas if the member cannot be accessed or viewed from outside of that exact class, it is considered private. C++ adds a third security type as a subset of private member attributes called protected, which allows a member attribute to be accessed from inherited classes but not in a public scope.\par
\subsubsection*{Exercise Questions}
These exercise questions cover chapter 7.3.

No exercise questions exist for this section yet.
\section{Structures (Optional)}
There's a concept in other programming languages known as structures, or structs. Structs are another way of structuring data compared to classes, but unfortunately, Python doesn't natively support structs. However, we can still go over what a struct is so that should you choose to pick up a new programming language down the line, you can understand how that code works.\par
Let's say that you wanted to store a date. There's several ways that we could store this date. We could make an entire class called \verb|date|, but this seems kind of wasteful and somewhat backwards. It's a lot of code for something so simple. Likewise, we could store our year, month and date in individual variables, but this seems kind of messy and like it could cause readability issues. Instead, we can make a struct. A struct is like a combination of data that can be accessed as a single datatype, but without the overhead of a class.\par
In performance oriented languages, like C++, C\#, Swift, or Java, structs are better than classes, since they require less memory to store and the runtime doesn't need to use all of the features of a class. In our previous example, we could make a \verb|date| struct that had three elements: year, month, and day. We can then call the entire struct to get all of its data or get specific pieces of data out of this struct by using our period notation.\par
Python is not a performance oriented language. It has a lot of overhead, especially as an interpreter-driven language, so the performance advantages of a dedicated struct data structure don't really apply to it.\par