{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### <p style=\"text-align: right;\"> &#9989; Put your name here</p>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Day 3 Pre-Class Assignment: Python and Pandas Review"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Goals for today's pre-class assignment \n",
    "\n",
    "1. Build a conceptual model of Python code flow and data stuctures using Python Tutor.\n",
    "2. Review Python data structures.\n",
    "2. Review some Pandas\n",
    "\n",
    "### Assignment instructions\n",
    "\n",
    "Watch the videos below, do the readings linked to below the videos, and complete the assigned programming problems.  Please get started early, and come to office hours if you have any questions! You should also use Slack to help each other thought any issues you run into!\n",
    "\n",
    "Recall that to make notebook cells that have Python code in them do something, hold down the 'shift' key and then press the 'enter' key (you'll have to do this to get the YouTube videos to run).  To edit a cell (to add answers, for example) you double-click on the cell, add your text, and then enter it by holding down 'shift' and pressing 'enter'\n",
    "\n",
    "**This assignment is due by 11:59 p.m. the day before class,** and should be uploaded into the \"Pre-class assignments\" dropbox folder for Day 3.  Submission instructions can be found at the end of the notebook."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Imports for the Day\n",
    "\n",
    "One of the downsides of notebooks is knowing when things got imported (also, the sequence of things but more on that later). What we will try to do is make sure that the first code snippet in every notebook are the imports necessary to run the entire notebook. When you restart, run that first cell to get imports right."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "from IPython.display import HTML\n",
    "from IPython.display import YouTubeVideo\n",
    "import pandas as pd\n",
    "import matplotlib.pyplot as plt\n",
    "import numpy as np"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "---\n",
    "## 0: Short survey for CMSE Research Study\n",
    "\n",
    "The Department of CMSE is in the early stages of carrying out research to understand how students interact with, digest, and ultimately learn computationally-driven content. As part of this effort, a survey aimed at understanding how you feel about your ability to accomplish a variety of programming-related tasks is included below. You participation in this survey is completely voluntary and the results will have _absolutely no impact_ on your final grade in this course. Furthemore, your responses will be kept completely confidential. Even your instructors will not be able to identify your individual reponses.\n",
    "\n",
    "Your participation will help to improve future iterations of our CMSE courses!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "<iframe \n",
       "\tsrc=\"https://forms.office.com/Pages/ResponsePage.aspx?id=lbSJs3uPL06VcR7QODNwghG_O665RWtGtjPQLrtCQLdUNjNUNVBPMEZXN05aNkk1S1BGQjJVTkVGSC4u\" \n",
       "\twidth=\"800px\" \n",
       "\theight=\"600px\" \n",
       "\tframeborder=\"0\" \n",
       "\tmarginheight=\"0\" \n",
       "\tmarginwidth=\"0\">\n",
       "\tLoading...\n",
       "</iframe>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "HTML(\n",
    "\"\"\"\n",
    "<iframe \n",
    "\tsrc=\"https://forms.office.com/Pages/ResponsePage.aspx?id=lbSJs3uPL06VcR7QODNwghG_O665RWtGtjPQLrtCQLdUNjNUNVBPMEZXN05aNkk1S1BGQjJVTkVGSC4u\" \n",
    "\twidth=\"800px\" \n",
    "\theight=\"600px\" \n",
    "\tframeborder=\"0\" \n",
    "\tmarginheight=\"0\" \n",
    "\tmarginwidth=\"0\">\n",
    "\tLoading...\n",
    "</iframe>\n",
    "\"\"\"\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "---\n",
    "## 1. Building a conceptual model  Using [Python Tutor](http://www.pythontutor.com/)\n",
    "This section introduces a learning tool called [Python Tutor](http://www.pythontutor.com/).  This is a web-based tool you can use to help figure out how the python interpreter maintains the state of variables and modules.  I recommend using this tool anytime you are confused about what is going on inside of python. Please watch the following video for an example about using Python Tutor.\n",
    "\n",
    "If you have trouble with the YouTube version, you watch [this video on MSU MediaSpace](https://mediaspace.msu.edu/media/0_ypt5chfx)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/jpeg": "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\n",
      "text/html": [
       "\n",
       "        <iframe\n",
       "            width=\"640\"\n",
       "            height=\"360\"\n",
       "            src=\"https://www.youtube.com/embed/1OQ_E1y73Es\"\n",
       "            frameborder=\"0\"\n",
       "            allowfullscreen\n",
       "        ></iframe>\n",
       "        "
      ],
      "text/plain": [
       "<IPython.lib.display.YouTubeVideo at 0x7fa6e12fff50>"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "YouTubeVideo(\"1OQ_E1y73Es\",width=640,height=360)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Watch the above video and answer the following questions:"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Question 1:**  In words, describe how python tutor represents the following two dimensional list:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "l = [ [('me','you'), 20, 30], [4, 5, 6], ['a','b','c']]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<font size=8 color=\"#009600\">&#9998;</font> Do This - Erase the contents of this cell and replace it with your answer to the above question!  (double-click on this text to edit this cell, and hit shift+enter to save the text). Please use appropriate Markup formating to make your answer's easy to read."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Question 2:**  Play with Python Tutor to see what else you can visualize.  Write an interesting example. Either an example that demonstrates something you didn't fully understand or an example that describe a limitation of the tool."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "#Do This - Ease the contents of this code cell and put your example code here\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "###ANSWER (Just one possible answer)\n",
    "import numpy as numpy\n",
    "#numpy not supported -- Python Tutor can't handle this module\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Question 3:**  Describe what you learned or what you found interesting in your answer to Question 2. "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<font size=8 color=\"#009600\">&#9998;</font> Do This - Erase the contents of this cell and replace it with your answer to the above question!  (double-click on this text to edit this cell, and hit shift+enter to save the text). Please use appropriate Markup formating to make your answer's easy to read."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "----\n",
    "\n",
    "# 2. Review of Python Containers (lists, sets, dictionaries, tuples)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/jpeg": "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\n",
      "text/html": [
       "\n",
       "        <iframe\n",
       "            width=\"640\"\n",
       "            height=\"360\"\n",
       "            src=\"https://www.youtube.com/embed/aBqTgR-gP3g\"\n",
       "            frameborder=\"0\"\n",
       "            allowfullscreen\n",
       "        ></iframe>\n",
       "        "
      ],
      "text/plain": [
       "<IPython.lib.display.YouTubeVideo at 0x7fa6e1348410>"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "YouTubeVideo(\"aBqTgR-gP3g\",width=640,height=360)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The cell below includes a reproduction of the table from the video. **Note**: If you're using \"JupyterLab\" instead of the standard Jupyter Notebook interface, you may find that this table runs off the edge of your browser window. If this happens, you are encouraged to open it as a standard Jupyter Notebook to end up with a version of the table that will scroll left-to-right."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "|Container Type|Mutable or Immutable|Initialization *Without* Values|Initializtion *With* Values|Adding Values to Container|Removing Values from Container|Modifying Values|Access Method|Notable Operations and Additional Information|\n",
    "|:---------------|:---------------|:---------------|:---------------|:---------------|:---------------|:---------------|:---------------|:---------------|\n",
    "|**List**| Mutable |<ul><li>`a=list()` </li><li> `a=[]` </li></ul> | `a=['1', '2', '3']`|  <ul><li>` list.append(item) #Adds item to the end of the list` </li><li> ` list.insert(index, item) #Adds item to the specified index in the list`</li></ul>|`list.remove(item) #removes the first instance of 'item' from the list. If there is not such element, this will cause an error`|`>>> a[0] = 'cat'` <br> `>>> a` <br> `['cat', '2', '3']` |Access by index: <br> `>>> a[0]` <br> `1`|See webpage at http://www.linuxtopia.org/online_books/programming_books/python_programming/python_ch14s07.html for some helpful methods when dealing with lists.|\n",
    "|**Dictionary**|Mutable| `student={}` | `>>> student={'name': 'John Doe', 'age': 22, 'college': 'MSU'}` | `>>> student['major']='Computer Science'` <br> `>>> student` <br> `{'name': 'John Doe', 'age': 22, 'college': 'MSU', 'major': 'Computer Science'}` | `del dictName[keyName] #This method removes all entries associated with the given key` | `>>> student['age'] = 23` <br> `>>> student` <br> `{'name': 'John Doe', 'age': 23, 'college': 'MSU', 'major': 'Computer Science'}`| Access by key word. Note that this key **must** be a string. <br> `>>>student['college']` <br> `MSU`| The 'in' keyword can be very helpful with dictionaries. Ex: <br><ul><li>`'k' in dict #Returns true if key 'k' is in dictionary dict`</li><li>`'k' not in dict #Returns true if key 'k' is not in dicitonary dict`</li><li>`for key in dict #This will iterate over all keys in dictionary dict`</li></ul> <br>See webpage at http://www.python-course.eu/python3_dictionaries.php for additional helpful methods and operations|\n",
    "|**Set**|Mutable. However the objects contained within a set **must** be immutable. | `s=set()`|`s=set(['a','b','c'])` | `s.add(item)`|<ul><li> `set.discard(item) #If item is in the set, the item is removed, otherwise nothing happens` </li><li> `set.remove(item) #If item is in the set, the item is removed, otherwise raise a KeyError` </li><li> `set.pop() #Remove and return an arbitrary element from the set. If the set is empty, raise a KeyError` </li>| Sets are unordered, therefore indexing does not mean anything. To modify a set, you must directly add or remove elements. |`>>> set.pop() #This will remove and return an arbitrary element from the set`|Some helpful methods include:<ul><li>`difference()`</li><li>`intersection()`</li><li>`isdisjoint()`</li><li>`union()`</li></ul><br> See webpage at http://www.programiz.com/python-programming/set for additional helpful methods and operations|\n",
    "| **Tuple** |Immutable|<ul><li>`t=()`</li><li> `t=tuple()`</li><ul>|<ul><li>1-tuple:<br>`t=('Hello',)`</li><li> 2-tuple:<br> `t=('Hello', 'Goodbye')`</li><ul>|N/A|N/A|N/A|`t=('Hello','Goodbye','Goodnight')`<ul><li>Access By Index: <br> `>>> t[0]` <br> `'Hello'` </li><br><li> Access By Slice <br> `>>>t[0:1:2]` <br> `('Hello','Goodbye')`</li></ul>|<ul><li>Packing and Unpacking</li><br><li>Tuple to List: `list(tupleName)`</li></ul>|\n",
    "| **NumPy Array\\***|Mutable|`a=np.array([])`| `a=np.array([1,2,3,4,5])` | <ul><li>`np.insert(arrayName,index,values,axis) #Inserts a value for an array at the given index.` </li><li>`np.append(arrayName,value,axis) #Appends values to the end of an array.`</li></ul>|`np.array(array,index/indices,axis) #Returns a new array with the given index or array of indices deleted on the given axis`|`>>> a[4] = 12` <br> `array([ 1,  2,  3,  4, 12])` <br><br> For additional information on manipulating NumPy Arrays see the webpage at http://docs.scipy.org/doc/numpy/reference/routines.array-manipulation.html |<ul><li>Access By Index: <br> `>>> a[0] `<br>` 1 `</li><li>Access By Slice: <br> `>>> a[0:5:2] `<br> `array([1, 3, 5])` </li></ul><br>See webpage at http://docs.scipy.org/doc/numpy/reference/arrays.indexing.html for further information about indexing of NumPy Arrays|See webpages at http://www.scipy-lectures.org/intro/numpy/array_object.html and https://docs.scipy.org/doc/numpy-dev/user/quickstart.html for additional information on NumPy Arrays|\n",
    "    \n",
    "\\*Use of the NumPy Array requires the NumPy Python Module. In these examples, it is assumed that the import statement is \"import numpy as np\"\n",
    "\n",
    "---"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Question 4:** What is the difference between mutable and immutable objects?  Give an example of a scientific model where you would choose one over the other (ex. maybe a tuple vs. a list). Explain the choice. "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<font size=8 color=\"#009600\">&#9998;</font> Do This - Erase the contents of this cell and replace it with your answer to the above question!  (double-click on this text to edit this cell, and hit shift+enter to save the text). Please use appropriate Markup formating to make your answer's easy to read."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Question 5:** Imagine a function that takes filename as a string input and counts the number of times each word appears in the file.  What type of container would make the most sense for storing the words and the word counts?  Why?"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<font size=8 color=\"#009600\">&#9998;</font> Do This - Erase the contents of this cell and replace it with your answer to the above question!  (double-click on this text to edit this cell, and hit shift+enter to save the text). Please use appropriate Markup formating to make your answer's easy to read."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Question 6:**  A digital image is often represented as a three dimensional array.  Where the first dimension is row, the second dimension is column and the third dimension is a color.  Create a three dimensional containers of numbers with 10 rows, 10 columns and 3 colors (red, green and blue) and initialize all of the numbers to zero.  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "#Do This - put your code here to generate a 3D container.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "###ANSWER \n",
    "import numpy as np\n",
    "n = np.zeros((10,10,3))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "----\n",
    "\n",
    "## 3. The basics of  Pandas\n",
    "\n",
    "Pandas is probably the fundamental tool we are going to use to do Data Science work. While we can do this work in straight Python, Pandas makes much of that work easier. We cannot do justice to all of Pandas, it is a big package, but we need to remind ourselves of some of the basics. We'll pick more and more of Pandas as we go along. \n",
    "\n",
    "What follows should mostly be review. Feel free to reach out and find tutorial pages that might help with reminding you of how Pandas works. In face, we'll ask some questions at the end as to your favorite tutorial pages."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3.1 Pandas Series\n",
    "\n",
    "The basic Pandas data structure is called a *Series*. It is a sequence, not unlike a numpy array, but with an associated set of labels for each value called the *index*. If you don't provide the index labels, Pandas will use the regular 0-based index as the label. Let me repeat that, it will use the numeric index as the index label. That will be important later.\n",
    "\n",
    "You can make a Series using either a python *dict*, with keys as the indicies, or by separately providing the values and indicies. You can also updated the index labels or reset the labels to the default. Note however that the `reset_index` method does *not* change the Series but returns, not a Series but a DataFrame, where the original index is preserved as a new column."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Series with indicies\n",
      "Type: <class 'pandas.core.series.Series'>\n",
      "one      1\n",
      "two      2\n",
      "three    3\n",
      "four     4\n",
      "dtype: int64\n",
      "\n",
      "Series with default indices\n",
      "Type: <class 'pandas.core.series.Series'>\n",
      "0    5\n",
      "1    6\n",
      "2    7\n",
      "3    8\n",
      "dtype: int64\n",
      "\n",
      "Series from a dictionary\n",
      "nine       9\n",
      "ten       10\n",
      "eleven    11\n",
      "twelve    12\n",
      "dtype: int64\n"
     ]
    }
   ],
   "source": [
    "# assumes you have imported Pandas as pd in the cell at the top of this page\n",
    "series_index = pd.Series([1,2,3,4], index=['one', 'two', 'three', 'four'])\n",
    "print(\"\\nSeries with indicies\")\n",
    "print(\"Type:\", type(series_index))\n",
    "print(series_index)\n",
    "\n",
    "series_noindex = pd.Series([5,6,7,8])\n",
    "print(\"\\nSeries with default indices\")\n",
    "print(\"Type:\", type(series_noindex))\n",
    "print(series_noindex)\n",
    "\n",
    "my_dict = { 'nine': 9, 'ten':10, 'eleven':11, 'twelve':12 }\n",
    "series_dict = pd.Series(my_dict)\n",
    "print(\"\\nSeries from a dictionary\")\n",
    "print(series_dict)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3.2 Manipulating Series\n",
    "\n",
    "You can access the values in a number of ways:\n",
    "* using the label in [ ], much as you would in a dictionary\n",
    "* using data member dot access if the label name would constitute a valid Python variable name (can't start with a digit for example\n",
    "* using numpy array indexing\n",
    "\n",
    "Without a label (using default indicies) you are restricted to using only the last approach"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "3\n",
      "3\n",
      "3\n",
      "7\n"
     ]
    }
   ],
   "source": [
    "#using label\n",
    "print(series_index[\"three\"])\n",
    "\n",
    "#using data member access\n",
    "print(series_index.three)\n",
    "\n",
    "#using array index, 0-based\n",
    "print(series_index[2])\n",
    "\n",
    "# no labels\n",
    "print(series_noindex[2])\n",
    "# series_noindex.2   # can't, 2 isn't a valid Python variable name"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**You** can assign a value to any of the locations you can view"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "nine        9\n",
      "ten        10\n",
      "eleven    111\n",
      "twelve    122\n",
      "dtype: int64\n"
     ]
    }
   ],
   "source": [
    "series_dict[\"eleven\"] = 111\n",
    "series_dict.twelve = 122\n",
    "print(series_dict)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3.3 Numpy like operations\n",
    "You can do many of the things you learned to do in numpy with a pandas Series. For example, you can work with ranges of the series elements. The labels are ordered and so the following works:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "two      2\n",
      "three    3\n",
      "four     4\n",
      "dtype: int64\n"
     ]
    }
   ],
   "source": [
    "print(series_index[\"two\":])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**You** can also apply Booleans to a Series"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "nine     9\n",
      "ten     10\n",
      "dtype: int64\n"
     ]
    }
   ],
   "source": [
    "print(series_dict[series_dict <= 10])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Perform Operations** which return a new series (but don't modify the existing one)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "nine       18\n",
      "ten        20\n",
      "eleven    222\n",
      "twelve    244\n",
      "dtype: int64\n",
      "63.0\n"
     ]
    }
   ],
   "source": [
    "print(series_dict * 2)\n",
    "print(series_dict.mean() )"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Lots of** operations, when I looked over 200, you can perform on a Series. We'll pick up more as we go."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "----\n",
    "\n",
    "## 4 Dataframes\n",
    "\n",
    "A pandas DataFrame is a 2 dimensional data structure. The easiest way to think of a DataFrame is a group of Series where each Series represents a column in the 2D structure. As with Series you can make them a number of ways but the standard way is to use a dictionary where the keys are the column *headers* and the values are a list of values under that header.\n",
    "\n",
    "<img src=\"df.png\" width=\"300\">\n",
    "\n",
    "It is always important to know the **types** in each column as that can affect the kinds of operations you can perform on a column. Listing the `.dtypes` provides such a list. A type of `object` is likely (though not necessarily) a string.\n",
    "\n",
    "An index for the rows is provided by default using 0-based array indexing. The use of `[]` label indexing returns a `Series` which is a column with that heading name. The index of the entire DataFrame is used for the returned Series."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'pandas.core.frame.DataFrame'>\n",
      "    name  age  weight complaint\n",
      "0  james   10     150    sprain\n",
      "1    jim   20     140       cut\n",
      "2   joan   30     130  headache\n",
      "3   jill   40     120     break\n",
      "\n",
      " Column types\n",
      "name         object\n",
      "age           int64\n",
      "weight        int64\n",
      "complaint    object\n",
      "dtype: object\n",
      "\n",
      " age column\n",
      "0    10\n",
      "1    20\n",
      "2    30\n",
      "3    40\n",
      "Name: age, dtype: int64\n",
      "<class 'pandas.core.series.Series'>\n"
     ]
    }
   ],
   "source": [
    "patient_dict = {\"name\":[\"james\",\"jim\",\"joan\",\"jill\"],\n",
    "                 \"age\":[10, 20, 30, 40],\n",
    "                 \"weight\":[150, 140, 130, 120],\n",
    "                 \"complaint\": [\"sprain\", \"cut\", \"headache\", \"break\"]}\n",
    "patient_df = pd.DataFrame(patient_dict)\n",
    "\n",
    "print(type(patient_df))\n",
    "print(patient_df)\n",
    "\n",
    "print(\"\\n Column types\")\n",
    "print(patient_df.dtypes)\n",
    "\n",
    "print(\"\\n age column\")\n",
    "age = patient_df[\"age\"]\n",
    "print(age)\n",
    "print(type(age))\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 4.1 Data Frame indexing\n",
    "\n",
    "As we noted above, the index for a DataFrame by default is a 0-based array index. However, we can choose to use a different column as an index for the DataFrame. The `.set_index()` method allows us to set the index.\n",
    "\n",
    "An **irritating** issue is whether the Series being worked on changes. Typically it does not but most methods provide a `inplace = True` setting to apply the changes to the existing element. Otherwise you must assign the result to preserve it.\n",
    "\n",
    "If you do not so indicate, the column being used as an index is no longer available using standard indexing. If you provide `drop = False` in set_index, the column is preserved in the DataFrame as well as in the index. If you `.reset_index()` returns to 0-based indexing\n",
    "\n",
    "To access a row, you can use either `.loc` or `.iloc`\n",
    "* `.loc` uses the row index **label** to access the row (or the 0-based index of none is provided). It returns a Series\n",
    "* `.iloc` uses the 0-based index regardless of whether a label exists. It too returns a Series\n",
    "\n",
    "Indicies and headers are preserved in the Series indexed from a DataFrame"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Age is now the index\n",
      "      name  weight complaint\n",
      "age                         \n",
      "10   james     150    sprain\n",
      "20     jim     140       cut\n",
      "30    joan     130  headache\n",
      "40    jill     120     break\n",
      "\n",
      "Back to 0-based indexing\n",
      "   age   name  weight complaint\n",
      "0   10  james     150    sprain\n",
      "1   20    jim     140       cut\n",
      "2   30   joan     130  headache\n",
      "3   40   jill     120     break\n",
      "\n",
      "Don't change the original\n",
      "   age   name  weight complaint\n",
      "0   10  james     150    sprain\n",
      "1   20    jim     140       cut\n",
      "2   30   joan     130  headache\n",
      "3   40   jill     120     break\n",
      "\n",
      "Index by age, keep the age column\n",
      "     age   name  weight complaint\n",
      "age                              \n",
      "10    10  james     150    sprain\n",
      "20    20    jim     140       cut\n",
      "30    30   joan     130  headache\n",
      "40    40   jill     120     break\n"
     ]
    }
   ],
   "source": [
    "patient_df.set_index(\"age\", inplace=True)\n",
    "print(\"\\nAge is now the index\")\n",
    "print(patient_df)\n",
    "\n",
    "# reset to 0-based\n",
    "patient_df.reset_index(inplace=True)\n",
    "print(\"\\nBack to 0-based indexing\")\n",
    "print(patient_df)\n",
    "\n",
    "# keep age as a column\n",
    "new_df = patient_df.set_index(\"age\", drop=False)\n",
    "print(\"\\nDon't change the original\")\n",
    "print(patient_df)\n",
    "print(\"\\nIndex by age, keep the age column\")\n",
    "print(new_df)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 4.2 Try it yourself\n",
    "\n",
    "Try doing the following:\n",
    "* make a DataFrame for grades. Headers are Name, Pid, Total Percent, Grade. Make up some names and values\n",
    "* set the index to be the Pid\n",
    "* print every student who got a 3.0 or greater"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "----\n",
    "\n",
    "# 5. Assignment wrap-up\n",
    "\n",
    "Hopefully you were able to get through all of that. We'll be trouble-shooting any issues you had\n",
    "\n",
    "**You must completely fill this out in order to receive credit for the assignment!**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "<iframe \n",
       "\tsrc=\"https://cmse.msu.edu/cmse202-pc-survey\" \n",
       "\twidth=\"800px\" \n",
       "\theight=\"600px\" \n",
       "\tframeborder=\"0\" \n",
       "\tmarginheight=\"0\" \n",
       "\tmarginwidth=\"0\">\n",
       "\tLoading...\n",
       "</iframe>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from IPython.display import HTML\n",
    "HTML(\n",
    "\"\"\"\n",
    "<iframe \n",
    "\tsrc=\"https://cmse.msu.edu/cmse202-pc-survey\" \n",
    "\twidth=\"800px\" \n",
    "\theight=\"600px\" \n",
    "\tframeborder=\"0\" \n",
    "\tmarginheight=\"0\" \n",
    "\tmarginwidth=\"0\">\n",
    "\tLoading...\n",
    "</iframe>\n",
    "\"\"\"\n",
    ")\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "---------\n",
    "### Congratulations, you're done with your pre-class assignment!\n",
    "\n",
    "Now, you just need to submit this assignment by uploading it to the course <a href=\"https://d2l.msu.edu/\">Desire2Learn</a> web page for Day 3's pre-class submission folder (Don't forget to add your name in the first cell)."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "&#169; Copyright,  Michigan State University Board of Trustees"
   ]
  }
 ],
 "metadata": {
  "anaconda-cloud": {},
  "kernelspec": {
   "display_name": "Python 3 CMSE",
   "language": "python",
   "name": "python3cmse"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.9"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
