\chapter{Complex Datatypes}
It may seem strange that we aren't covering complex \index{datatype}datatypes right next to simple datatypes, but it's for a reason: knowing how to use simple datatypes and basic Python functionality is key to understanding and utilizing these complex datatypes.\par
Python has four complex datatypes that are available for you to use out-of-the-box: \index{datatype!list}lists, \index{datatype!dictionary}dictionaries, \index{datatype!tuple}tuples, and \index{datatype!set}sets. We will go over all four types, but we will spend most of our focus on lists and dictionaries.\par
It's also possible for us to make our own complex datatypes, and we'll do that when we cover classes in Chapter 7.
\section{Lists}
Let's imagine for a moment: you want to process the statistics for each rider on your favorite pro cycling teams. Sure, you could create variables for name, functional threshold power (FTP), peak power, and watts per kilogram for every rider. What might this look like?\footnote{Readers should note that this data is fabricated. Do not use these figures in your code.}\par
\begin{lstlisting}[style=pippython]
ath1name = "Peter Sagan"
ath1ftp = 470
ath1peak = 1230
ath1wpk = 6.7
ath2name = "Caleb Ewan"
ath2ftp = 471
ath2peak = 1903
ath2wpk = 7.0
\end{lstlisting}
Here we run into an inherent problem with individual variables: it gets really messy, really fast. It'd be really easy to spend all day making individual variables for every single rider. Well, there's a better way: lists. Lists are one of the \newterm[complex datatypes]{complex datatypes} in Python, and they allow us to store multiple pieces of individual data in a single data structure.\par
You can think of a list as a sequence of individual pieces of data. Instead of storing our data as individual variables, we can store all of the names in one list, all of the FTP data in a different list, all of the peak power figures in a third list, and all of the watts per kilogram measurements in a fourth list. Let's look at how to create these lists and get the data out of them.\par
\subsection{Creating Lists}
Creating lists isn't a particularly difficult task, and the same general structure applies as when declaring and initializing a variable. Let's use the same data as above, but expand on it a little bit. For these examples, we'll use five athletes. If we were to write each of these as individual variables, we'd have 20 variables, but instead, we can store all of the data we need in just four variable.\par
Lists are stored in variables, just like individual values. We even use the same assignment operator \verb|=|. The only thing that's different is the form of the data that we're putting into our variable. In Python, we create lists using square brackets \verb|[]| to denote the start and end of the list and commas \verb|,| to delimit each of the elements in the list. Consider the following code.\footnote{Again, all of the data has been fabricated.}\par
\begin{lstlisting}[style=pippython]
names = ["Peter Sagan",
    "Caleb Ewan",
    "Mathieu Van Der Poel",
    "Chris Froome",
    "Mark Cavendish"]
ftps = [470, 471, 460, 480, 465]
peaks = [1230, 1903, 1653, 1403, 1109]
wpks = [6.7, 7.0, 6.7, 6.3, 6.2]
\end{lstlisting}
As you can see, we're adding elements to our lists just as we would assign individual values to a variable. We use the same syntax to indicate a string (double quotes) or float (decimal points).\par
\warningtext{Common pitfall: comma placement}{When writing out a list of strings, it is surprisingly easy to accidentally put your commas inside of your strings instead of outside, as the former is common in English writing. If you do put a comma inside of a string, there is nothing to delimit the two strings, so Python won't be able to store the string and your program will likely crash.}
If your code isn't working, you might want to double-check that you've placed your commas correctly. The following code has just one misplaced comma that will prevent the code from running properly.\par
\begin{lstlisting}[style=pippython]
names = ["Peter Sagan,"
    "Caleb Ewan",
    "Mathieu Van Der Poel",
    "Chris Froome",
    "Mark Cavendish"]
\end{lstlisting}
It's also possible to mix the datatypes that go in your lists. For example, we could also structure our data by creating one variable for each athlete, as shown here.
\begin{lstlisting}[style=pippython]
saganData = ["Peter Sagan", 470, 1230, 6.7]
ewanData = ["Caleb Ewan", 471, 1903, 7.0]
vanDerPoelData = ["Mathieu Van Der Poel", 460, 1653, 6.7]
froomeData = ["Chris Froome", 480, 1403, 6.3]
cavendishData = ["Mark Cavendish", 465, 1109, 6.2]
\end{lstlisting}
When you're writing your own programs, there isn't necessarily a "right" and a "wrong" way to represent your data, but you should consider what kind of problem you're trying to solve and construct your variables around that. There are certainly "worse" and "better" ways to represent data. If you were trying to create a program that calculated average stats for all of the athletes on a team, then the first model might work better. It's a lot easier to grab all of the elements of just one array, rather than having to iterate through each of the variables for each athlete. However, if you were trying to create a program that showed all of the data for a certain athlete, then the second model would be easier to work with. It would be a lot easier than grabbing one bit of data from a bunch of variables.
\subsubsection*{Exercise Questions}
These exercise questions cover chapter 5.1.
\begin{Exercise}
    \Question{In your own words, describe what a list is.}
    \Question{What advantages do lists offer over simpler datatypes?}
    \Question{What drawbacks to lists have compared to their simpler counterparts?}
\end{Exercise}
\begin{Exercise}
    \Question{Provide an example of a list with all of the same datatype from earlier in this chapter.}
    \Question{For the list that you chose, what datatypes are in the list?}
    \Question{Can you put multiple datatypes into one list? If so, provide an example of this from earlier in this chapter. If not, provide the error message that Python generates.}
\end{Exercise}
\begin{Exercise}
    \Question{What characters are used to enclose a list in Python?}
    \Question{What separates each of the elements in a Python list?}
\end{Exercise}
\begin{Exercise}
    \Question{Write a Python list that has the names of five of your professors or instructors and put the list into a variable called \verb|instructors|.}
    \Question{Write a Python list that has five breeds of dogs and put the list into a variable called \verb|dogs|.}
    \Question{Write a Python list that has the names of four cities and put the list into a variable called \verb|cities|.}
    \Question{Write a Python list that has the number of stories of three residence halls on your campus and put the list into a variable called \verb|resHallHeights|. Follow the line with a comment with the name of the residence halls, but do not store the names in the actual list.}
\end{Exercise}
\subsection{Accessing Data Inside of Lists}
Now that we've created our list, it's probable that we'd want to access some data inside of that list.\par
In the past, when we stored individual elements to a variable, we could just call that variable to get its contents, such as shown here.
\begin{lstlisting}[style=pippython]
ath4name = "Chris Froome"
print(ath4name)
\end{lstlisting}
\begin{lstlisting}[style=none]
Chris Froome
\end{lstlisting}
There's nothing special about the code that we just saw. But, what if we tried to print a list?\par
\begin{lstlisting}[style=pippython]
froomeData = ["Chris Froome", 480, 1403, 6.3]
print(froomeData)
\end{lstlisting}
\begin{lstlisting}[style=none]
['Chris Froome', 480, 1403, 6.3]
\end{lstlisting}
Python very helpfully prints everything in the list. It can't read our mind and figure out that we only want the name, or the first element of the vector.\footnote{The term "list" is a term very specific to Python. In other languages, the more commonly used term is "vector." If you see the term "vector," understand it to mean what a Python list is.}\footnote{There is a difference between arrays and vectors, namely that arrays are assigned a specific length in memory when they are declared, while vectors can be expanded and shrunken at will. Since Python does not differentiate between arrays and vectors, we will not cover their differences in depth in this book, but you'll find more detail in a book on a language with memory management, such as C++.} Instead, we need to instruct Python to only give us a certain \newterm[element]{datatype!list!element} in the list. An element is one individual chunk of data in a list.\par
\boxtext{Why the quotes?}{Observe in the above list how Chris Froome is printed surrounded by single quotes. This is because we are mixing our datatypes in a list, and Python wants to make sure that we know that this is a string. If you see quotes surrounding a list element, you should automatically consider it to be a string element. There is no such differentiation, however, between integers and floats.}\par
\boxtext{Typecasting a list versus list element}{Recall how we \indexterm{typecast} variables in chapter 4.6. We can also typecast elements of a list. Simply refer to the variable that the list is in, along with the element index. Remember to not typecast the entire list if you're only trying to typecast an element in a list.}
We can tell Python to give us the $n$th element in a list, where $n$ is the index of the element in the list, starting at 0. You can think of the $n$th element in a list as you would think of an element in a sequence in calculus. The $n$th element of the Fibonacci sequence $F$ could be denoted as $F_{n}$, where $n$ is the element of the sequence. In this case, instead of sequences, we're looking at lists, and instead of numbers, any type of data can be represented. Let's look at our Chris Froome list in a table, along with the \indexterm{index}\footnote{In this book, we refer to the plural of "index" as "indices." However, you may also see "indexes" written in documentation or in other textbooks.} numbers.\par
\vspace{5mm}
\begin{tabular}{|l|l|l|l|l|}
\hline
Index & 0              & 1   & 2    & 3   \\
\hline
Data  & \verb|"Chris Froome"| & \verb|480| & \verb|1403| & \verb|6.3|\\
\hline
\end{tabular}\par
\vspace{5mm}
\warningtext{Indices start at zero}{Remember, in Python, indices start at 0, not at 1!}\par
If we wanted to get the name, then we could ask Python to give us the 0th element of the array. In Python, we do this using square brackets, just not in the same way that we used to initialize the array. Instead, we can write the name of the variable that has the data in it, followed by square brackets with the index number of the element of the array. Don't add an extra space in between the variable name and the square brackets with the index number.\par
\begin{lstlisting}[style=pippython]
froomeData = ["Chris Froome", 480, 1403, 6.3]
print(froomeData[0])
\end{lstlisting}
\begin{lstlisting}[style=none]
Chris Froome
\end{lstlisting}
Since we're printing a specific element of the array, it prints without the square brackets, commas, or any quotation marks around strings.\par
It's very easy for beginning programmers to forget that arrays start at zero in almost every programming language.\footnote{Arrays start at one in Matlab for some ungodly reason, but it is very much the exception.} If you're having issues getting a specific element of a list, you should double-check that your index number is correct.\par
Just like how we've accessed an element in a list, we can also change that item's value. Changing the value of an element of a list is just like changing an individual variable. However, instead of referring to the variable as a whole, you should only refer to the specific index of data that is to be overwritten. For example, say I got Chris Froome's FTP incorrect: it should be changed to 483. I know that the index of the FTP in the \verb|froomeData| list is at location 1, so I can get the old value easily.
\begin{lstlisting}[style=pippython]
print(froomeData[1])
\end{lstlisting}
\begin{lstlisting}[style=none]
480
\end{lstlisting}
We can also edit that value as if we were editing a regular variable.
\begin{lstlisting}[style=pippython]
froomeData[1] = 483
print(froomeData[1])
\end{lstlisting}
\begin{lstlisting}[style=none]
483
\end{lstlisting}
It might also be helpful to know how many elements are in the list. Python can provide this via the \verb|len()| function, which lets us know the length of the list. \verb|len()| takes one argument, the name of a list, and it returns an integer with the number of elements in the list. Let's say that we forgot how many athletes were in the \verb|names| list. We could use the following to print the length of the list.\par
\begin{lstlisting}[style=pippython]
print(len(names))
\end{lstlisting}
\begin{lstlisting}[style=none]
5
\end{lstlisting}
The return value of the \verb|len()| function is just a regular integer.\par
\subsection{Appending to Lists}
Down the line, it's possible that you'd want to append to a list. Appending an element means that you are adding that new element to the end of an existing list. In order to append to a list, your list must already exist.\par
Let's go back to the original example of lists. It is provided below, for your convenience.
\begin{lstlisting}[style=pippython]
names = ["Peter Sagan",
    "Caleb Ewan",
    "Mathieu Van Der Poel",
    "Chris Froome",
    "Mark Cavendish"]
ftps = [470, 471, 460, 480, 465]
peaks = [1230, 1903, 1653, 1403, 1109]
wpks = [6.7, 7.0, 6.7, 6.3, 6.2]
\end{lstlisting}\footnote{For reference, FTP (functional threshold power), peak power, and WPK (watts per kilogram) are real units for measuring cycling performance, even if the actual measurements are made up. They represent the power that a cyclist can put out.}
Using this code, imagine that we wanted to add another athlete, Tadej Poga\v{c}ar. We could reinitialize all of the lists with the new data, but that's an awful lot of work for something so trivial. Thankfully, Python has a much easier way: the \verb|append()| method. \verb|append()| only takes one argument: the element that is to be appended to the end of the existing list. Instead of passing in the list to append to as an argument, we will instead use a \newterm[method]{functions!method} on the list itself. A method is a way of manipulating a data structure, like a list.\par
The syntax to add an element to a list is as follows.\par
\begin{lstlisting}[style=pippython]
names.append("Tadej Pogacar")
ftps.append(466)
peaks.append(1369)
wpks.append(6.5)
\end{lstlisting}
Since we are using a method on a data structure (the structure is a list), we will put the name of the method after the name of the data structure itself, separated by a period. We can then pass any arguments that we need to pass into to the method inside of the parentheses. Do not confuse methods with functions. They are similar, but they aren't exactly the same. We'll get to those differences in chapter 7.3.\par
What if we want to add multiple pieces of data to an existing list? Let's say that we had two lists, one for male and one for female athletes, but we needed to combine these lists into one. We can use the \verb|extend()| method. \verb|extend()| takes one argument, another list.\footnote{You can also pass in a tuple or a set, but these are topics that we won't cover in depth in this book.} Consider the following code, which creates two lists of names, one for males and one for females, then combines them into one list.
\begin{lstlisting}[style=pippython]
maleNames = ["Peter Sagan",
    "Caleb Ewan",
    "Mathieu Van Der Poel",
    "Chris Froome",
    "Mark Cavendish"]
femaleNames = ["Hannah Barnes",
    "Ella Harris",
    "Jessica Pratt",
    "Ellen van Dijk",
    "Katie Hall"]
allNames = maleNames
allNames.extend(femaleNames)
\end{lstlisting}
We begin by creating our two lists as normal. Then, we can put our list of male names into a new list called \verb|allNames|. We can then extend the \verb|allNames| list using the list of female names. After this, \verb|allNames| has all of the athlete names.\par
\warningtext{Append Versus Extend}{If you attempt to use the append method to append a list to another list, you'll end up creating a nested list, not adding the components of the list to the other list. If you attempt to use the extend method to add a single item to a list, you'll end up with an error, since the extend method expects a list as its argument.}
Just as we have appended to a list, we can also remove items from an existing array. We can do this either by name or by index number. Let's say that we wanted to remove Mark Cavendish from the \verb|allNames| list. We know that his index number is 4 (remember, indices start at 0) and that his entry is \verb|"Mark Cavendish"|, and we can use either to remove the element.\par
If we wanted to remove by name, we can use the \verb|remove()| method. We can pass in the exact data that we want to remove as whatever datatype the data is stored as at that list location. That is, if the data is an integer, we can pass an integer into the \verb|remove()| method. However, we know that the entry is a string, so we'll pass in a string literal.
\begin{lstlisting}[style=pippython]
allNames.remove("Mark Cavendish")
\end{lstlisting}
We can also remove by index by using the \verb|pop()| method. The \verb|pop()| method can only take an integer, the index number of the element.
\begin{lstlisting}[style=pippython]
allNames.pop(4)
\end{lstlisting}
If you do not specify an argument for \verb|pop()|, Python will remove the last element of the array.\par
Finally, we can clear all of the elements of a list. Clearing the elements only clears the contents; it does not remove the list itself. The list only has no content. We do this using the \verb|clear()| method. \verb|clear()| takes no arguments.
\begin{lstlisting}[style=pippython]
maleNames.clear()
\end{lstlisting}
\subsubsection*{Exercise Questions}
\begin{Exercise}
    \Question{Where do indices start in Python lists?}
    \Question{Lists contain multiple objects. What is the formal name for these individual objects?}
    \Question{If you wanted to access the $n$th element of a list, what index number would you give Python in terms of $n$?}
\end{Exercise}
\begin{Exercise}
Consider the \verb|instructors| list that you made in chapter 5.1.1.
    \Question{How long is the list? Give the Python code that gave you how long the list is.}
    \Question{What is the third element of that list? Give the Python code that gave you the third element. Remember, indices start at 0 in Python, so make sure you're getting the third element, not the fourth element!}
    \Question{Add two new professors or instructors to the \verb|instructors| list. What code did you use? Also give the new length of the list, along with the code that you used to get the length of the list.}
    \Question{Print the \verb|instructors| list. Then, remove the third professor or instructor from the \verb|instructors| list by the value of the element (rather than the index). What code did you use?}
    \Question{Without printing the list again, remove the element with index number 4 (not the fourth) from the \verb|instructors| list using the index number (rather than the element value). What code did you use?}
\end{Exercise}
\begin{Exercise}
Consider the \verb|cities| list that you made in chapter 5.1.1.
    \Question{Change the third element (careful about the what the index number is!) to "Berlin" (it's okay if you already have Berlin in your list, we'll just add it again). Provide your code.}
    \Question{Run the following in the Python interpreter: \verb|cities[2]|. What is the output?}
    \Question{Clear all of the elements from the \verb|cities| list, then print the list. What is the code that you used to clear the elements from the list? What is the output?}
    \Question{Now, what datatype is \verb|cities|: list, list of strings, or \indexterm{Nonetype}?}
\end{Exercise}

\section{Dictionaries}
Lists are just one way of storing multiple pieces of data. There are also dictionaries, and they operate in a fundamentally different ways compared to lists.\par
\subsection{Lists Versus Dictionaries}
While lists and dictionaries might appear similar on the surface, each has their own positives and negatives. The underlying concept of each data structure is different, for one. When we took a look at lists and how to get certain elements from lists, we saw that we could draw a table with our index and the data at that index location. Comparatively speaking, dictionaries use a key instead of an index. While lists store data as a sequence of data, lists are stored in key-data pairs. The keys in dictionaries are like sub-variable names, and they describe a specific piece of data within the larger dictionary.\par
Another way to think of dictionaries in Python is to compare them to real dictionaries with words and definitions. In a word dictionary, the words are sorted in some logical manner (alphabetically) and the accompanying data (the definition) is stored alongside the words. In Python, the words are the keys and the definitions are the data.\par
\subsection{Creating Dictionaries}
Just like creating a list is like declaring a variable, creating a dictionary is like creating a list.\par
Let's take a look at how we could represent the data in the second model of lists in chapter 5.1. The data is provided here again.
\begin{lstlisting}[style=pippython]
saganData = ["Peter Sagan", 470, 1230, 6.7]
ewanData = ["Caleb Ewan", 471, 1903, 7.0]
vanDerPoelData = ["Mathieu Van Der Poel", 460, 1653, 6.7]
froomeData = ["Chris Froome", 480, 1403, 6.3]
cavendishData = ["Mark Cavendish", 465, 1109, 6.2]
\end{lstlisting}
At first glance, the name makes sense, but what are the numbers next to the names? We might be able to remember, but it'd be a lot easier if everything was labeled. This is the perfect opportunity to use a dictionary. We could represent the above data as shown in this code.
\begin{lstlisting}[style=pippython]
saganData = {
    "name": "Peter Sagan",
    "ftp": 470,
    "peak": 1230,
    "wpk": 6.7
}
ewanData = {
    "name": "Caleb Ewan",
    "ftp": 471,
    "peak": 1903,
    "wpk": 7.0
}
vanDerPoelData = {
    "name": "Mathieu Van Der Poel",
    "ftp": 460,
    "peak": 1653,
    "wpk": 6.7
}
froomeData = {
    "name": "Chris Froome",
    "ftp": 480,
    "peak": 1403,
    "wpk": 6.3
}
cavendishData = {
    "name": "Mark Cavendish",
    "ftp": 465,
    "peak": 1109,
    "wpk": 6.2
}
\end{lstlisting}
To create a dictionary (or five), surround the contents of each dictionary with curly braces \verb|{}|. Specify the key first, in quotes, as it is a string literal. Delimit the key and the data using a colon \verb|:|, then enter the data that should occupy that key. Separate individual lines with commas \verb|,|. It seems complicated, but with enough time, it's actually pretty simple.\par
As you can see, you can use the same key names in multiple different variables. However, you cannot use the same key name within one dictionary. For example, the following code is not syntactically correct, even though the values are different.
\begin{lstlisting}[style=pippython]
saganData = {
    "name": "Peter Sagan",
    "ftp": 470,
    "peak": 1230,
    "wpk": 6.7
    "wpk": 6.9
}
\end{lstlisting}
\begin{lstlisting}[style=none]
SyntaxError: invalid syntax
\end{lstlisting}
However, we could use the following dictionary, which is syntactically correct.
\begin{lstlisting}[style=pippython]
saganData = {
    "name": "Peter Sagan",
    "ftp": 470,
    "peak": 1230,
    "wpk1": 6.7
    "wpk2": 6.9
}
\end{lstlisting}
\subsection{Accessing Data Inside of Dictionaries}
Accessing data inside of dictionaries is remarkably similar to how we access data inside of lists. We even use the same characters!\par
When accessing data inside of a dictionary, we still use the square brackets \verb|[]| that we used to access data from lists, but what goes inside of those brackets is different. In lists, we put the index number of the element of the array. However, we don't have an index number in a dictionary. Instead, we can use the element's key to get its value. Since we're using a string literal, we need to put the key's name inside of quotes. Consider the following code.\par
\begin{lstlisting}[style=pippython]
froomeData = {
    "name": "Chris Froome",
    "ftp": 480,
    "peak": 1403,
    "wpk": 6.3
}
print(froomeData["ftp"])
\end{lstlisting}
\begin{lstlisting}[style=none]
480
\end{lstlisting}
If you've forgotten what you named your keys, you can also pull up a list of keys for any given dictionary by using the \verb|keys()| method, as shown below.
\begin{lstlisting}[style=pippython]
print(froomeData.keys())
\end{lstlisting}
\begin{lstlisting}[style=none]
dict_keys(['name', 'ftp', 'peak', 'wpk'])
\end{lstlisting}
Python will return the name of all of the keys as a list.\par
\subsection{Appending to Dictionaries}
Appending to dictionaries is an inevitable part of programming as you become more familiar with the tools of the language. You'll never be able to store all the data in your variable initialization, so we'll need to know how to append.\par
Unlike lists, we don't have a simple method to append a new key to a dictionary, like \verb|append()|. Instead, we can append items by simply defining a new key and data pair for the dictionary. Let's say that we wanted to add an updated FTP value for Chris Froome in a key called \verb|updatedFTP|.
\begin{lstlisting}[style=pippython]
froomeData = {
    "name": "Chris Froome",
    "ftp": 480,
    "peak": 1403,
    "wpk": 6.3
}
froomeData["updatedFTP"] = 485
print(froomeData.keys())
\end{lstlisting}
\begin{lstlisting}[style=none]
dict_keys(['name', 'ftp', 'peak', 'wpk', 'updatedFTP'])
\end{lstlisting}
As we can see, there is a new key named \verb|updatedFTP|. We can then use this key as we would any other.\par
However, dictionaries are not method-less. In order to modify existing data, we can use the \verb|update()| method. \verb|update()| takes one argument, a dictionary with new data. Let's say that we wanted to change Chris Froome's FTP, since it was wrong; instead of 480, it should be 483. We can use \verb|update()| to pass in a dictionary specifying the key that should be changed and the value that it should be changed to.\par
\begin{lstlisting}[style=pippython]
froomeData = {
    "name": "Chris Froome",
    "ftp": 480,
    "peak": 1403,
    "wpk": 6.3
}
froomeData.update({"ftp": 483})
\end{lstlisting}
The brackets and braces might look confusing, but break it down and it becomes quite simple. The outer parentheses \verb|()| are for the \verb|update()| method, and they specify arguments for that method. The curly braces \verb|{}| are for the dictionary, and they specify that the data being passed in is a dictionary and what the contents of that dictionary are.\par
Of note is that if you attempt to run the \verb|update()| method on a dictionary that doesn't already have that key, Python will create the key and populate it with the data that you specify. You can then use this key as if you had created it by using the first method of appending to a dictionary.
\subsubsection*{Exercise Questions}
These exercise questions cover chapter 5.2
\begin{Exercise}
    \Question{What is a dictionary?}
    \Question{What are the differences between Python lists and dictionaries?}
    \Question{Lists store data in [?]-[?] pairs, whereas dictionaries store data in [?]-[?] pairs. (Fill in the blanks)}
    \Question{Suppose you wanted to store the names of all of the NHL teams. Would you use a list or a dictionary? Why?}
\end{Exercise}
\begin{Exercise}
    \Question{Consider a potential dictionary named \verb|falcons| that would hold team data from the Atlanta Falcons NFL team. What are some key names that this dictionary might have?}
    \Question{Consider a potential dictionary that would hold information on one of the dorms on your campus. What might you name the dictionary? What are some key names that this dictionary might have?}
\end{Exercise}
\begin{Exercise}
    \Question{Create a new dictionary inside of a variable named \verb|eagles|. Add four keys: \verb|code|, \verb|city|, \verb|wins|, and \verb|winrate|. Initialize all of the keys to a \indexterm{Nonetype}.}
    \Question{In the \verb|eagles| dictionary, change the \verb|code| value to a string \verb|PHI|.}
    \Question{In the \verb|eagles| dictionary, change the \verb|city| value to a string\\ \verb|Philadelphia|.}
    \Question{In the \verb|eagles| dictionary, change the \verb|wins| value to an integer \verb|4|.}
    \Question{The Eagles played 16 games, of which they won four, tied one, and lost eleven. Use Python to calculate the win percentage. Win percentage is calculated using the following formula: ($2 \times \text{wins} + \text{ties}) / (2 \times \text{total games played}) \times 100$. Put the value in the \verb|eagles| dictionary in the \verb|winrate| key as a float. Try to do this in a single line.}
\end{Exercise}

\section{Tuples}
\newterm[Tuples]{datatype!tuple} are most often used to pass data between different data structures, which we'll cover in Chapter 7. You may have heard of tuples in precalculus, calculus, linear algebra, or some other mathematics course, where the definition of a tuple is a sequence of $n$ elements, where $n$ is some non-negative integer. Tuples, by definition, are ordered (given that they are a sequence), and they must be finite.\par
For example, $(2, 3, 4, 5, 6)$ is a valid mathematical tuple. It has a $n=5$, which is greater than zero and is finite. The size of this tuple is immutable - this is a 5-tuple, and it will always be a 5-tuple.\par
\boxtext{Tuple Notation}{If you haven't worked with tuples before, $n$-tuple notation is used to give the size of the tuple. A 5-tuple means that the tuple has 5 elements in it.}
Tuples are very similar in Python. Like a mathematical tuple, a tuple must have a size greater than 0 and must be finite. Unlike mathematical tuples, tuples can have different datatypes in them. Like in a list, you can mix booleans, integers, floats, and strings in a single tuple. You can also refer to tuple elements by their index number using square brackets, just like in lists. However, you cannot make a tuple larger or smaller after you create its size. If you create a 3-tuple, your tuple size is limited to 3. Tuples are also immutable. Once you create a tuple, you cannot change its value.\par
Consider the following tuple.\par
\begin{lstlisting}[style=pippython]
leafygreens = ("Romaine Lettuce", "Iceberg Lettuce", "Arugula")
\end{lstlisting}
We could refer to the second element (iceberg lettuce) by its index number 1.
\warningtext{Indices start at zero}{Indices start at 0 in Python!}
\begin{lstlisting}[style=pippython]
print(leafygreens[1])
\end{lstlisting}
\begin{lstlisting}[style=none]
Iceberg Lettuce
\end{lstlisting}
However, we cannot redefine the second element to be Butterhead Lettuce.\par
\begin{lstlisting}[style=pippython]
# NOT CORRECT
leafygreens[1] = "Butterhead Lettuce"
\end{lstlisting}
If I want to change an element in the tuple, I need to reinitialize the entire tuple variable.\par
\begin{lstlisting}[style=pippython]
leafygreens = ("Romaine Lettuce", "Butterhead Lettuce", "Arugula")
print(leafygreens[1])
\end{lstlisting}
\begin{lstlisting}
Butterhead Lettuce
\end{lstlisting}
If we want to store data, it is almost always more practical to use a list or a dictionary. However, there are still some cases where we would want to use a tuple: when we are interacting with functions. When we want to call a function and pass specified arguments to that function, we should use a tuple, since a tuple is of a fixed length and is immutable. In this use case, we will almost never see the tuple placed into a variable, but rather given as a tuple literal. Because of their limited use case, you probably won't want to use a tuple unless you see it in library documentation for some module that you're using. We wanted to introduce the concept of tuples to you regardless, since they do exist.
\subsubsection*{Exercise Questions}
These exercise questions cover chapter 5.3.
\begin{Exercise}
\Question{What is a tuple?}
\Question{How is a tuple different from a list?}
\Question{In Python, how do we create a tuple?}
\Question{Can tuples be changed after they are created? Provide an example backing up your claim.}
\end{Exercise}
\begin{Exercise}
Define a 4-tuple of strings with courses that you have taken. Do not put the tuple into a variable.
\end{Exercise}

\section{Sets}
\newterm[Sets]{datatype!set} are the simplest of the complex datatypes, so if you understand lists, dictionaries, and tuples, you already understand a set.\par
In mathematics, sets are simply a collection of elements. There are no orders, sequences, or indices. Sets also cannot contain duplicate entries. Any duplicate entries will be ignored, since in a set, all that matters is whether an element is present in the set or not. This means that the set ${2, 3, 4}$ and ${2, 3, 4, 3}$ are the same, since the values 2, 3, and 4 are in both sets. In mathematics, we write sets inside of curly braces: ${2, 3, 4, 5, 6}$.\par

\subsubsection*{Exercise Questions}
These exercise questions cover chapter 5.4.

No exercise questions exist for this section.

\section{Subsetting}
Now that we have seen indices in Python, we can subset based on those indices. For example, consider this list.\par
\begin{lstlisting}[style=pippython]
names = ["Peter Sagan",
    "Caleb Ewan",
    "Mathieu Van Der Poel",
    "Chris Froome",
    "Mark Cavendish"]
\end{lstlisting}
We know that lists are indexed at 0, so if we wanted to get Mathieu Van Der Poel out of the list, we could refer to \verb|names[2]|.
\begin{lstlisting}[style=pippython]
print(names[2])
\end{lstlisting}
\begin{lstlisting}[style=none]
Mathieu Van Der Poel
\end{lstlisting}
What if we wanted to get the first two elements from the list? We could refer to the \verb|0|'th and \verb|1|'s element, sure. But, a better tool is something called \newterm[subsetting]{datatype!subset}. Subsetting allows us to get any number of elements from a vector of objects, including strings and lists.\footnote{They also work on non-native datatypes, like the Pandas dataframe and series or the NumPy array, which we'll cover in Chapter 10.}\par
The subsetting operator is a colon inside of square brackets. The colon is sort of like a "to" operator, meaning that we can refer to index numbers $i$ to $j$ as \verb|[i:j]|. Consider the \verb|names| list from before. If we wanted to refer to the first three names, we really want names 0 to 3 (not including 3), so we can refer to this as the following.
\begin{lstlisting}[style=pippython]
print(names[0:3])
\end{lstlisting}
\begin{lstlisting}[style=none]
['Peter Sagan', 'Caleb Ewan', 'Mathieu Van Der Poel']
\end{lstlisting}
If we wanted names 1 and 2, we could use this.
\begin{lstlisting}[style=pippython]
print(names[1:3])
\end{lstlisting}
\begin{lstlisting}[style=none]
['Caleb Ewan', 'Mathieu Van Der Poel']
\end{lstlisting}
What if we wanted to refer to the last element of the vector? Python supports something really cool called \newterm[negative indexing]{datatype!subset!negative indexing}. This essentially counts the vector in reverse order, starting at -1. So, the last element is -1, the second-to-last element is -2, the third-to-last element is -3, and so on. If we wanted to get the last element of the \verb|names| list, we could use negative indexing to get that element.
\begin{lstlisting}[style=pippython]
print(names[-1])
\end{lstlisting}
\begin{lstlisting}[style=none]
'Mark Cavendish'
\end{lstlisting}
If we wanted the second-to-last element, we could use negative indexing to get just that element.\par
\begin{lstlisting}[style=pippython]
print(names[-2])
\end{lstlisting}
\begin{lstlisting}[style=none]
'Chris Froome'
\end{lstlisting}
Subsetting also works on strings, where each character in the string is considered its own element. So, let's say we had the string:
\begin{lstlisting}[style=pippython]
text = "This will begin to make things right. I've traveled too far, and seen too much, to ignore the despair in the galaxy. Without the Jedi, there can be no balance in the Force. Well, because of you now we have a chance."
\end{lstlisting}
This isn't a \textit{short} string persay, and we might not want to print the whole string every time. If we want the first few characters of the string, we can use the third type of subsetting: \newterm[implicit subsetting]{datatype!subset!implicit}. Implicit subsetting is deliberately leaving out either the to or from marker. In implicit subsetting, Python will assume that you want to subset from the beginning of the vector to the set mark or from the set mark to the end of the vector. Where a blank exists, Python fills the blank with either the first element (if the "from" element is blank) or the last element (if the "to" element is blank). Consider the above string. If we only wanted to print the first 30 characters of this string, we can use implicit subsetting to tell Python that we want to print the beginning of the string up to the 30th element.\par
\begin{lstlisting}[style=pippython]
print(text[:30])
\end{lstlisting}
\begin{lstlisting}[style=none]
This will begin to make things
\end{lstlisting}
Similarly, if we wanted to print the all but the first 50 characters of this string, we can use implicit subsetting to tell Python that we want to print from the 50th element to the last element.
\begin{lstlisting}[style=pippython]
print(text[50:])
\end{lstlisting}
\begin{lstlisting}[style=none]
d too far, and seen too much, to ignore the despair in the galaxy. Without the Jedi, there can be no balance in the Force. Well, because of you now we have a chance.
\end{lstlisting}
We can also throw negative indexing into our implicit subsetting for an extra fun time! If we wanted to print only the last 50 characters, we could use negative indexing and an implicit subset. This is essentially telling Python to give us from the 50th-to-the-last element to the last element.
\begin{lstlisting}[style=pippython]
print(text[-50:])
\end{lstlisting}
\begin{lstlisting}[style=none]
 Force. Well, because of you now we have a chance.
\end{lstlisting}
Similarly, we could tell Python to give us from the first element to the 50th-to-the-last element.
\begin{lstlisting}[style=pippython]
print(text[:-50])
\end{lstlisting}
\begin{lstlisting}[style=none]
This will begin to make things right. I've traveled too far, and seen too much, to ignore the despair in the galaxy. Without the Jedi, there can be no balance in the
\end{lstlisting}
Negative indexing and implicit subsetting also work with lists. If we consider our \verb|names| list and we wanted from the third-to-the-last to the last element, we could use implicit subsetting with a negative index to get those three elements.
\begin{lstlisting}[style=pippython]
print(names[-3:])
\end{lstlisting}
\begin{lstlisting}[style=none]
['Mathieu Van Der Poel', 'Chris Froome', 'Mark Cavendish']
\end{lstlisting}
\subsubsection*{Exercise Questions}
These exercise questions cover chapter 5.5.
\begin{Exercise}
	\Question{What is subsetting?}
	\Question{What kinds of objects can be subsetted?}
	\Question{What is negative indexing?}
	\Question{What is implicit subsetting?}
\end{Exercise}
\begin{Exercise}
	\Question{Create a string with the following text: "Let's have a nice tree right here. Nothing wrong with washing your brush. If I paint something, I don't want to have to explain what it is. Don't be afraid to make these big decisions. Once you start, they sort of just make themselves. Everything is happy if you choose to make it that way."}
	\Question{Put that string into a variable called \verb|happytree|.}
	\Question{Print the first 30 characters of \verb|happytree|.}
	\Question{Print the last 30 characters of \verb|happytree|.}
	\Question{Print the 10th to the 40th character of \verb|happytree|.}
	\Question{Print from the 30th character to the last character of \verb|happytree|.}
\end{Exercise}
\begin{Exercise}
	\Question{Create a list with the following elements and put it into a variable called \verb|pokemon|:\\
"Bulbasaur"\\
"Ivysaur"\\
"Venusaur"\\
"Charmander"\\
"Charmeleon"\\
"Charizard"\\
"Squirtle"\\
"Wartortle"\\
"Blastoise"\\
"Caterpie"\\
"Metapod"\\
"Butterfree"\\
"Weedle"\\
"Kakuna"\\
"Pikachu"\\
"Arbok"\\
"Raichu"\\
"Nidorino"}
	\Question{How many elements are in this list? What method did you use to get this length?}
	\Question{Print the first element of \verb|pokemon|.}
	\Question{Print the last element of \verb|pokemon|.}
	\Question{Print the third element of \verb|pokemon|.}
	\Question{Print the first three elements of \verb|pokemon|.}
	\Question{Print the last three elements of \verb|pokemon|.}
	\Question{Print the third to the last element of \verb|pokemon|.}
\end{Exercise}
\begin{Exercise}
	\Question{Create a list with the following elements and put it into a variable called \verb|villans|:\\
"Bane"\\
"Black Mask"\\
"Catwoman"\\
"Clayface"\\
"Deadshot"\\
"Firefly"\\
"Harley Quinn"\\
"Professor Hugo Strange"\\
"Hush"\\
"Joker"\\
"Killer Croc"\\
"Mr. Freeze"\\
"Man-Bat"}
	\Question{How many elements are in this list? What method did you use to get this length?}
	\Question{Print the first element of \verb|villans|.}
	\Question{Print the last element of \verb|villans|.}
	\Question{Print the last seven elements of \verb|villans|.}
	\Question{Print from the 7th element to the last element of \verb|villans|.}
	\Question{Print the seventh element of \verb|villans|.}
	\Question{Print the seventh-from-the-last element of \verb|villans|.}
\end{Exercise}

\section{String Manipulation}
We just covered subsetting, including in strings and in lists, but we will cover two more methods for manipulating strings in Python: stripping and matching.
\subsection{Stripping}
An important feature of string handling is the ability to remove characters from a string. For example, let's say you got some data and it was formatted as \verb|&&data&&| or it was surrounded by spaces. How could we get rid of this cruft?\par
The process of stripping removes unwanted characters from a string. Python provides us with three stripping methods: left stripping, right stripping, and dual stripping. As their names suggest, these methods can remove characters from the left side of the string, the right side of the string, or from both sides of the string at the same time, respectively. The functions to do this are \verb|lstrip()|, \verb|rstrip()|, and \verb|strip()|.\par
By default, all three methods only remove whitespace. So, if you had extra tabs or spaces at the beginning or end of your string, you could simply call the \verb|strip| method to remove the whitespaces.\par
\begin{lstlisting}[style=pippython]
print("  data  ")
print("  data  ".strip())
\end{lstlisting}
\begin{lstlisting}[style=none]
  data
data
\end{lstlisting}
We didn't give the \verb|strip()| method anything, so it only removed the spaces. However, we could also give it letters, numbers, symbols, or any other valid characters. For example, consider the following two print statements.\par
\begin{lstlisting}[style=pippython]
print("fpppppppppppppppffdatapffffffppppp")
print("fpppppppppppppppffdatapffffffppppp".strip("fp"))
\end{lstlisting}
\begin{lstlisting}[style=none]
fpppppppppppppppffdatapffffffppppp
data
\end{lstlisting}
As soon as Python runs into a character that shouldn't be stripped, it stops evaluating from that side. So, even if my word contained \verb|p| and \verb|f|, it wouldn't get stripped out. For example, consider the following print statement.\par
\begin{lstlisting}[style=pippython]
print("pppppppppppppapplepppp".strip("p"))
\end{lstlisting}
\begin{lstlisting}[style=none]
apple
\end{lstlisting}
The word "apple" has the letter \verb|p| in it, but it doesn't get stripped out because Python has stopped when it reached the \verb|a|.\par
Let's now consider the left stripping. Left-stripping will remove letters that match stop words from the beginning of the string only.\par
\begin{lstlisting}[style=pippython]
print("pppppppppppppapplepppp".lstrip("p"))
\end{lstlisting}
\begin{lstlisting}[style=none]
applepppp
\end{lstlisting}
Python removed all of the \verb|p|'s on the left side, up to the first non-stripped character. It didn't remove anything from the right side, though. If we wanted to only remove the right-side characters, we can use the \verb|rstrip()| method.\par
\begin{lstlisting}[style=pippython]
print("pppppppppppppapplepppp".rstrip("p"))
\end{lstlisting}
\begin{lstlisting}[style=none]
pppppppppppppapple
\end{lstlisting}
\subsubsection*{Exercise Questions}
These exercise questions cover chapter 5.6.1.
\begin{Exercise}
	\Question{What were the three methods introduced?}
	\Question{What is the difference between each method?}
\end{Exercise}
\begin{Exercise}
	\Question{If you wanted to remove certain characters from the beginning of a string, what method would you use?}
	\Question{If you wanted to remove certain characters from the end of a string, what method would you use?}
	\Question{If you wanted to remove certain characters from the beginning and end of a string, what method would you use?}
\end{Exercise}
\begin{Exercise}
	\Question{Define a new string named \verb|fruit| and initialize it to \verb|33333banana33333|.}
	\Question{Remove only the characters \verb|3| from the left side of \verb|fruit|.}
	\Question{Remove only the characters \verb|3| from the right side of \verb|fruit|.}
	\Question{Remove the letters \verb|a| and \verb|b| from the left side of \verb|fruit|. Leave the \verb|a| on the right side of \verb|fruit|.}
\end{Exercise}
\begin{Exercise}
Consider the string \verb|aaaaaaabababbbbbb| for this exercise.
	\Question{Without writing any code, strip the character \verb|a| from both sides of the string. Why did you stop removing characters where you did?}
	\Question{Without writing any code, strip the character \verb|b| from both sides of the original string (the string before part 1). Why did you stop removing characters where you did?}
	\Question{Without writing any code, strip the characters \verb|ab| from both sides of the original string. Why did you stop removing characters where you did?}
\end{Exercise}
\begin{Exercise}
	\Question{Define a new string named \verb|actor| and initialize it to \\\verb|////  Chadwick Boseman    ****|. There are two spaces between the forward slashes and "Chadwick", and there are four spaces between "Boseman" and the asterisks.}
	\Question{In one line, remove the asterisk and forward slash characters from \verb|actor|.}
	\Question{Remove the spaces from the beginning and end of \verb|actor|. Did you specify any arguments for the function that you used? Why or why not?}
\end{Exercise}

\subsection{Regular Expression Matching}
What if we wanted to match a chunk of a string? This is where regular expressions come in. Regular expressions, or \newterm[regexes]{regex} allow us to match or check if a match exists between two strings. Regexes have some special style that allows us to match as specifically or as broadly as is necessary for the application.\par
\subsubsection{Regexes}
For this section, let's consider the following text.
\begin{lstlisting}[style=none]
He is headstrong and he has much to learn of the living Force, but he is capable. There is little more he can learn from me. Young Skywalker's fate will be decided later. Now is not the time for this. the Senate is voting for a new Supreme Chancellor and Queen Amidala is returning home, which will put pressure on the Federation, and could widen the confrontation. And draw out the Queen's attacker.
\end{lstlisting}
The most simple regex is a direct match. To make a direct match, we simply enter the string to match. Let's try to match the word "the". The regex parser will find 6 matches ("of the living," "not the time", "the Senate is," "on the Federation," "widen the confrontation," and "out the Queen's").\par
If we chose a direct match that occurs inside of other words, the regex parser will grab those as well. For example, if we try to match the phrase "ch", the regex parser will find 2 matches ("has much to" and "home, which will").\par
There are several characters that we can use to modify the regex search, with the most greedy being the period. This character is something called a \newterm[wildcard]{regex!wildcard}, which means that it can match different things that adhere to a certain condition. The period matches any single character, meaning that each character in our text has been matched ("H", "e", " ", "i", "s", " ", "h", "e", "a", "d", "s", "t", "r", "o", "n", "g", " "...).\par
What if we wanted to find a word character only? This is where the word wildcard comes in: \verb|\w|. The \verb|\w| wildcard matches any word character, including from A-Z, a-z, 0-9, or the underscore character. In our text, the \verb|\w| wildcard would match "H", "e", "i", "s",..., "e", "r", but skip spaces, periods, and apostrophes. Similarly, the \verb|\d| wildcard matches any digit from 0-9. It would find no matches in the text above, since the text above has no digits. The \verb|\s| wildcard matches any whitespace, including spaces, tabs, newlines, and carriage returns.\par
\warningtext{Case Sensitive}{Regexes are case sensitive, meaning that \texttt{\textbackslash d} and \texttt{\textbackslash D} are not the same thing.}
The \verb|\w|, \verb|\d|, and \verb|\s| wildcards also have negative versions, meaning that it will search the opposite. The negative versions are the capital \verb|\W|, \verb|\D|, and \verb|\S|, which will find \textit{non}-word, \textit{non}-digit, and \textit{non}-whitespace characters, respectively. That means that using the \verb|\s| (lowercase) wildcard catches all of the spaces and the newline at the end of the passage, while the \verb|\S| (uppercase) wildcard catches all of the letters, numbers, and symbols but no spaces or newlines.\par
We can also create our own custom character sets to select by. For example, if we wanted only the letters \verb|a|, \verb|b|, \verb|c|, \verb|d|, and \verb|e| to be captured, you can use a custom character set. To create a custom character set, just enclose the characters that you want to include in square brackets. So, to catch \verb|a|, \verb|b|, \verb|c|, \verb|d|, and \verb|e|, we would write \verb|[abcde]|. This would catch every letter that is a, b, c, d, or e, lowercase only. In our passage, it would catch the \verb|e| in \verb|He|, but not the \verb|H|. It also catches the \verb|e|, \verb|a|, and \verb|d| in \verb|headstrong|. If we wanted to include capitals, we would need to explicitly set this in our regex: \verb|[ABCDEabcde]|. This would also catch the \verb|C| in \verb|Chancellor|.\par
Regexes also can span a range of letters by using the dash \verb|-|. For example, if we wanted to rewrite the previous regex (\verb|[ABCDEabcde]|) using a dash, we could write \verb|[A-Ea-e]|. This works for \verb|[A-Z]|, \verb|[a-z]|, and \verb|[0-9]|. So, the following regex would capture every letter and number from A-z, 0-9, no matter the case: \verb|[A-Za-z0-9]|.\par
To this point, we have only been covering single characters unless we specify a literal match. What if we want to match multiple letters? This is called a quantifier, and it allows us to match multiples of characters together as one. For example, if we wanted to match an entire word (instead of matching letters of a word), we would use a quantifier on a letter wildcard. There are six valid quantifiers.
\begin{itemize}
\item \verb|?| matches zero or one of the previous token
\item \verb|*| matches zero or more of the previous token
\item \verb|+| matches one or more of the previous token
\item \verb|{n}| matches exactly $n$ of the previous token
\item \verb|{n,}| matches $n$ or more of the previous token
\item \verb|{n,m}| matches between $n$ and $m$ of the previous token
\end{itemize}
Let's apply this to our passage. We'll use the \verb|[A-Za-z]| regex as our token to quantify. If we apply the \verb|?| quantifier, our regex looks like \verb|[A-Za-z]?|, and this will match every single letter, as well as a \verb|None| at the end of every word, since the end of every word has zero of the \verb|[A-Za-z]| token.\par
If we use the \verb|*| quantifier, our regex looks like \verb|[A-Za-z]*|, and this will match zero or one capital or lowercase letters. This will match every single word, but it will also match the end of every word, resulting in every other match being \verb|None| or \verb|null|.\par
Instead, we might want to use the \verb|+| quantifier, which will look like \verb|[A-Za-z]+|. This will match entire words separated by anything that isn't a letter. We don't get any \verb|None|s or nulls.\par
If we use the \verb|{2}| quantifier, our regex will look like \verb|[A-Za-z]{2}|. This will match all two letter pairs. So, it will match \verb|He| and \verb|is|, but it will also match the chunks of "headstrong" as \verb|he|, \verb|ea|, \verb|ds|, \verb|ro|, and \verb|ng|.\par
If we use the \verb|{3,}| quantifier, our regex will look like \verb|[A-Za-z]{3,}|. This will match all words that are three letters long or longer. So, it won't match \verb|He| or \verb|is|, but it will match \verb|headstrong| and \verb|and|.\par
If we use the \verb|{3,6}| quantifier, our regex will look like \verb|[A-Za-z]{3,6}|. This will match all words that are three letters long or longer, but six letters long or shorter. So, this will match \verb|and| and \verb|much|, but it won't match with the entirety of "headstrong". However, it will match \verb|headst| and \verb|rong| from \verb|headstrong|.\par
If we wanted to match only entire words, we need to use something called a word boundary. Word boundaries limit matches to immediately between a character matched by the \verb|\w| (lowercase) wildcard and a character by \verb|\W| (capital) wildcard (in either order). So, if we wanted to only find whole words that are between 3 and 6 letters long that are lowercase or have uppercase letters, we would have to put word boundaries around the beginning and end to make sure that the space is present at the beginning and end of the word. This would look like \verb|\b[A-Za-z]{3,6}\b|. This regex would match word like \verb|and| and \verb|Senate|, but it would not match \verb|headstrong|, since by the sixth character, the next character is not a \verb|\W| character.\par
This is a very basic introduction to regexes. Regexes can become incredibly complex. For example, something as simple as an email address can require a doozy of a regex.\par
\begin{lstlisting}[style=none]
(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])
\end{lstlisting}
This regex is actually on the shorter end of email-address-validating regexes. However, the best way to get started with regexes is to write them out.
\subsubsection{Regex Matching in Python}
Python has a library called \verb|re| that provides regular expression matching capabilities. This library can be loaded by this line.\par
\begin{lstlisting}[style=pippython]
import re
\end{lstlisting}
One of the most common methods inside of \verb|re| is the \verb|match()| method. The \verb|match()| method takes two arguments: \verb|pattern| and \verb|string|, which correspond to the regex and the string to be tested. The \verb|match()| method, as its name suggests, matches at the beginning of the string.\par
In Python, when we write out a regex, we should specify to Python that we are actually writing out a regex instead of just a regular string, and we do that by fixing a \verb|r| to the beginning of the string, before the opening quotation mark.\par
Let us consider the following string.\par
\begin{lstlisting}[style=pippython]
teststr = "Traveling through hyperspace isn't like dusting crops, boy! Without precise calculations we could fly right through a star or bounce too close to a supernova and that'd end your trip real quick, wouldn't it? What's that flashing? We're losing our deflector shield. Go strap yourself in, I'm going to make the jump to light speed. We've entered the Alderaan system. Governor Tarkin, I should have expected to find you holding Vader's leash."
\end{lstlisting}
Let's say that we wanted to find all of the full words that were longer than 4 letters. Our regex for this would look like \verb|\b[A-Za-z]{4,}\b|. This regex matches the letters from A-Z and a-z (case insensitive) in sequences of at least four letters long between two word boundaries. We can apply this to the \verb|match()| method as follows.\par
\begin{lstlisting}[style=pippython]
matches = re.match(r'\b[A-Za-z]{4,}\b', teststr)
\end{lstlisting}
Notice how the regex is prefixed with a \verb|r|. This tells Python that this should be treated as a regex, and normal escaping should be ignored.\cprotect\footnote{If normal escaping is in effect, things like \verb|\n| would be evaluated as newlines instead of as a newline in a regex, and your regex would likely not work correctly.}\par
The \verb|match()| method returns a \verb|Match| object with the first valid match. We can get the match by looking at the \verb|0|th element of the \verb|Match| object, which returns the entire match.
\begin{lstlisting}[style=pippython]
print(matches[0])
\end{lstlisting}
\begin{lstlisting}[style=none]
Traveling
\end{lstlisting}
In this case, the first match is the word \verb|Traveling|. There is no object at \verb|[1]|, since the \verb|match()| method only returns the first match. But what if we wanted to get all of the matches?\par
This is where the \verb|findall()| method comes in. The \verb|findall()| method scans through the entire string and puts the resulting matches into a list. Here is the same regex, but using the \verb|findall()| method instead of the \verb|match()| method. Again, this regex matches the letters from A-Z and a-z (case insensitive) in sequences of at least four letters long between two word boundaries.
\begin{lstlisting}[style=pippython]
matches = re.findall(r'\b[A-Za-z]{4,}\b', teststr)
print(matches)
\end{lstlisting}
\begin{lstlisting}[style=none]
['Traveling', 'through', 'hyperspace', 'like', 'dusting', 'crops', 'Without', 'precise', 'calculations', 'could', 'right', 'through', 'star', 'bounce', 'close', 'supernova', 'that', 'your', 'trip', 'real', 'quick', 'wouldn', 'What', 'that', 'flashing', 'losing', 'deflector', 'shield', 'strap', 'yourself', 'going', 'make', 'jump', 'light', 'speed', 'entered', 'Alderaan', 'system', 'Governor', 'Tarkin', 'should', 'have', 'expected', 'find', 'holding', 'Vader', 'leash']
\end{lstlisting}
Now, let's suppose that we had a comma-separated file and we wanted to separate the individual elements into a list, without the commas. This is where we would use the \verb|split()| method. The \verb|split()| method splits a string at every match and puts everything between the matches into list elements.\par
Let's suppose that we had the following string, which represents comma-separated values.
\begin{lstlisting}[style=pippython]
testcommas = "172,Austin Czarnik,czarnau01,29,Eastern,Metropolitan,NYI,Off,C,12,95,86,52.5,5.4,72,61,54.1,7.1,16.9,91.8,108.8,51.7,48.3,11:02,10:22,4,4,-0.1,16,62.5,0:41,10:23,3.5,4.2,1.6,0:27,7.7,14,0,0:11,-11,0,23.7,2,4,6,6,0,0.9,2,0,0,0,4,0,0,10,20,132,11:02,5,2,23,35,39.7"
\end{lstlisting}
If we call the \verb|split()| method to split on commas, we will split this string into individual cells without the commas. For this, we will use the regex \verb|r','|, which matches on the literal comma character \verb|,|.\par
\begin{lstlisting}[style=pippython]
matches = re.split(r",", testcommas)
print(matches)
\end{lstlisting}
\begin{lstlisting}[style=none]
['172', 'Austin Czarnik', 'czarnau01', '29', 'Eastern', 'Metropolitan', 'NYI', 'Off', 'C', '12', '95', '86', '52.5', '5.4', '72', '61', '54.1', '7.1', '16.9', '91.8', '108.8', '51.7', '48.3', '11:02', '10:22', '4', '4', '-0.1', '16', '62.5', '0:41', '10:23', '3.5', '4.2', '1.6', '0:27', '7.7', '14', '0', '0:11', '-11', '0', '23.7', '2', '4', '6', '6', '0', '0.9', '2', '0', '0', '0', '4', '0', '0', '10', '20', '132', '11:02', '5', '2', '23', '35', '39.7']
\end{lstlisting}
Python has split up the \verb|testcommas| string on the commas without including any of the commas themselves. Our regular expression was matching on the literal comma character \verb|,|, so any matches to the regular expression were considered to be a delimiting character.
\subsubsection*{Exercise Questions}
These exercise questions cover chapter 5.6.2.
\begin{Exercise}
	\Question{What is a regular expression?}
	\Question{Why might we want to write a regular expression?}
\end{Exercise}
\begin{Exercise}
Write a Python-compliant regular expression that captures the following expressions.
	\Question{The exact phrase "cat".}
	\Question{The exact phrase "dog".}
	\Question{The exact phrase "cat" or "dog".}
	\Question{A three-digit number.}
	\Question{Lowercase-only words surrounded by a space that are exactly five letters long. Do not capture the space.}
	\Question{Uppercase-only words surrounded by a space that are exactly six letters long. Do not capture the space.}
	\Question{Uppercase-only words surrounded by a space that are more or equal to one letter but less than or equal to five letters. Do not capture the space.}
	\Question{Uppercase letters, lowercase letters, numbers, and underscores.}
	\Question{Uppercase letters, lowercase letters, and numbers surrounded by a space that are more than or equal to three letters. Do not capture the space.}
	\Question{Spaces, tabs, newlines, and carriage returns.}
	\Question{Commas, apostrophes, quotation marks, exclamation marks, and dollar signs.}
	\Question{Two or more commas next to each other.}
	\Question{Exactly two spaces next to each other.}
	\Question{Words that are exactly five letters long.}
\end{Exercise}
\begin{Exercise}
	\Question{What are the methods that we introduced for using regular expressions in Python?}
	\Question{Let's say you were given a paragraph of prose text and you were told to split it into individual words. What method would you use? You do not need to write out the regular expression; only provide the method.}
	\Question{Let's say you were given a stanza of poem text and you were told to split it into individual lines. What method would you use? You do not need to write out the regular expression.}
	\Question{Let's say you were given a paragraph of prose text and you were told to find the first instance of a phrase. What method would you use? You do not need to write out the regular expression.}
	\Question{Let's say you were given a line of delimiter-separated data and you were told to split the individual data elements into their own elements in a list. What method would you use? You do not need to write out the regular expression.}
\end{Exercise}
\begin{Exercise}
For the following exercise questions, consider the following text passage.\\
\begin{lstlisting}[style=none]
It is a period of civil war. Rebel spaceships, striking from a hidden base, have won their first victory against the evil Galactic Empire. During the battle, Rebel spies managed to steal secret plans to the Empire's ultimate weapon, the DEATH STAR, an armored space station with enough power to destroy an entire planet. Pursued by the Empire's sinister agents, Princess Leia races home aboard her starship, custodian of the stolen plans that can save her people and restore freedom to the galaxy...\end{lstlisting}
\Question{Write a regular expression and choose the correct method to get the word \verb|Rebel| from the text.}
\Question{Write a regular expression and choose the correct method to get the phrase \verb|civil war| from the text.}
\Question{Write a regular expression and choose the correct method that puts all words that start with a capital letter in a list.}
\end{Exercise}
\begin{Exercise}
For the following exercise questions, consider the following text passage. Indented lines are part of the previous line (meaning that there are six total lines).\\
\begin{lstlisting}[style=none]
Once upon a midnight dreary, while I pondered, weak and weary,
Over many a quaint and curious volume of forgotten lore-
While I nodded, nearly napping, suddenly there came a tapping,
As of some one gently rapping, rapping at my chamber door.
"'Tis some visitor," I muttered, "tapping at my chamber door-
Only this and nothing more."
\end{lstlisting}
\Question{Write a regular expression and choose the correct method to put each line of the poem into its own list element.}
\Question{Write a regular expression and choose the correct method to put all of the words that end in \textit{ing} into a list. This should match words like \textit{napping}, \textit{tapping}, and \textit{rapping}.}
\Question{Write a regular expression and choose the correct method to put all of the phrases that start with a quotation mark and end with a qotation mark into a list. For your convenience, all of the quotation marks have been converted to standard quotes (instead of smart quotes).}
\Question{Write a regular expression and choose the correct method to put each phrase of the poem into its own list element. Each phrase starts with a comma, dash, or period and ends with the next comma, dash, or period. So, \textit{Once upon a midnight dreary} would be considered one phrase, \textit{while I pondered} is another phrase, \textit{weak and weary} is another phrase, and \textit{Over many a quaint and curious volume of forgotten lore} is another phrase. Note that newlines are not necessarily an indicator of a new phrase.}
\end{Exercise}

\section{Random Number Generation}
Now that we have knowledge of complex datatypes, it makes sense for us to now cover random number generation, since some random number generation outputs rely on prior knowledge of complex datatypes.\par
Random number generation is a very useful feature of any programming language, but in order to understand the limitations of random number generation, we need to understand why computers can't generate random numbers.\par
If you've used a Texas Instruments TI-84 graphing calculator, you may have generated random numbers using it. If you were in a classroom with others, you might've gotten the same random numbers, meaning that the numbers aren't really randomly generated.\par
This is a deficiency with computers. Computers are inherently unable to generate random numbers due to their procedural nature. Because of this, computers have to use pseudo-random number generation techniques.\par
\funtext{RNG in the real world}{Video games use random numbers to carry out many of their functions, and sometimes, certain random numbers may make the game much more difficult. If you hear the phrase "bad RNG," now you know what that means!}
Random number generation in a computer starts with something called a seed. In a computer, random numbers are generated as the result of a mathematical function, and the seed is the input to that mathematical function that will return a pseudo-random number. Sometimes, seeding by hand is a good thing, because it will ensure that we will get the same "random" number every single time. This is great for testing purposes.\par
However, seeding can also be done by something completely unrelated to the computer. Some programs seed according to insanely small units of time, like nanoseconds. Others seed using arbitrary numeric data, like processor cycles. Yet others seed using external data.\par
\funtext{Lava lamps}{Cloudflare's San Francisco office famously seeds its cryptographic functions using a camera feed of lava lamps. The lava lamps move in random ways, and the camera used to capture the lava lamps has digital noise that cannot be predicted.}
After a seed has been chosen, it needs to be processed. Modern random-number generators are good enough that you can treat the near-randomness of your random number as random. However, older random-number generators were much more primative. One of these methods is called linear congruential generation, or LCG. LCG uses a mathematical function, iterated over multiple times, to create a random number.\par
To use LCG, you need to have four things: a minimum, a maximum, a seed, and the number of iterations.\par
The generator itself is quite a simple machine. Using itself, it creates mathematically related output based off of its own output. The LCG equation is given as

$$
x = (a * x + c) \text{ mod }m
$$

where $a$ is the multiplier, $c$ is the increment amount for each iteration, and $m$ is a modulus, which are all constant values. $x$ is the seed. Every time a new number is needed, the increment amount increases the mutiplier by $c$. Then, to get the number in the right range, we can use

$$
o = \frac{(r_\text{upper} - r_\text{lower}) * ((a * x + c) \text{ mod }m)}{(m - 1) + r_\text{lower}}
$$

to get a number, where $r_\text{upper}$ is the upper range of our possible random numbers, $r_\text{lower}$ is the lower range of our possible random numbers, and $o$ is the random number.\par
This is a very primative pseudo-random number generator. There are only as many intermediate steps from the seed to the pseudo-random number as iterations, and in general, more intermediate steps leads to better random numbers. Because of this, LCGs are rarely used anymore, but their theory of operation make them a useful tool for understanding why we get the random numbers that we do.\par
Thankfully, Python has a simple library that allows us to use a much more sophisticated pseudo-random number generator. Predicably, this library is called \verb|random|. There are three methods inside of \verb|random| that will be of great use to us: \verb|random()|, \verb|randint()|, and \verb|choice()|.\par
Let us start with \verb|random()|. The \verb|random()| method generates pseudo-random floating-point values on a uniform real distribution from 0 to 1. As opposed to the very simple linear congruential generator that we previously used, \verb|random()| uses the Mersenne Twister generator, which is a much more complex and precise generator than the LCG.\par
\funtext{Mersenne Twisters in C}{Python is built on top of C, and it actually uses the C-based Mersenne Twister generator found in \texttt{mt19937} for 32-bit C and \texttt{mt19937\_64} for 64-bit C. It produces a 53-bit precision float and uses a modulus of 2 mod 19937 - 1 (hence C's generator naming).}
To use the \verb|random()| method in Python, we first need to import the \verb|random| library.\par
\begin{lstlisting}[style=pippython]
import random
\end{lstlisting}
Now, we can call the \verb|random()| method to generate a random floating-point number from 0 to 1.\par
\begin{lstlisting}[style=pippython]
print(random.random())
print(random.random())
print(random.random())
\end{lstlisting}
\begin{lstlisting}[style=none]
0.7592076143986661
0.22557165065717144
0.01434871426522899
\end{lstlisting}
More often than not, we will want to generate a random integer. We could use the \verb|random()| method and pull a little bit from the output, but that's a lot of work. So instead, let's use the \verb|randint()| method. The \verb|randint()| method takes two arguments, a minimum and a maximum for the random number.\par
\begin{lstlisting}[style=pippython]
print(random.randint(1, 10))
print(random.randint(1, 10))
print(random.randint(1, 10))
\end{lstlisting}
\begin{lstlisting}[style=none]
3
2
7
\end{lstlisting}
Now, let's suppose that we have a list with two coin sides: heads and tails.\par
\begin{lstlisting}[style=pippython]
coin = ['heads', 'tails']
\end{lstlisting}
If we wanted to generate a coin flip, we could generate a random integer, then get the value of the item at that index list.\par
\begin{lstlisting}[style=pippython]
print(coin[random.randint(0, 1)])
\end{lstlisting}
\begin{lstlisting}[style=none]
heads
\end{lstlisting}
However, since we have a list already, this is the perfect scenario to use the \verb|choice()| method, which picks a pseudo-random choice from a list.\par
\begin{lstlisting}[style=pippython]
print(random.choice(coin))
\end{lstlisting}
\begin{lstlisting}[style=none]
heads
\end{lstlisting}
We mentioned seeds when we were talking about linear congruential generators, and it's not for nought. Every random number generator has a seed. Whether you can see or edit that seed or not doesn't matter - the seed \textit{is} there. Again, it could be seeded from something else (like a video feed of a lava lamp). By default, Python seeds its random numbers from the current system time. Hoewver, Python's \verb|random| library allows us to set a seed manually so that our results can be reproducable. That means that if I set my seed to be \verb|215|, then I generate a random integer, it should be the same as if you set your seed to be \verb|215|, then generated a random integer.\par
In Python, the \verb|random| class has a method that we can use to set a seed manually called \verb|seed()|. Once we set the seed, it is the same for the rest of the environment.\par
\begin{lstlisting}[style=pippython]
random.seed(215)
print(random.randint(1, 100))
\end{lstlisting}
\begin{lstlisting}[style=none]
6
\end{lstlisting}
If your seed was set to the 215, the first random integer that you generate from 1 to 100 should be 6.

\subsubsection*{Exercise Questions}
These exercise questions cover chapter 5.7.
\begin{Exercise}
	\Question{We introduced two methods for generating pseudo-random numbers. What are they?}
	\Question{Which of the two methods does the \verb|random| library utilize in Python?}
\end{Exercise}
\begin{Exercise}
	\Question{What is a pseudo-randomly generated number?}
	\Question{We have been using the term \textit{pseudo-random} throughout this chapter. Why?}
\end{Exercise}
\begin{Exercise}
	\Question{What is a seed?}
	\Question{What is a situation where we might want to set the seed?}
	\Question{If we do not explicitly set a seed, what will Python use as the seed?}
\end{Exercise}
\begin{Exercise}
	\Question{In a new Python script, import the \verb|random| library.}
	\Question{Create a pseudo-random floating point number from 0 to 1 and place the result into a new variable called \verb|randomfloat1|.}
	\Question{Print \verb|randomfloat1|.}
	\Question{Create another pseudo-random floating point number from 0 to 1 and place the result into a new variable called \verb|randomfloat2|.}
	\Question{Print \verb|randomfloat2|.}
	\Question{Sum \verb|randomfloat1| and \verb|randomfloat2| and put the result into a new variable called \verb|randomsum|.}
\end{Exercise}
\begin{Exercise}
	\Question{In a new Python script, import the \verb|random| library.}
	\Question{Create a new pseudo-random integer in the range of 0 to 1000 and place the result into a new variable called \verb|dividend|.}
	\Question{Create another pseudo-random integer in the range of 1 to 100 and place the result into a new variable called \verb|divisor|.}
	\Question{Print the quotient of $dividend \div divisor$.}
	\Question{Print the remainder value of $dividend \div divisor$ as an integer.}
	\Question{Print the quotient of $dividend \div divisor$ without the decimal/remainder portion.}
\end{Exercise}


% This LaTeX was auto-generated from MATLAB code.
% To make changes, update the MATLAB code and republish this document.

\documentclass{article}
\usepackage{graphicx}
\usepackage{color}

\sloppy
\definecolor{lightgray}{gray}{0.5}
\setlength{\parindent}{0pt}

\begin{document}

\subsection*{Contents}

\begin{itemize}
\setlength{\itemsep}{-1ex}
   \item clear workspace variables
   \item Make a vector and plot
   \item Create math in MATLAB publishing
   \item Make bullets
   \item How about a numbered list? Just use \# instead of *
   \item You can do hyperlinks as well
   \item Types of text
\end{itemize}
\begin{verbatim}
% Author: Dylan Mikesell
% Created: 20 September 2016
% Last modified: 21 September 2016
\end{verbatim}

\subsection*{clear workspace variables}

\begin{verbatim}
clear all;
close all;
\end{verbatim}

\subsection*{Make a vector and plot}

\begin{verbatim}
x = linspace(0,2*pi,180/pi);
y = sin(x);

h = figure;
plot(x,y,'k');
\end{verbatim}

\includegraphics [width=4in]{MatlablPublishingExample_01.png}

\subsection*{Create math in MATLAB publishing}

\begin{par}
This is called inline math with a single dollar sign (\$) around the math.
\end{par} \vspace{1em}
\begin{par}
$y = \sin(x)$
\end{par} \vspace{1em}
\begin{par}
This is called display math with two dollar signs (\$\$) around the math.
\end{par} \vspace{1em}
\begin{par}
$$y = \sin(x)$$
\end{par} \vspace{1em}

\subsection*{Make bullets}

\begin{itemize}
\setlength{\itemsep}{-1ex}
   \item This is the first bullet
   \item This is the second bullet
\end{itemize}
\begin{verbatim}
% The trick is the '% *' symbols. Also, make sure there are no empty lines
% betweeen the bullets and the '%% section title' line. Otherwise, the
% bullets are not interpreted as bullets. If you have blank lines, make
% sure to comment those lines. Same goes for the math examples above.
\end{verbatim}

\subsection*{How about a numbered list? Just use \# instead of *}

\begin{enumerate}
\setlength{\itemsep}{-1ex}
   \item ITEM1
   \item ITEM2
\end{enumerate}

\subsection*{You can do hyperlinks as well}

\begin{par}
\begin{verbatim}GEOS397\end{verbatim}
\end{par} \vspace{1em}
\begin{verbatim}
% Note the space in between the URL and the text that will be linked.
\end{verbatim}

\subsection*{Types of text}

\begin{par}
\textbf{You can write in bold.}
\end{par} \vspace{1em}
\begin{par}
\textit{You can write in italic.}
\end{par} \vspace{1em}
\begin{verbatim}
% Note the *a* notation for bold and _a_ for italic.
\end{verbatim}

\end{document}


\chapter{Related Work}
\label{chap:related-work}

Compared to the execution problem, the literature for the order placement problem is sparse (as confirmed by Guo et al. \cite{guo2013optimal}).
In this Chapter, we will provide an overview of the work relied upon for the foundations of this project and for the insights they provided.
We will first consider an empirical study of the general behavior of order placements, which serves as the conceptual basis for this project.
Then, we will present a statistical approach which provides contrast to the subsequent overview of previous machine learning approaches.

\section{Execution/Placement behaviour}
\label{sec:related-execution-behaviour}

Kearns et al. \cite{nevmyvaka2005electronic} determined which limit order price results in the most advantageous execution price.
First, the \textit{expected execution price} is investigated with respect to the placement of the limit order.
Based on this analysis, the standard deviation of the resulting prices will identify the \textit{risk} that comes with limit order placement.
Finally, by combining the previous two results, an \textit{efficient pricing frontier} can be drawn which highlights the trade-off between risk and returns.

Although this research does not optimize the placement of limit orders per se, it provides a method to measure the expected costs for (1) placing orders at certain limit levels or (2) submitting a market order.
Therefore, this approach can serve as a measure to determine how well a method which does attempt to optimize the limit order placement performs.
Regarding the definition stated in Section \ref{sec:execution-placement}, their research can be categorized between order execution and placement.
No splitting of orders was performed, however a time horizon of several hours was chosen, resulting in an evaluation of order placement with an extended time horizon.

\begin{figure}[H]
    \centering
    \makebox[\linewidth]{
        \includegraphics[width=8cm]{kearns-return.png}
    }
    \caption{Taken from \cite{nevmyvaka2005electronic}. An illustration of the pricing strategy that produces the most favorable expected execution price.}
    \label{fig:kearns-return}
\end{figure}

Figure \ref{fig:kearns-return} shows on the y-axis the return as the weighted average price paid of the expected execution price while acquiring 10,000 shares of MSFT within one hour.
The x-axis represents the limit level ranging from -\$50 to +\$100.
As is evident from the figure, the expected execution price is at its most favorable when setting the limit price close to the price of the spread, although only on the buyer side with a price of approximately \$10 lower than what is currently offered.
The return becomes worse when placing orders deeper in the order book (in other words, offering a lower price) as the orders then do not get filled within an hour and instead, the inventory has to be bought by means of a market order at the end of the period.
Likewise, the return can be expected to be lower when placing the order higher in the order book (i.e. deeper in the opposing side of the book, meaning one is willing to pay more).
This is due to the fact that the order is filled instantly by paying a premium.

\begin{figure}[H]
    \centering
    \makebox[\linewidth]{
        \includegraphics[width=8cm]{kearns-std.png}
    }
    \caption{Taken from \cite{nevmyvaka2005electronic}. An illustration of the uncertainty of the expected execution price.}
    \label{fig:kearns-std}
\end{figure}

Risk is defined as the standard deviation of the returns and is illustrated on the y-axis in Figure \ref{fig:kearns-std}.
This is an important aspect to be considered throughout our project as it illustrates the danger that arises from placing limit orders at less favourable limit levels.
As has been already demonstrated, orders which are placed deep in either side of the book are less likely to be executed and their final prices are therefore necessarily less certain.

\begin{figure}[H]
    \centering
    \makebox[\linewidth]{
        \includegraphics[width=8cm]{kearns-frontier.png}
    }
    \caption{Taken from \cite{nevmyvaka2005electronic} An illustration of the trade-off between risk and return indicated by a efficient pricing frontier.}
    \label{fig:kearns-frontier}
\end{figure}

Lastly, both techniques were combined and this resulted in an efficient pricing frontier (based on the \textit{efficient frontier} initially formulated by Harry Markowitz in 1952 \cite{markowitz1952portfolio}).
Figure \ref{fig:kearns-frontier} shows the trade-off between the risk (x-axis) and return (y-axis).
In this example, the point of minimum risk is at $(8, 18)$ and the point of maximum returns at $(29, 9)$.
With this technique, a trader, or in our case a reinforcement learning agent, can decide upon an execution strategy by choosing how much risk and return he is willing to accept.

\section{Statistical approach}
\label{sec:related-statistical}

Substantial work in a statistical context was carried out by Chaiyakorn Yingsaeree in his dissertation \cite{yingsaeree2012algorithmic}.
A framework was proposed for the making of order placement decisions based on the trade-off between the profit gained from favorable execution prices and the risk of non-execution.
An execution probability model was developed which estimates the expected payoff (e.g. return) and its variance ($\implies$ risk) while placing orders at a certain limit level.  This is followed by the application of \textit{mean variance optimization} to balance the trade-off.
The framework was not able to beat the best static strategy in all evaluated cases, however the improvement gained when it could beat the best static strategy was very significant.
This gives us hope that, where the statistical approach has its limitations, with the reinforcement learning approach presented in this work, we may be able to understand the limitations of market data to a greater extent and avoid the shortcomings of the former strategy.
\\
\\
\textit{We are providing here an overview of the framework without specific application, as this would exceed the scope of this overview.}
\\
\\
The strategy is to buy $x$ shares in time $T$, which leaves the trader with the following options:
\begin{enumerate}
    \item Do nothing.
    \item Submit a market order at $t=0$ at price $p_{0}^M$
    \item Submit a market order at $t=T$ at price $p_{T}^M$
    \item Submit limit order at price $p^L$. If the order is not filled, either a market order follows or no action is taken (depending on the use case).
\end{enumerate}
\hfill
\\
A function $U_{E}(p)$ defines the payoff in the event of an execution at price $p$, and a function $U_{NE}(p)$ defines the cost if the order is not executed at the end of the period at market price $p$.
Consequently, the payoff the trader will receive from submitting a limit buy order at price level $L$ is defined as,
\begin{equation}
    U(p^L) = \begin{cases}
                U_E(p), & \text{if order is executed}.\\
                U_{NE}(p_T^M), & \text{if not executed}.
             \end{cases}
\end{equation}
\hfill
\\
The expected price is compounded by a) the probability that the limit order at price $p^L$ will be executed before the end of the period and b) the distribution of the asset price at the end of the period,
\begin{equation}
    \mathbb{E}[U(p^L)] = P_E(p^L)\ U(p^L) + [1-P_E(p^L)] \int_{-\infty}^{\infty} U_{NE}(p) f_{p_M^T | p^L}(p) dp,
\end{equation}
whereas $P_E(p^L)$ is the probability that the limit order at price $p^L$ will be executed before the end of the period, and $f_{p_M^T | p^L}(.)$ is the probability density function of the asset price at the end of the period.
\\
Similarly, the variance was defined as $V[U(p^L)]$, and this was followed by a mean variance optimization step which introduced the utility function,
\begin{equation}
    U_O(p^L) = \mathbb{E}[U(p^L)] - \lambda V[U(p^L)],
\end{equation}
whereas $\lambda$ serves as a risk factor.
That is, when $\lambda=0$ the trader is concerned only about the profit, and when $\lambda=1$ the trader is equally concerned about profit, risk, and missed opportunities.
As a result, the trade-off between profit and risk was defined as,
\begin{equation}
    \hat{p} = \arg\max_{p^L}\ U_O(p^L)
\end{equation}

\section{Supervised Learning approach}
\label{sec:related-supervised}

Fletcher et al. \cite{fletcher2010multiple} investigated order books with the aim of forecasting the movements of bid and ask prices at time $t+\Delta{t}$.
Although this was not directly applied to the optimization of order placement, it was suggested that the resulted predictions can be used as the limit price to be set while placing an order.

SVM classification techniques with different kernels along with two Multiple Kernel Learning (MKL) techniques were used.
The authors' approach is a multi-class setup with three labels, A: $P_{t+\Delta{t}}^{Bid} > P_t^{Ask}$, B: $P_{t+\Delta{t}}^{Ask} < P_t^{Bid}$ and C: $P_{t+\Delta{t}}^{Bid} < P_t^{Ask}, P_{t+\Delta{t}}^{Ask} > P_t^{Bid}$.
The feature used is the volume at time $t$ at each of the price levels of the order book on both sides, is defined as a vector $V_t$.
A set of features was constructed that contains volumes from the current time $t$ and previous time step $t-1$.

With a time delta ($\Delta{t}$) of 100 seconds, an accuracy of 51\% was achieved.
When a shorter time delta was chosen, this resulted in significantly better performance. However, this is mostly due to the fact that the zero movement prediction was accurate.
An increased time delta resulted in significantly worse prediction accuracy.
\\
\\
A supervised learning approach, such as presented in this research, has multiple disadvantages.
First, the model is incentivized based on the accuracy of bid and ask price predictions and therefore does not incorporate the outcome of order placements, at the predicted price levels, during training at all.
Instead, with this setup the process of order placement would be attempted in a subsequent step where the predicted price determines at which price level to place the order.
However, a multi-class setup would only provide knowledge whether to place a limit- or market order and does not specify the exact price level.
Certainly, such an approach can easily be modified in order to become a regression problem where the price is defined specifically.
However, the outcome of the order placement would still not have an impact on the loss function during training.

\section{Reinforcement Learning approach}
\label{sec:related-reinforcement}
A large-scale empirical application of reinforcement learning to optimize trade execution has been presented by Kearns et al. \cite{nevmyvaka2006reinforcement}.
Although the title of their research suggests otherwise, their work is related to order placement with a larger time horizon $H$ (2 minutes and 8 minutes), according to our definition in Section \ref{sec:execution-placement}.
Their research objective is accordingly defined as:
\begin{quote}
    to sell (or buy) V shares of a given stock within a fixed time period (or horizon) H, in a manner that maximizes the revenue received (or minimizes the capital spent).
\end{quote}
They built a reinforcement learning based on 1.5 years of millisecond time-scale limit order data from NASDAQ.
The investigation considered three stocks, AMZN, NVDA, and QCOM; each with an inventory $I$ of 5,000 shares.
The relative improvement over a submit-and-leave strategy ranged from 27.16\% to 35.50\%.
An additional improvement of 12.85\% was achieved by considering the following market variables: Spread, Immediate Cost, and Signed Volume.

The architecture developed is as follows.
\textit{States} are represented by a vector $x \in X$ and correspond to an observation state that has the function of making a  partially observable environment fully observable.
\textit{Actions} ($a \in A$) represent the limit price relative to the current ask price, $ask - a$.
That is, action $a = 0$ is the ask price, $a < 0$ is a limit price deep in the book, and $a > 0$ is a limit order on the opposing side of the book.
The \textit{reward} represent the VWAP (Eq. \ref{eq:vwap}) of the executed order relative to the bid-ask mid price ($\frac{ask + bid}{2}$).
If the order is not filled completely at the end of the time horizon H, then a market order follows.
The chosen \textit{algorithm} is a slightly adapted version of the Q-Learning algorithm that was developed by the authors, and which explores the state space inductively.
Starting from $t=T...0$ the algorithm explores the inventories $i=0...I$.
At each step, all possible actions in this state are evaluated, leading to the most rewarding strategy for $t=0$.
\\
\\
This work demonstrates the suitability of reinforcement learning for the limit order placement problem.
The use of a reward function that involves the outcome of the proceeded placement itself allows to train a model specifically for this task.
In addition, and unlike what was shown in Section \ref{sec:related-supervised}, this architecture does not require a separation of the prediction and placement processes.
Therefore, this research provides foundation for modelling and integrating the limit order placement problem into a reinforcement learning context with the use of a relatively complex environment and a simple agent.
Furthermore, the results show the potential improvements that can be achieved by using market features.


\documentclass[10pt]{beamer}

\usetheme[progressbar=frametitle]{metropolis}
\usepackage{appendixnumberbeamer}

\usepackage{booktabs}
\usepackage[scale=2]{ccicons}

\usepackage{pgfplots}
\usepgfplotslibrary{dateplot}

\usepackage{xspace}
\newcommand{\themename}{\textbf{\textsc{metropolis}}\xspace}

\title{Linear Regression}
\subtitle{A soft introduction}
% \date{\today}
\date{}
\author{Dan Alexandru}
%\institute{FII}
% \titlegraphic{\hfill\includegraphics[height=1.5cm]{logo.pdf}}

\begin{document}

\maketitle

\begin{frame}{Table of contents}
  \setbeamertemplate{section in toc}[sections numbered]
  \tableofcontents[hideallsubsections]
\end{frame}

\section{Introduction}

\begin{frame}{Linear regression}
\begin{columns}[T,onlytextwidth]
    \column{0.6\textwidth}
     \begin{equation*}
        y = X\beta+\varepsilon
      \end{equation*}

        y = response variable (regressand) \\
        X = input vector (regressor) \\
        $\beta$ = \textasciitilde weight (regression coefficient)\\
        $\varepsilon$ = \textasciitilde bias (disturbance or error term / noise)

  \column{0.5\textwidth}
    \begin{center}\includegraphics[scale=0.3]{visualize/linear-example.png}\end{center}
\end{columns}
\end{frame}

\section{Implementation}

\begin{frame}{Sample data}
%url: http://profs.info.uaic.ro/~ciortuz/ML.ex-book/implementation-exercises/ML.ex-book.Companion.pdf - slide 7
%url: http://profs.info.uaic.ro/~ciortuz/ML.ex-book/implementation-exercises/CMU.2009s.ZBJ.HW1.pr4.linRegr.insulin.data.NO-code/data2.txt
 \begin{table}
    \caption{Insulin data (source: CMU, 2009, ZBJ - HW1 pr4)\break
    For ease, weightage will be the indicator for train/test data.}
    \begin{tabular}{lcr}
      \toprule
      bloodsugarlevel & insulindose & weightage\\
      \midrule
      30,000000 & 1335,000026 & 1\\
      31,000000 & 1421,670027 & 1\\
      34,500000 & 1909,320033 & 2\\
      35,250000 & 2007,750035 & 2\\
      \bottomrule
    \end{tabular}
  \end{table}
\end{frame}
\begin{frame}{Visualizing the data}
  \begin{center}\includegraphics[scale=0.5]{visualize/linear-reg01.png}\end{center}
\end{frame}

\begin{frame}{Technologies used}
\begin{columns}[T,onlytextwidth]
    \column{0.33\textwidth}
      \includegraphics[scale=0.3]{assets/python.png}

    \column{0.33\textwidth}

    \column{0.33\textwidth}
     \includegraphics[scale=0.5]{assets/scikit-learn.png}
\end{columns}

\vspace{5mm} %5mm vertical space

\begin{columns}[T,onlytextwidth]
    \column{0.33\textwidth}
      \includegraphics[scale=0.1]{assets/tkinter.png}

    \column{0.66\textwidth}
     \includegraphics[scale=0.35]{assets/matplotlib.png}
\end{columns}
\end{frame}

\begin{frame}{Implementation}
   \huge\begin{center}Demo\end{center}
\end{frame}

\begin{frame}{Visualizing the solution}
  \begin{center}\includegraphics[scale=0.5]{visualize/linear-reg02.png}\end{center}
\end{frame}

\section{Conclusion}

\begin{frame}{Summary}

  Get this presentation and the code from

  \begin{center}\url{github.com/xR86/ml-stuff/tree/master/labs-machine-learning/implementations}\end{center}

  The repo is licensed under a
  \href{https://github.com/xR86/ml-stuff/blob/master/LICENSE}{MIT License}.

  \begin{center}\includegraphics[scale=0.5]{mitlogo.png}\end{center}

\end{frame}

\end{document}


\documentclass[letterpaper]{article}

%\usepackage{fullpage}
%\usepackage{nopageno}
\usepackage{amsmath}
\usepackage{amssymb}
\allowdisplaybreaks

\newcommand{\abs}[1]{\left\lvert #1 \right\rvert}

\begin{document}
\title{Notes}
\date{January 14, 2015}
\maketitle
\section*{graph theory birthday}
leibniz and the geometry of postion (maybe called topology now)

200 years before algebraists, at this time it's all analysis

he says maybe you only care about relations, not distance

\subsection*{next}
mid 18th century, bridges of königsberg.

königsberg has river around it, with bridges throughout. check drawing online

game is to cross every bridge exactly once and return to starting place, enter euler

``very  little relationship to mathematics'' but changes his mind later. then solves every bridge problem ever. 21 paragraphs.

he also solved the optimal number of sails to have on a sailing vessel.

anachronistic to say that he invented graph theory. however the bridges problem is considered the original graph theory problem.

in modern theory/notation each land bit is a point and each bridge is an edge.

\subsection*{definition}
a graph is written $G=G(V,E)$ where $V, E$ are a pair of sets such that $E$ is a subset of $V\times V$ where $E$ can have repetitions.

\subsection*{abstract examples}
$V=\{v_1,v_2,v_3,v_4\}$, $E=\{(v_1,v_2),(v_1,v_2), (v_1,v_1), \dots\}$

\section*{definitions}
\subsection*{simple graph}
a graph is simple if $E$ has no repetitions and excludes $(v_i,v_i)$
\subsection*{multigraph}
a graph that is not simple is called a multigraph

königsberg is an example of this
\subsection*{incident/adjacent}
two vertices $v_i$ and $v_j$ are called incident or adjacent if $(v_i,v_j)$ is in $E$
\subsection*{neighborhood of $v_i$}
if $v_i\in V$ then $N_G(v_i)=\{(v_i,v_j)\in E\}$
\subsection*{order}
$|V(G)|$ is the order of G
\subsection*{size}
$|E(G)|$ is the size of G
\subsection*{path}
a path is a graph like $.\_.\_.\_.$ (a line with discrete points on it. this one is order 4, size 3)

a path on $n$ vertices is denoted $P_n$ but instructor will often call $P_{n-1}=P_n$ because $P_n$ had $P_{n-1}$ edges

\subsection*{trivial graph}
if $|V(G)|$ (order) is one and $|E(G)|$ (size) is zero then we have a trivial graph

this is opposed to not having any vertices or having multiple vertices and no edges

\subsection*{empty}
if $|E(G)|$ size is zero then we have an empty  graph
\subsection*{complete graph}
$E(G)=\{V\times V-(v_i,v_i)\}$ then $G$ is a complete graph
\subsubsection*{example}
$V=\{(v_1,v_2,v_3\}$ with a triangle graph.

the trivial graph is a complete graph

\subsubsection*{notation}
$K_n$ is complete graph  on $n$ vertices.
$K_1$ is a point, $K_2$ is a line, $K_3$ is a triangle, $K_4$ is a square with an x

\subsection*{order of neighborhood}
$|N_G(v_i)|$ is the degree of a vertex (valence)

\section*{theorem}
if $G$ is finite and simple, then
\[\sum\limits_{v_i\in V}{|N_G(v_i)|}=2|E|\]
\subsection*{proof}
adding each degree counts one end of each edge

each two vertices to each edge

\section*{homework}
define: path, cycle, isomorphism, subgraph, regular graph, bipartate graph, complement

numbers: 2,3,4,11,13,18
\end{document}


\section{Discussion}
What could have gone wrong? \\
There are several factors on which this experiment could have gone wrong. First of all the program to generate the data uses the function shuffle() from the random library in Python. This function is used to shuffle the deck of cards. Due to computers cannot generate random numbers and I don't know how the shuffling is done in this function, I cannot know for sure that this function shuffles the deck in a reliable way. If the shuffle is not random, this can result in repetitive decks of cards, which games based on this deck would result in the same results, which could make the win probability turnout higher or lower than they really are. \\
This does not apply tot the randint() function from the same library, which is used for the user decision in drawing or passing. The counters in the refinement proof that this function gave a good 50/50 ratio in draw and pass, this is what it is intended to do.