From dd1632af4bf264336c6a60e0b6d65faff185ee12 Mon Sep 17 00:00:00 2001 From: msyamkumar <msyamkumar@wisc.edu> Date: Wed, 16 Nov 2022 09:22:07 -0600 Subject: [PATCH] New lec 29 notebooks --- .../lec_28_pandas2-checkpoint.ipynb | 5626 ----------------- .../lec_28_pandas2_template-checkpoint.ipynb | 1208 ---- .../demo_lec_28-checkpoint.ipynb | 1038 --- .../demo_lec_28_template-checkpoint.ipynb | 1151 ---- .../lec_29_web1-checkpoint.ipynb | 3255 ---------- .../lec_29_web1_template-checkpoint.ipynb | 767 --- .../pandas1-checkpoint.ipynb | 1736 ----- .../pandas_1_worksheet-checkpoint.ipynb | 2042 ------ f22/meena_lec_notes/lec-29/lec_29_web1.ipynb | 2124 ++----- .../lec-29/lec_29_web1_template.ipynb | 284 +- f22/meena_lec_notes/lec-29/my_course_data.csv | 18 - 11 files changed, 705 insertions(+), 18544 deletions(-) delete mode 100644 f22/meena_lec_notes/lec-28/.ipynb_checkpoints/lec_28_pandas2-checkpoint.ipynb delete mode 100644 f22/meena_lec_notes/lec-28/.ipynb_checkpoints/lec_28_pandas2_template-checkpoint.ipynb delete mode 100644 f22/meena_lec_notes/lec-29/.ipynb_checkpoints/demo_lec_28-checkpoint.ipynb delete mode 100644 f22/meena_lec_notes/lec-29/.ipynb_checkpoints/demo_lec_28_template-checkpoint.ipynb delete mode 100644 f22/meena_lec_notes/lec-29/.ipynb_checkpoints/lec_29_web1-checkpoint.ipynb delete mode 100644 f22/meena_lec_notes/lec-29/.ipynb_checkpoints/lec_29_web1_template-checkpoint.ipynb delete mode 100644 f22/meena_lec_notes/lec-29/.ipynb_checkpoints/pandas1-checkpoint.ipynb delete mode 100644 f22/meena_lec_notes/lec-29/.ipynb_checkpoints/pandas_1_worksheet-checkpoint.ipynb delete mode 100644 f22/meena_lec_notes/lec-29/my_course_data.csv diff --git a/f22/meena_lec_notes/lec-28/.ipynb_checkpoints/lec_28_pandas2-checkpoint.ipynb b/f22/meena_lec_notes/lec-28/.ipynb_checkpoints/lec_28_pandas2-checkpoint.ipynb deleted file mode 100644 index df2d96e..0000000 --- a/f22/meena_lec_notes/lec-28/.ipynb_checkpoints/lec_28_pandas2-checkpoint.ipynb +++ /dev/null @@ -1,5626 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [], - "source": [ - "import pandas as pd\n", - "from pandas import Series, DataFrame\n", - "# We can explictly import Series and DataFrame, why might we do this?" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Series Review\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Series from `list`" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "0 54\n", - "1 22\n", - "2 19\n", - "3 73\n", - "4 80\n", - "dtype: int64" - ] - }, - "execution_count": 2, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "scores_list = [54, 22, 19, 73, 80]\n", - "scores_series = Series(scores_list)\n", - "scores_series\n", - "\n", - "# What is the terminology for: 0, 1, 2, ... ?? A: index\n", - "# What is the terminology for: 54, 22, 19, .... ?? A: value" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Selecting certain scores.\n", - "What are all the scores `> 50`?" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "0 True\n", - "1 False\n", - "2 False\n", - "3 True\n", - "4 True\n", - "dtype: bool" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "scores_series > 50" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Answer:** Boolean indexing. Try the following..." - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "0 54\n", - "1 22\n", - "4 80\n", - "dtype: int64" - ] - }, - "execution_count": 4, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "scores_series[[True, True, False, False, True]] # often called a \"mask\"" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We are really writing a \"mask\" for our data." - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "0 54\n", - "3 73\n", - "4 80\n", - "dtype: int64" - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "scores_series[scores_series > 50]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Series from `dict`" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Rita 5\n", - "Therese 3\n", - "Janice 6\n", - "dtype: int64\n", - "Rita 3\n", - "Therese 7\n", - "Janice 4\n", - "dtype: int64\n", - "Therese 5\n", - "Janice 5\n", - "Rita 8\n", - "dtype: int64\n" - ] - } - ], - "source": [ - "# Imagine we hire students and track their weekly hours\n", - "week1 = Series({\"Rita\": 5, \"Therese\": 3, \"Janice\": 6})\n", - "week2 = Series({\"Rita\": 3, \"Therese\": 7, \"Janice\": 4})\n", - "week3 = Series({\"Therese\": 5, \"Janice\": 5, \"Rita\": 8}) # Wrong order! Will this matter?\n", - "print(week1)\n", - "print(week2)\n", - "print(week3)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### For everyone in Week 1, add 3 to their hours " - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "Rita 8\n", - "Therese 6\n", - "Janice 9\n", - "dtype: int64" - ] - }, - "execution_count": 7, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "week1 = week1 + 3\n", - "week1" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Total up everyone's hours" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "Janice 18\n", - "Rita 19\n", - "Therese 18\n", - "dtype: int64" - ] - }, - "execution_count": 8, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "total_hours = week1 + week2 + week3\n", - "total_hours" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### What is week1 / week3 ?" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "Janice 1.8\n", - "Rita 1.0\n", - "Therese 1.2\n", - "dtype: float64" - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "week1 / week3\n", - "# Notice that we didn't have to worry about the order of indices" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### What type of values are stored in week1 > week2?" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Rita 8\n", - "Therese 6\n", - "Janice 9\n", - "dtype: int64\n", - "Rita 3\n", - "Therese 7\n", - "Janice 4\n", - "dtype: int64\n" - ] - }, - { - "data": { - "text/plain": [ - "Rita True\n", - "Therese False\n", - "Janice True\n", - "dtype: bool" - ] - }, - "execution_count": 10, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "print(week1)\n", - "print(week2)\n", - "week1 > week2 \n", - "# Notice that indices are ordered the same" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### What is week1 > week3?" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Rita 8\n", - "Therese 6\n", - "Janice 9\n", - "dtype: int64\n", - "Therese 5\n", - "Janice 5\n", - "Rita 8\n", - "dtype: int64\n" - ] - }, - { - "data": { - "text/plain": [ - "Janice True\n", - "Rita False\n", - "Therese True\n", - "dtype: bool" - ] - }, - "execution_count": 11, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "print(week1)\n", - "print(week3)\n", - "# week1 > week3 # Does not work (ValueError) because indices are not in same order\n", - "\n", - "# How can we fix this?\n", - "week1.sort_index() > week3.sort_index()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "\n", - "# Lecture 28: Pandas 2 - DataFrames\n", - "\n", - "\n", - "Learning Objectives:\n", - "- Create a DataFrame from \n", - " - a dictionary of Series, lists, or dicts\n", - " - a list of Series, lists, dicts\n", - "- Select a column, row, cell, or rectangular region of a DataFrame\n", - "- Convert CSV files into DataFrames and DataFrames into CSV Files\n", - "- Access the head or tail of a DataFrame" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Big Idea**: Data Frames store 2-dimensional data in tables! It is a collection of Series." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## You can create a DataFrame in a variety of ways!\n", - "\n", - "- dictionary of Series\n", - "- dictionary of lists\n", - "- dictionary of dictionaries\n", - "- list of dictionarines\n", - "- list of lists\n", - "\n", - "### From a dictionary of Series" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "<div>\n", - "<style scoped>\n", - " .dataframe tbody tr th:only-of-type {\n", - " vertical-align: middle;\n", - " }\n", - "\n", - " .dataframe tbody tr th {\n", - " vertical-align: top;\n", - " }\n", - "\n", - " .dataframe thead th {\n", - " text-align: right;\n", - " }\n", - "</style>\n", - "<table border=\"1\" class=\"dataframe\">\n", - " <thead>\n", - " <tr style=\"text-align: right;\">\n", - " <th></th>\n", - " <th>Player name</th>\n", - " <th>Score</th>\n", - " </tr>\n", - " </thead>\n", - " <tbody>\n", - " <tr>\n", - " <th>0</th>\n", - " <td>Alice</td>\n", - " <td>6</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1</th>\n", - " <td>Bob</td>\n", - " <td>7</td>\n", - " </tr>\n", - " <tr>\n", - " <th>2</th>\n", - " <td>Cindy</td>\n", - " <td>8</td>\n", - " </tr>\n", - " <tr>\n", - " <th>3</th>\n", - " <td>Dan</td>\n", - " <td>9</td>\n", - " </tr>\n", - " </tbody>\n", - "</table>\n", - "</div>" - ], - "text/plain": [ - " Player name Score\n", - "0 Alice 6\n", - "1 Bob 7\n", - "2 Cindy 8\n", - "3 Dan 9" - ] - }, - "execution_count": 12, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "names = Series([\"Alice\", \"Bob\", \"Cindy\", \"Dan\"])\n", - "scores = Series([6, 7, 8, 9])\n", - "\n", - "# to make a dictionary of Series, need to write column names for the keys\n", - "DataFrame({\n", - " \"Player name\": names,\n", - " \"Score\": scores\n", - "})" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### From a dictionary of lists" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "<div>\n", - "<style scoped>\n", - " .dataframe tbody tr th:only-of-type {\n", - " vertical-align: middle;\n", - " }\n", - "\n", - " .dataframe tbody tr th {\n", - " vertical-align: top;\n", - " }\n", - "\n", - " .dataframe thead th {\n", - " text-align: right;\n", - " }\n", - "</style>\n", - "<table border=\"1\" class=\"dataframe\">\n", - " <thead>\n", - " <tr style=\"text-align: right;\">\n", - " <th></th>\n", - " <th>Player name</th>\n", - " <th>Score</th>\n", - " </tr>\n", - " </thead>\n", - " <tbody>\n", - " <tr>\n", - " <th>0</th>\n", - " <td>Alice</td>\n", - " <td>6</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1</th>\n", - " <td>Bob</td>\n", - " <td>7</td>\n", - " </tr>\n", - " <tr>\n", - " <th>2</th>\n", - " <td>Cindy</td>\n", - " <td>8</td>\n", - " </tr>\n", - " <tr>\n", - " <th>3</th>\n", - " <td>Dan</td>\n", - " <td>9</td>\n", - " </tr>\n", - " </tbody>\n", - "</table>\n", - "</div>" - ], - "text/plain": [ - " Player name Score\n", - "0 Alice 6\n", - "1 Bob 7\n", - "2 Cindy 8\n", - "3 Dan 9" - ] - }, - "execution_count": 13, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "name_list = [\"Alice\", \"Bob\", \"Cindy\", \"Dan\"]\n", - "score_list = [6, 7, 8, 9]\n", - "\n", - "# this is the same as above, reminding us that Series act like lists\n", - "DataFrame({\n", - " \"Player name\": name_list,\n", - " \"Score\": score_list\n", - "})" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### From a dictionary of dictionaries\n", - "We need to make up keys to match the things in each column" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "<div>\n", - "<style scoped>\n", - " .dataframe tbody tr th:only-of-type {\n", - " vertical-align: middle;\n", - " }\n", - "\n", - " .dataframe tbody tr th {\n", - " vertical-align: top;\n", - " }\n", - "\n", - " .dataframe thead th {\n", - " text-align: right;\n", - " }\n", - "</style>\n", - "<table border=\"1\" class=\"dataframe\">\n", - " <thead>\n", - " <tr style=\"text-align: right;\">\n", - " <th></th>\n", - " <th>Player name</th>\n", - " <th>Score</th>\n", - " </tr>\n", - " </thead>\n", - " <tbody>\n", - " <tr>\n", - " <th>0</th>\n", - " <td>Alice</td>\n", - " <td>6</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1</th>\n", - " <td>Bob</td>\n", - " <td>7</td>\n", - " </tr>\n", - " <tr>\n", - " <th>2</th>\n", - " <td>Cindy</td>\n", - " <td>8</td>\n", - " </tr>\n", - " <tr>\n", - " <th>3</th>\n", - " <td>Dan</td>\n", - " <td>9</td>\n", - " </tr>\n", - " </tbody>\n", - "</table>\n", - "</div>" - ], - "text/plain": [ - " Player name Score\n", - "0 Alice 6\n", - "1 Bob 7\n", - "2 Cindy 8\n", - "3 Dan 9" - ] - }, - "execution_count": 14, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "data = {\n", - " \"Player name\": {0: \"Alice\", 1: \"Bob\", 2: \"Cindy\", 3: \"Dan\"},\n", - " \"Score\": {0: 6, 1: 7, 2: 8, 3: 9}\n", - "}\n", - "DataFrame(data)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### From a list of dicts" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "<div>\n", - "<style scoped>\n", - " .dataframe tbody tr th:only-of-type {\n", - " vertical-align: middle;\n", - " }\n", - "\n", - " .dataframe tbody tr th {\n", - " vertical-align: top;\n", - " }\n", - "\n", - " .dataframe thead th {\n", - " text-align: right;\n", - " }\n", - "</style>\n", - "<table border=\"1\" class=\"dataframe\">\n", - " <thead>\n", - " <tr style=\"text-align: right;\">\n", - " <th></th>\n", - " <th>Player name</th>\n", - " <th>Score</th>\n", - " </tr>\n", - " </thead>\n", - " <tbody>\n", - " <tr>\n", - " <th>0</th>\n", - " <td>Alice</td>\n", - " <td>6</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1</th>\n", - " <td>Bob</td>\n", - " <td>7</td>\n", - " </tr>\n", - " <tr>\n", - " <th>2</th>\n", - " <td>Cindy</td>\n", - " <td>8</td>\n", - " </tr>\n", - " <tr>\n", - " <th>3</th>\n", - " <td>Dan</td>\n", - " <td>9</td>\n", - " </tr>\n", - " </tbody>\n", - "</table>\n", - "</div>" - ], - "text/plain": [ - " Player name Score\n", - "0 Alice 6\n", - "1 Bob 7\n", - "2 Cindy 8\n", - "3 Dan 9" - ] - }, - "execution_count": 15, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "data = [\n", - " {\"Player name\": \"Alice\", \"Score\": 6},\n", - " {\"Player name\": \"Bob\", \"Score\": 7},\n", - " {\"Player name\": \"Cindy\", \"Score\": 8},\n", - " {\"Player name\": \"Dan\", \"Score\": 9}\n", - "]\n", - "DataFrame(data)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### From a list of lists" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "<div>\n", - "<style scoped>\n", - " .dataframe tbody tr th:only-of-type {\n", - " vertical-align: middle;\n", - " }\n", - "\n", - " .dataframe tbody tr th {\n", - " vertical-align: top;\n", - " }\n", - "\n", - " .dataframe thead th {\n", - " text-align: right;\n", - " }\n", - "</style>\n", - "<table border=\"1\" class=\"dataframe\">\n", - " <thead>\n", - " <tr style=\"text-align: right;\">\n", - " <th></th>\n", - " <th>0</th>\n", - " <th>1</th>\n", - " </tr>\n", - " </thead>\n", - " <tbody>\n", - " <tr>\n", - " <th>0</th>\n", - " <td>Alice</td>\n", - " <td>6</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1</th>\n", - " <td>Bob</td>\n", - " <td>7</td>\n", - " </tr>\n", - " <tr>\n", - " <th>2</th>\n", - " <td>Cindy</td>\n", - " <td>8</td>\n", - " </tr>\n", - " <tr>\n", - " <th>3</th>\n", - " <td>Dan</td>\n", - " <td>9</td>\n", - " </tr>\n", - " </tbody>\n", - "</table>\n", - "</div>" - ], - "text/plain": [ - " 0 1\n", - "0 Alice 6\n", - "1 Bob 7\n", - "2 Cindy 8\n", - "3 Dan 9" - ] - }, - "execution_count": 16, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "data = [\n", - " [\"Alice\", 6],\n", - " [\"Bob\", 7],\n", - " [\"Cindy\", 8],\n", - " [\"Dan\", 9]\n", - "]\n", - "DataFrame(data)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Explicitly naming the columns\n", - "We have to add the column names, we do this with `columns = [name1, name2, ....]` " - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "<div>\n", - "<style scoped>\n", - " .dataframe tbody tr th:only-of-type {\n", - " vertical-align: middle;\n", - " }\n", - "\n", - " .dataframe tbody tr th {\n", - " vertical-align: top;\n", - " }\n", - "\n", - " .dataframe thead th {\n", - " text-align: right;\n", - " }\n", - "</style>\n", - "<table border=\"1\" class=\"dataframe\">\n", - " <thead>\n", - " <tr style=\"text-align: right;\">\n", - " <th></th>\n", - " <th>Player name</th>\n", - " <th>Score</th>\n", - " </tr>\n", - " </thead>\n", - " <tbody>\n", - " <tr>\n", - " <th>0</th>\n", - " <td>Alice</td>\n", - " <td>6</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1</th>\n", - " <td>Bob</td>\n", - " <td>7</td>\n", - " </tr>\n", - " <tr>\n", - " <th>2</th>\n", - " <td>Cindy</td>\n", - " <td>8</td>\n", - " </tr>\n", - " <tr>\n", - " <th>3</th>\n", - " <td>Dan</td>\n", - " <td>9</td>\n", - " </tr>\n", - " </tbody>\n", - "</table>\n", - "</div>" - ], - "text/plain": [ - " Player name Score\n", - "0 Alice 6\n", - "1 Bob 7\n", - "2 Cindy 8\n", - "3 Dan 9" - ] - }, - "execution_count": 17, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "data = [\n", - " [\"Alice\", 6],\n", - " [\"Bob\", 7],\n", - " [\"Cindy\", 8],\n", - " [\"Dan\", 9]\n", - "]\n", - "DataFrame(data, columns=[\"Player name\", \"Score\"])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Explicitly naming the indices\n", - "We can use `index = [name1, name2, ...]` to rename the index of each row" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "<div>\n", - "<style scoped>\n", - " .dataframe tbody tr th:only-of-type {\n", - " vertical-align: middle;\n", - " }\n", - "\n", - " .dataframe tbody tr th {\n", - " vertical-align: top;\n", - " }\n", - "\n", - " .dataframe thead th {\n", - " text-align: right;\n", - " }\n", - "</style>\n", - "<table border=\"1\" class=\"dataframe\">\n", - " <thead>\n", - " <tr style=\"text-align: right;\">\n", - " <th></th>\n", - " <th>Player name</th>\n", - " <th>Score</th>\n", - " </tr>\n", - " </thead>\n", - " <tbody>\n", - " <tr>\n", - " <th>A</th>\n", - " <td>Alice</td>\n", - " <td>6</td>\n", - " </tr>\n", - " <tr>\n", - " <th>B</th>\n", - " <td>Bob</td>\n", - " <td>7</td>\n", - " </tr>\n", - " <tr>\n", - " <th>C</th>\n", - " <td>Cindy</td>\n", - " <td>8</td>\n", - " </tr>\n", - " <tr>\n", - " <th>D</th>\n", - " <td>Dan</td>\n", - " <td>9</td>\n", - " </tr>\n", - " </tbody>\n", - "</table>\n", - "</div>" - ], - "text/plain": [ - " Player name Score\n", - "A Alice 6\n", - "B Bob 7\n", - "C Cindy 8\n", - "D Dan 9" - ] - }, - "execution_count": 18, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "data = [\n", - " {\"Player name\": \"Alice\", \"Score\": 6},\n", - " {\"Player name\": \"Bob\", \"Score\": 7},\n", - " {\"Player name\": \"Cindy\", \"Score\": 8},\n", - " {\"Player name\": \"Dan\", \"Score\": 9}\n", - "]\n", - "DataFrame(data, index = [\"A\", \"B\", \"C\", \"D\"]) # must have a name for each row" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Explicitly naming the columns" - ] - }, - { - "cell_type": "code", - "execution_count": 19, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "<div>\n", - "<style scoped>\n", - " .dataframe tbody tr th:only-of-type {\n", - " vertical-align: middle;\n", - " }\n", - "\n", - " .dataframe tbody tr th {\n", - " vertical-align: top;\n", - " }\n", - "\n", - " .dataframe thead th {\n", - " text-align: right;\n", - " }\n", - "</style>\n", - "<table border=\"1\" class=\"dataframe\">\n", - " <thead>\n", - " <tr style=\"text-align: right;\">\n", - " <th></th>\n", - " <th>Name</th>\n", - " <th>Age</th>\n", - " </tr>\n", - " </thead>\n", - " <tbody>\n", - " <tr>\n", - " <th>A</th>\n", - " <td>Hope</td>\n", - " <td>10</td>\n", - " </tr>\n", - " <tr>\n", - " <th>B</th>\n", - " <td>Peace</td>\n", - " <td>7</td>\n", - " </tr>\n", - " <tr>\n", - " <th>C</th>\n", - " <td>Joy</td>\n", - " <td>4</td>\n", - " </tr>\n", - " <tr>\n", - " <th>D</th>\n", - " <td>Love</td>\n", - " <td>11</td>\n", - " </tr>\n", - " </tbody>\n", - "</table>\n", - "</div>" - ], - "text/plain": [ - " Name Age\n", - "A Hope 10\n", - "B Peace 7\n", - "C Joy 4\n", - "D Love 11" - ] - }, - "execution_count": 19, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# You try: \n", - "# Make a DataFrame of 4 people you know with different ages\n", - "# Give names to both the columns and rows\n", - "ages = [\n", - " [\"Hope\", 10],\n", - " [\"Peace\", 7],\n", - " [\"Joy\", 4],\n", - " [\"Love\", 11]\n", - "]\n", - "DataFrame(ages, index = [\"A\", \"B\", \"C\", \"D\"], columns = [\"Name\", \"Age\"])\n", - "\n", - "# Share how you did with this with your neighbor\n", - "# If you both did it the same way, try it a different way." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Select a column, row, cell, or rectangular region of a DataFrame\n", - "### Data lookup: Series\n", - "- `s.loc[X]` <- lookup by pandas index\n", - "- `s.iloc[X]` <- lookup by integer position" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "Alice 6\n", - "Bob 7\n", - "Cindy 8\n", - "Dan 9\n", - "dtype: int64" - ] - }, - "execution_count": 20, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "hours = Series({\"Alice\":6, \"Bob\":7, \"Cindy\":8, \"Dan\":9})\n", - "hours" - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "7" - ] - }, - "execution_count": 21, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Lookup Bob's hours by pandas index.\n", - "hours.loc[\"Bob\"]" - ] - }, - { - "cell_type": "code", - "execution_count": 22, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "8" - ] - }, - "execution_count": 22, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Lookup Bob's hours by integer position.\n", - "hours.iloc[2]" - ] - }, - { - "cell_type": "code", - "execution_count": 23, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "8" - ] - }, - "execution_count": 23, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Lookup Cindy's hours by pandas index.\n", - "hours.loc[\"Cindy\"]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Data lookup: DataFrame\n", - "\n", - "\n", - "- `d.loc[r]` lookup ROW by pandas ROW index\n", - "- `d.iloc[r]` lookup ROW by ROW integer position\n", - "- `d[c]` lookup COL by pandas COL index\n", - "- `d.loc[r, c]` lookup by pandas ROW index and pandas COL index\n", - "- `d.iloc[r, c]` lookup by ROW integer position and COL integer position" - ] - }, - { - "cell_type": "code", - "execution_count": 24, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "<div>\n", - "<style scoped>\n", - " .dataframe tbody tr th:only-of-type {\n", - " vertical-align: middle;\n", - " }\n", - "\n", - " .dataframe tbody tr th {\n", - " vertical-align: top;\n", - " }\n", - "\n", - " .dataframe thead th {\n", - " text-align: right;\n", - " }\n", - "</style>\n", - "<table border=\"1\" class=\"dataframe\">\n", - " <thead>\n", - " <tr style=\"text-align: right;\">\n", - " <th></th>\n", - " <th>Player name</th>\n", - " <th>Score</th>\n", - " </tr>\n", - " </thead>\n", - " <tbody>\n", - " <tr>\n", - " <th>H</th>\n", - " <td>Hope</td>\n", - " <td>10</td>\n", - " </tr>\n", - " <tr>\n", - " <th>P</th>\n", - " <td>Peace</td>\n", - " <td>7</td>\n", - " </tr>\n", - " <tr>\n", - " <th>J</th>\n", - " <td>Joy</td>\n", - " <td>4</td>\n", - " </tr>\n", - " <tr>\n", - " <th>L</th>\n", - " <td>Love</td>\n", - " <td>11</td>\n", - " </tr>\n", - " </tbody>\n", - "</table>\n", - "</div>" - ], - "text/plain": [ - " Player name Score\n", - "H Hope 10\n", - "P Peace 7\n", - "J Joy 4\n", - "L Love 11" - ] - }, - "execution_count": 24, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# We often call the object that we make df\n", - "data = [\n", - " [\"Hope\", 10],\n", - " [\"Peace\", 7],\n", - " [\"Joy\", 4],\n", - " [\"Love\", 11]\n", - "]\n", - "df = DataFrame(data, index = [\"H\", \"P\", \"J\", \"L\"], columns = [\"Player name\", \"Score\"])\n", - "df" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### What are 3 different ways of accessing row L? " - ] - }, - { - "cell_type": "code", - "execution_count": 25, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Player name Love\n", - "Score 11\n", - "Name: L, dtype: object\n", - "Player name Love\n", - "Score 11\n", - "Name: L, dtype: object\n", - "Player name Love\n", - "Score 11\n", - "Name: L, dtype: object\n" - ] - } - ], - "source": [ - "#df[\"L\"] # Nope!\n", - "print(df.loc[\"L\"])\n", - "print(df.iloc[3])\n", - "print(df.iloc[-1])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### How about accessing a column?" - ] - }, - { - "cell_type": "code", - "execution_count": 26, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "<div>\n", - "<style scoped>\n", - " .dataframe tbody tr th:only-of-type {\n", - " vertical-align: middle;\n", - " }\n", - "\n", - " .dataframe tbody tr th {\n", - " vertical-align: top;\n", - " }\n", - "\n", - " .dataframe thead th {\n", - " text-align: right;\n", - " }\n", - "</style>\n", - "<table border=\"1\" class=\"dataframe\">\n", - " <thead>\n", - " <tr style=\"text-align: right;\">\n", - " <th></th>\n", - " <th>Player name</th>\n", - " <th>Score</th>\n", - " </tr>\n", - " </thead>\n", - " <tbody>\n", - " <tr>\n", - " <th>H</th>\n", - " <td>Hope</td>\n", - " <td>10</td>\n", - " </tr>\n", - " <tr>\n", - " <th>P</th>\n", - " <td>Peace</td>\n", - " <td>7</td>\n", - " </tr>\n", - " <tr>\n", - " <th>J</th>\n", - " <td>Joy</td>\n", - " <td>4</td>\n", - " </tr>\n", - " <tr>\n", - " <th>L</th>\n", - " <td>Love</td>\n", - " <td>11</td>\n", - " </tr>\n", - " </tbody>\n", - "</table>\n", - "</div>" - ], - "text/plain": [ - " Player name Score\n", - "H Hope 10\n", - "P Peace 7\n", - "J Joy 4\n", - "L Love 11" - ] - }, - "execution_count": 26, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "df" - ] - }, - { - "cell_type": "code", - "execution_count": 27, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "H Hope\n", - "P Peace\n", - "J Joy\n", - "L Love\n", - "Name: Player name, dtype: object\n" - ] - } - ], - "source": [ - "print(df[\"Player name\"])\n", - "#df[0] # Doesn't work!" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### What are 3 different ways to access a single cell?" - ] - }, - { - "cell_type": "code", - "execution_count": 28, - "metadata": { - "scrolled": true - }, - "outputs": [ - { - "data": { - "text/html": [ - "<div>\n", - "<style scoped>\n", - " .dataframe tbody tr th:only-of-type {\n", - " vertical-align: middle;\n", - " }\n", - "\n", - " .dataframe tbody tr th {\n", - " vertical-align: top;\n", - " }\n", - "\n", - " .dataframe thead th {\n", - " text-align: right;\n", - " }\n", - "</style>\n", - "<table border=\"1\" class=\"dataframe\">\n", - " <thead>\n", - " <tr style=\"text-align: right;\">\n", - " <th></th>\n", - " <th>Player name</th>\n", - " <th>Score</th>\n", - " </tr>\n", - " </thead>\n", - " <tbody>\n", - " <tr>\n", - " <th>H</th>\n", - " <td>Hope</td>\n", - " <td>10</td>\n", - " </tr>\n", - " <tr>\n", - " <th>P</th>\n", - " <td>Peace</td>\n", - " <td>7</td>\n", - " </tr>\n", - " <tr>\n", - " <th>J</th>\n", - " <td>Joy</td>\n", - " <td>4</td>\n", - " </tr>\n", - " <tr>\n", - " <th>L</th>\n", - " <td>Love</td>\n", - " <td>11</td>\n", - " </tr>\n", - " </tbody>\n", - "</table>\n", - "</div>" - ], - "text/plain": [ - " Player name Score\n", - "H Hope 10\n", - "P Peace 7\n", - "J Joy 4\n", - "L Love 11" - ] - }, - "execution_count": 28, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "df" - ] - }, - { - "cell_type": "code", - "execution_count": 29, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Joy\n", - "Joy\n", - "Joy\n" - ] - } - ], - "source": [ - "# How to access Cindy?\n", - "#print(df[\"C\", \"Player name\"]) # Nope!\n", - "print(df.loc[\"J\", \"Player name\"])\n", - "print(df[\"Player name\"].loc[\"J\"])\n", - "print(df.iloc[2, 0])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## How to set values for a specific entry?\n", - "\n", - "- `d.loc[r, c] = new_val`\n", - "- `d.iloc[r, c] = new_val`" - ] - }, - { - "cell_type": "code", - "execution_count": 30, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "<div>\n", - "<style scoped>\n", - " .dataframe tbody tr th:only-of-type {\n", - " vertical-align: middle;\n", - " }\n", - "\n", - " .dataframe tbody tr th {\n", - " vertical-align: top;\n", - " }\n", - "\n", - " .dataframe thead th {\n", - " text-align: right;\n", - " }\n", - "</style>\n", - "<table border=\"1\" class=\"dataframe\">\n", - " <thead>\n", - " <tr style=\"text-align: right;\">\n", - " <th></th>\n", - " <th>Player name</th>\n", - " <th>Score</th>\n", - " </tr>\n", - " </thead>\n", - " <tbody>\n", - " <tr>\n", - " <th>H</th>\n", - " <td>Hope</td>\n", - " <td>10</td>\n", - " </tr>\n", - " <tr>\n", - " <th>P</th>\n", - " <td>Peace</td>\n", - " <td>7</td>\n", - " </tr>\n", - " <tr>\n", - " <th>J</th>\n", - " <td>Joy</td>\n", - " <td>4</td>\n", - " </tr>\n", - " <tr>\n", - " <th>L</th>\n", - " <td>Luisa</td>\n", - " <td>11</td>\n", - " </tr>\n", - " </tbody>\n", - "</table>\n", - "</div>" - ], - "text/plain": [ - " Player name Score\n", - "H Hope 10\n", - "P Peace 7\n", - "J Joy 4\n", - "L Luisa 11" - ] - }, - "execution_count": 30, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "#change player D's name\n", - "df.loc[\"L\", \"Player name\"] = \"Luisa\"\n", - "df" - ] - }, - { - "cell_type": "code", - "execution_count": 31, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "<div>\n", - "<style scoped>\n", - " .dataframe tbody tr th:only-of-type {\n", - " vertical-align: middle;\n", - " }\n", - "\n", - " .dataframe tbody tr th {\n", - " vertical-align: top;\n", - " }\n", - "\n", - " .dataframe thead th {\n", - " text-align: right;\n", - " }\n", - "</style>\n", - "<table border=\"1\" class=\"dataframe\">\n", - " <thead>\n", - " <tr style=\"text-align: right;\">\n", - " <th></th>\n", - " <th>Player name</th>\n", - " <th>Score</th>\n", - " </tr>\n", - " </thead>\n", - " <tbody>\n", - " <tr>\n", - " <th>H</th>\n", - " <td>Hope</td>\n", - " <td>10</td>\n", - " </tr>\n", - " <tr>\n", - " <th>P</th>\n", - " <td>Peace</td>\n", - " <td>7</td>\n", - " </tr>\n", - " <tr>\n", - " <th>J</th>\n", - " <td>Joy</td>\n", - " <td>4</td>\n", - " </tr>\n", - " <tr>\n", - " <th>L</th>\n", - " <td>Luisa</td>\n", - " <td>14</td>\n", - " </tr>\n", - " </tbody>\n", - "</table>\n", - "</div>" - ], - "text/plain": [ - " Player name Score\n", - "H Hope 10\n", - "P Peace 7\n", - "J Joy 4\n", - "L Luisa 14" - ] - }, - "execution_count": 31, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# then add 3 to that player's score using .loc\n", - "df.loc[\"L\",\"Score\"] += 3\n", - "df" - ] - }, - { - "cell_type": "code", - "execution_count": 32, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "<div>\n", - "<style scoped>\n", - " .dataframe tbody tr th:only-of-type {\n", - " vertical-align: middle;\n", - " }\n", - "\n", - " .dataframe tbody tr th {\n", - " vertical-align: top;\n", - " }\n", - "\n", - " .dataframe thead th {\n", - " text-align: right;\n", - " }\n", - "</style>\n", - "<table border=\"1\" class=\"dataframe\">\n", - " <thead>\n", - " <tr style=\"text-align: right;\">\n", - " <th></th>\n", - " <th>Player name</th>\n", - " <th>Score</th>\n", - " </tr>\n", - " </thead>\n", - " <tbody>\n", - " <tr>\n", - " <th>H</th>\n", - " <td>Hope</td>\n", - " <td>17</td>\n", - " </tr>\n", - " <tr>\n", - " <th>P</th>\n", - " <td>Peace</td>\n", - " <td>7</td>\n", - " </tr>\n", - " <tr>\n", - " <th>J</th>\n", - " <td>Joy</td>\n", - " <td>4</td>\n", - " </tr>\n", - " <tr>\n", - " <th>L</th>\n", - " <td>Luisa</td>\n", - " <td>14</td>\n", - " </tr>\n", - " </tbody>\n", - "</table>\n", - "</div>" - ], - "text/plain": [ - " Player name Score\n", - "H Hope 17\n", - "P Peace 7\n", - "J Joy 4\n", - "L Luisa 14" - ] - }, - "execution_count": 32, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# add 7 to a different player's score using .iloc\n", - "df.iloc[0, 1] += 7\n", - "df" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Find the max score and the mean score" - ] - }, - { - "cell_type": "code", - "execution_count": 33, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "17 10.5\n" - ] - } - ], - "source": [ - "# find the max and mean of the \"Score\" column\n", - "print(df[\"Score\"].max(), df[\"Score\"].mean())" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Find the highest scoring player" - ] - }, - { - "cell_type": "code", - "execution_count": 34, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "<div>\n", - "<style scoped>\n", - " .dataframe tbody tr th:only-of-type {\n", - " vertical-align: middle;\n", - " }\n", - "\n", - " .dataframe tbody tr th {\n", - " vertical-align: top;\n", - " }\n", - "\n", - " .dataframe thead th {\n", - " text-align: right;\n", - " }\n", - "</style>\n", - "<table border=\"1\" class=\"dataframe\">\n", - " <thead>\n", - " <tr style=\"text-align: right;\">\n", - " <th></th>\n", - " <th>Player name</th>\n", - " <th>Score</th>\n", - " </tr>\n", - " </thead>\n", - " <tbody>\n", - " <tr>\n", - " <th>H</th>\n", - " <td>Hope</td>\n", - " <td>17</td>\n", - " </tr>\n", - " <tr>\n", - " <th>P</th>\n", - " <td>Peace</td>\n", - " <td>7</td>\n", - " </tr>\n", - " <tr>\n", - " <th>J</th>\n", - " <td>Joy</td>\n", - " <td>4</td>\n", - " </tr>\n", - " <tr>\n", - " <th>L</th>\n", - " <td>Luisa</td>\n", - " <td>14</td>\n", - " </tr>\n", - " </tbody>\n", - "</table>\n", - "</div>" - ], - "text/plain": [ - " Player name Score\n", - "H Hope 17\n", - "P Peace 7\n", - "J Joy 4\n", - "L Luisa 14" - ] - }, - "execution_count": 34, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "df" - ] - }, - { - "cell_type": "code", - "execution_count": 35, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'Hope'" - ] - }, - "execution_count": 35, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "highest_scorer = df[\"Score\"].idxmax()\n", - "df[\"Player name\"].loc[highest_scorer]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Slicing a DataFrame\n", - "\n", - "- `df.iloc[ROW_SLICE, COL_SLICE]` <- make a rectangular slice from the DataFrame using integer positions\n", - "- `df.loc[ROW_SLICE, COL_SLICE]` <- make a rectangular slice from the DataFrame using index" - ] - }, - { - "cell_type": "code", - "execution_count": 36, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "<div>\n", - "<style scoped>\n", - " .dataframe tbody tr th:only-of-type {\n", - " vertical-align: middle;\n", - " }\n", - "\n", - " .dataframe tbody tr th {\n", - " vertical-align: top;\n", - " }\n", - "\n", - " .dataframe thead th {\n", - " text-align: right;\n", - " }\n", - "</style>\n", - "<table border=\"1\" class=\"dataframe\">\n", - " <thead>\n", - " <tr style=\"text-align: right;\">\n", - " <th></th>\n", - " <th>Player name</th>\n", - " <th>Score</th>\n", - " </tr>\n", - " </thead>\n", - " <tbody>\n", - " <tr>\n", - " <th>P</th>\n", - " <td>Peace</td>\n", - " <td>7</td>\n", - " </tr>\n", - " <tr>\n", - " <th>J</th>\n", - " <td>Joy</td>\n", - " <td>4</td>\n", - " </tr>\n", - " </tbody>\n", - "</table>\n", - "</div>" - ], - "text/plain": [ - " Player name Score\n", - "P Peace 7\n", - "J Joy 4" - ] - }, - "execution_count": 36, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "df.iloc[1:3, 0:2]" - ] - }, - { - "cell_type": "code", - "execution_count": 37, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "<div>\n", - "<style scoped>\n", - " .dataframe tbody tr th:only-of-type {\n", - " vertical-align: middle;\n", - " }\n", - "\n", - " .dataframe tbody tr th {\n", - " vertical-align: top;\n", - " }\n", - "\n", - " .dataframe thead th {\n", - " text-align: right;\n", - " }\n", - "</style>\n", - "<table border=\"1\" class=\"dataframe\">\n", - " <thead>\n", - " <tr style=\"text-align: right;\">\n", - " <th></th>\n", - " <th>Player name</th>\n", - " <th>Score</th>\n", - " </tr>\n", - " </thead>\n", - " <tbody>\n", - " <tr>\n", - " <th>P</th>\n", - " <td>Peace</td>\n", - " <td>7</td>\n", - " </tr>\n", - " <tr>\n", - " <th>J</th>\n", - " <td>Joy</td>\n", - " <td>4</td>\n", - " </tr>\n", - " </tbody>\n", - "</table>\n", - "</div>" - ], - "text/plain": [ - " Player name Score\n", - "P Peace 7\n", - "J Joy 4" - ] - }, - "execution_count": 37, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "df.loc[\"P\":\"J\", \"Player name\":\"Score\"] # notice that this way is inclusive of endpoints" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Set values for sliced DataFrame\n", - "\n", - "- `d.loc[ROW_SLICE, COL_SLICE] = new_val` <- set value by ROW INDEX and COL INDEX\n", - "- `d.iloc[ROW_SLICE, COL_SLICE] = new_val` <- set value by ROW Integer position and COL Integer position" - ] - }, - { - "cell_type": "code", - "execution_count": 38, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "<div>\n", - "<style scoped>\n", - " .dataframe tbody tr th:only-of-type {\n", - " vertical-align: middle;\n", - " }\n", - "\n", - " .dataframe tbody tr th {\n", - " vertical-align: top;\n", - " }\n", - "\n", - " .dataframe thead th {\n", - " text-align: right;\n", - " }\n", - "</style>\n", - "<table border=\"1\" class=\"dataframe\">\n", - " <thead>\n", - " <tr style=\"text-align: right;\">\n", - " <th></th>\n", - " <th>Player name</th>\n", - " <th>Score</th>\n", - " </tr>\n", - " </thead>\n", - " <tbody>\n", - " <tr>\n", - " <th>H</th>\n", - " <td>Hope</td>\n", - " <td>17</td>\n", - " </tr>\n", - " <tr>\n", - " <th>P</th>\n", - " <td>Peace</td>\n", - " <td>7</td>\n", - " </tr>\n", - " <tr>\n", - " <th>J</th>\n", - " <td>Joy</td>\n", - " <td>4</td>\n", - " </tr>\n", - " <tr>\n", - " <th>L</th>\n", - " <td>Luisa</td>\n", - " <td>14</td>\n", - " </tr>\n", - " </tbody>\n", - "</table>\n", - "</div>" - ], - "text/plain": [ - " Player name Score\n", - "H Hope 17\n", - "P Peace 7\n", - "J Joy 4\n", - "L Luisa 14" - ] - }, - "execution_count": 38, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "df" - ] - }, - { - "cell_type": "code", - "execution_count": 39, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "<div>\n", - "<style scoped>\n", - " .dataframe tbody tr th:only-of-type {\n", - " vertical-align: middle;\n", - " }\n", - "\n", - " .dataframe tbody tr th {\n", - " vertical-align: top;\n", - " }\n", - "\n", - " .dataframe thead th {\n", - " text-align: right;\n", - " }\n", - "</style>\n", - "<table border=\"1\" class=\"dataframe\">\n", - " <thead>\n", - " <tr style=\"text-align: right;\">\n", - " <th></th>\n", - " <th>Player name</th>\n", - " <th>Score</th>\n", - " </tr>\n", - " </thead>\n", - " <tbody>\n", - " <tr>\n", - " <th>H</th>\n", - " <td>Hope</td>\n", - " <td>17</td>\n", - " </tr>\n", - " <tr>\n", - " <th>P</th>\n", - " <td>Peace</td>\n", - " <td>12</td>\n", - " </tr>\n", - " <tr>\n", - " <th>J</th>\n", - " <td>Joy</td>\n", - " <td>9</td>\n", - " </tr>\n", - " <tr>\n", - " <th>L</th>\n", - " <td>Luisa</td>\n", - " <td>14</td>\n", - " </tr>\n", - " </tbody>\n", - "</table>\n", - "</div>" - ], - "text/plain": [ - " Player name Score\n", - "H Hope 17\n", - "P Peace 12\n", - "J Joy 9\n", - "L Luisa 14" - ] - }, - "execution_count": 39, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "df.loc[\"P\":\"J\", \"Score\"] += 5\n", - "df" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Pandas allows slicing of non-contiguous columns" - ] - }, - { - "cell_type": "code", - "execution_count": 40, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "P Peace\n", - "L Luisa\n", - "Name: Player name, dtype: object" - ] - }, - "execution_count": 40, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# just get Player name for Index B and D\n", - "df.loc[[\"P\", \"L\"],\"Player name\"]" - ] - }, - { - "cell_type": "code", - "execution_count": 41, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "<div>\n", - "<style scoped>\n", - " .dataframe tbody tr th:only-of-type {\n", - " vertical-align: middle;\n", - " }\n", - "\n", - " .dataframe tbody tr th {\n", - " vertical-align: top;\n", - " }\n", - "\n", - " .dataframe thead th {\n", - " text-align: right;\n", - " }\n", - "</style>\n", - "<table border=\"1\" class=\"dataframe\">\n", - " <thead>\n", - " <tr style=\"text-align: right;\">\n", - " <th></th>\n", - " <th>Player name</th>\n", - " <th>Score</th>\n", - " </tr>\n", - " </thead>\n", - " <tbody>\n", - " <tr>\n", - " <th>H</th>\n", - " <td>Hope</td>\n", - " <td>17</td>\n", - " </tr>\n", - " <tr>\n", - " <th>P</th>\n", - " <td>Peace</td>\n", - " <td>14</td>\n", - " </tr>\n", - " <tr>\n", - " <th>J</th>\n", - " <td>Joy</td>\n", - " <td>9</td>\n", - " </tr>\n", - " <tr>\n", - " <th>L</th>\n", - " <td>Luisa</td>\n", - " <td>16</td>\n", - " </tr>\n", - " </tbody>\n", - "</table>\n", - "</div>" - ], - "text/plain": [ - " Player name Score\n", - "H Hope 17\n", - "P Peace 14\n", - "J Joy 9\n", - "L Luisa 16" - ] - }, - "execution_count": 41, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# add 2 to the people in rows B and D\n", - "df.loc[[\"P\", \"L\"],\"Score\"] += 2\n", - "df" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Boolean indexing on a DataFrame\n", - "\n", - "- `d[BOOL SERIES]` <- makes a new DF of all rows that lined up were True" - ] - }, - { - "cell_type": "code", - "execution_count": 42, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "<div>\n", - "<style scoped>\n", - " .dataframe tbody tr th:only-of-type {\n", - " vertical-align: middle;\n", - " }\n", - "\n", - " .dataframe tbody tr th {\n", - " vertical-align: top;\n", - " }\n", - "\n", - " .dataframe thead th {\n", - " text-align: right;\n", - " }\n", - "</style>\n", - "<table border=\"1\" class=\"dataframe\">\n", - " <thead>\n", - " <tr style=\"text-align: right;\">\n", - " <th></th>\n", - " <th>Player name</th>\n", - " <th>Score</th>\n", - " </tr>\n", - " </thead>\n", - " <tbody>\n", - " <tr>\n", - " <th>H</th>\n", - " <td>Hope</td>\n", - " <td>17</td>\n", - " </tr>\n", - " <tr>\n", - " <th>P</th>\n", - " <td>Peace</td>\n", - " <td>14</td>\n", - " </tr>\n", - " <tr>\n", - " <th>J</th>\n", - " <td>Joy</td>\n", - " <td>9</td>\n", - " </tr>\n", - " <tr>\n", - " <th>L</th>\n", - " <td>Luisa</td>\n", - " <td>16</td>\n", - " </tr>\n", - " </tbody>\n", - "</table>\n", - "</div>" - ], - "text/plain": [ - " Player name Score\n", - "H Hope 17\n", - "P Peace 14\n", - "J Joy 9\n", - "L Luisa 16" - ] - }, - "execution_count": 42, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "df" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Make a Series of Booleans based on Score >= 15" - ] - }, - { - "cell_type": "code", - "execution_count": 43, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "H True\n", - "P False\n", - "J False\n", - "L True\n", - "Name: Score, dtype: bool" - ] - }, - "execution_count": 43, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "b = df[\"Score\"] >= 15\n", - "b" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### use b to slice the DataFrame\n", - "if b is true, include this row in the new df" - ] - }, - { - "cell_type": "code", - "execution_count": 44, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "<div>\n", - "<style scoped>\n", - " .dataframe tbody tr th:only-of-type {\n", - " vertical-align: middle;\n", - " }\n", - "\n", - " .dataframe tbody tr th {\n", - " vertical-align: top;\n", - " }\n", - "\n", - " .dataframe thead th {\n", - " text-align: right;\n", - " }\n", - "</style>\n", - "<table border=\"1\" class=\"dataframe\">\n", - " <thead>\n", - " <tr style=\"text-align: right;\">\n", - " <th></th>\n", - " <th>Player name</th>\n", - " <th>Score</th>\n", - " </tr>\n", - " </thead>\n", - " <tbody>\n", - " <tr>\n", - " <th>H</th>\n", - " <td>Hope</td>\n", - " <td>17</td>\n", - " </tr>\n", - " <tr>\n", - " <th>L</th>\n", - " <td>Luisa</td>\n", - " <td>16</td>\n", - " </tr>\n", - " </tbody>\n", - "</table>\n", - "</div>" - ], - "text/plain": [ - " Player name Score\n", - "H Hope 17\n", - "L Luisa 16" - ] - }, - "execution_count": 44, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "df[b]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### do the last two things in a single step" - ] - }, - { - "cell_type": "code", - "execution_count": 45, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "<div>\n", - "<style scoped>\n", - " .dataframe tbody tr th:only-of-type {\n", - " vertical-align: middle;\n", - " }\n", - "\n", - " .dataframe tbody tr th {\n", - " vertical-align: top;\n", - " }\n", - "\n", - " .dataframe thead th {\n", - " text-align: right;\n", - " }\n", - "</style>\n", - "<table border=\"1\" class=\"dataframe\">\n", - " <thead>\n", - " <tr style=\"text-align: right;\">\n", - " <th></th>\n", - " <th>Player name</th>\n", - " <th>Score</th>\n", - " </tr>\n", - " </thead>\n", - " <tbody>\n", - " <tr>\n", - " <th>H</th>\n", - " <td>Hope</td>\n", - " <td>17</td>\n", - " </tr>\n", - " <tr>\n", - " <th>L</th>\n", - " <td>Luisa</td>\n", - " <td>16</td>\n", - " </tr>\n", - " </tbody>\n", - "</table>\n", - "</div>" - ], - "text/plain": [ - " Player name Score\n", - "H Hope 17\n", - "L Luisa 16" - ] - }, - "execution_count": 45, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "df[df[\"Score\"] >= 15]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Creating DataFrame from csv" - ] - }, - { - "cell_type": "code", - "execution_count": 46, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "<div>\n", - "<style scoped>\n", - " .dataframe tbody tr th:only-of-type {\n", - " vertical-align: middle;\n", - " }\n", - "\n", - " .dataframe tbody tr th {\n", - " vertical-align: top;\n", - " }\n", - "\n", - " .dataframe thead th {\n", - " text-align: right;\n", - " }\n", - "</style>\n", - "<table border=\"1\" class=\"dataframe\">\n", - " <thead>\n", - " <tr style=\"text-align: right;\">\n", - " <th></th>\n", - " <th>Index</th>\n", - " <th>Title</th>\n", - " <th>Genre</th>\n", - " <th>Director</th>\n", - " <th>Cast</th>\n", - " <th>Year</th>\n", - " <th>Runtime</th>\n", - " <th>Rating</th>\n", - " <th>Revenue</th>\n", - " </tr>\n", - " </thead>\n", - " <tbody>\n", - " <tr>\n", - " <th>0</th>\n", - " <td>0</td>\n", - " <td>Guardians of the Galaxy</td>\n", - " <td>Action,Adventure,Sci-Fi</td>\n", - " <td>James Gunn</td>\n", - " <td>Chris Pratt, Vin Diesel, Bradley Cooper, Zoe S...</td>\n", - " <td>2014</td>\n", - " <td>121</td>\n", - " <td>8.1</td>\n", - " <td>333.13</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1</th>\n", - " <td>1</td>\n", - " <td>Prometheus</td>\n", - " <td>Adventure,Mystery,Sci-Fi</td>\n", - " <td>Ridley Scott</td>\n", - " <td>Noomi Rapace, Logan Marshall-Green, Michael ...</td>\n", - " <td>2012</td>\n", - " <td>124</td>\n", - " <td>7.0</td>\n", - " <td>126.46M</td>\n", - " </tr>\n", - " <tr>\n", - " <th>2</th>\n", - " <td>2</td>\n", - " <td>Split</td>\n", - " <td>Horror,Thriller</td>\n", - " <td>M. Night Shyamalan</td>\n", - " <td>James McAvoy, Anya Taylor-Joy, Haley Lu Richar...</td>\n", - " <td>2016</td>\n", - " <td>117</td>\n", - " <td>7.3</td>\n", - " <td>138.12M</td>\n", - " </tr>\n", - " <tr>\n", - " <th>3</th>\n", - " <td>3</td>\n", - " <td>Sing</td>\n", - " <td>Animation,Comedy,Family</td>\n", - " <td>Christophe Lourdelet</td>\n", - " <td>Matthew McConaughey,Reese Witherspoon, Seth Ma...</td>\n", - " <td>2016</td>\n", - " <td>108</td>\n", - " <td>7.2</td>\n", - " <td>270.32</td>\n", - " </tr>\n", - " <tr>\n", - " <th>4</th>\n", - " <td>4</td>\n", - " <td>Suicide Squad</td>\n", - " <td>Action,Adventure,Fantasy</td>\n", - " <td>David Ayer</td>\n", - " <td>Will Smith, Jared Leto, Margot Robbie, Viola D...</td>\n", - " <td>2016</td>\n", - " <td>123</td>\n", - " <td>6.2</td>\n", - " <td>325.02</td>\n", - " </tr>\n", - " <tr>\n", - " <th>...</th>\n", - " <td>...</td>\n", - " <td>...</td>\n", - " <td>...</td>\n", - " <td>...</td>\n", - " <td>...</td>\n", - " <td>...</td>\n", - " <td>...</td>\n", - " <td>...</td>\n", - " <td>...</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1063</th>\n", - " <td>1063</td>\n", - " <td>Guardians of the Galaxy Vol. 2</td>\n", - " <td>Action, Adventure, Comedy</td>\n", - " <td>James Gunn</td>\n", - " <td>Chris Pratt, Zoe Saldana, Dave Bautista, Vin D...</td>\n", - " <td>2017</td>\n", - " <td>136</td>\n", - " <td>7.6</td>\n", - " <td>389.81</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1064</th>\n", - " <td>1064</td>\n", - " <td>Baby Driver</td>\n", - " <td>Action, Crime, Drama</td>\n", - " <td>Edgar Wright</td>\n", - " <td>Ansel Elgort, Jon Bernthal, Jon Hamm, Eiza Gon...</td>\n", - " <td>2017</td>\n", - " <td>113</td>\n", - " <td>7.6</td>\n", - " <td>107.83</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1065</th>\n", - " <td>1065</td>\n", - " <td>Only the Brave</td>\n", - " <td>Action, Biography, Drama</td>\n", - " <td>Joseph Kosinski</td>\n", - " <td>Josh Brolin, Miles Teller, Jeff Bridges, Jenni...</td>\n", - " <td>2017</td>\n", - " <td>134</td>\n", - " <td>7.6</td>\n", - " <td>18.34</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1066</th>\n", - " <td>1066</td>\n", - " <td>Incredibles 2</td>\n", - " <td>Animation, Action, Adventure</td>\n", - " <td>Brad Bird</td>\n", - " <td>Craig T. Nelson, Holly Hunter, Sarah Vowell, H...</td>\n", - " <td>2018</td>\n", - " <td>118</td>\n", - " <td>7.6</td>\n", - " <td>608.58</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1067</th>\n", - " <td>1067</td>\n", - " <td>A Star Is Born</td>\n", - " <td>Drama, Music, Romance</td>\n", - " <td>Bradley Cooper</td>\n", - " <td>Lady Gaga, Bradley Cooper, Sam Elliott, Greg G...</td>\n", - " <td>2018</td>\n", - " <td>136</td>\n", - " <td>7.6</td>\n", - " <td>215.29</td>\n", - " </tr>\n", - " </tbody>\n", - "</table>\n", - "<p>1068 rows × 9 columns</p>\n", - "</div>" - ], - "text/plain": [ - " Index Title Genre \\\n", - "0 0 Guardians of the Galaxy Action,Adventure,Sci-Fi \n", - "1 1 Prometheus Adventure,Mystery,Sci-Fi \n", - "2 2 Split Horror,Thriller \n", - "3 3 Sing Animation,Comedy,Family \n", - "4 4 Suicide Squad Action,Adventure,Fantasy \n", - "... ... ... ... \n", - "1063 1063 Guardians of the Galaxy Vol. 2 Action, Adventure, Comedy \n", - "1064 1064 Baby Driver Action, Crime, Drama \n", - "1065 1065 Only the Brave Action, Biography, Drama \n", - "1066 1066 Incredibles 2 Animation, Action, Adventure \n", - "1067 1067 A Star Is Born Drama, Music, Romance \n", - "\n", - " Director Cast \\\n", - "0 James Gunn Chris Pratt, Vin Diesel, Bradley Cooper, Zoe S... \n", - "1 Ridley Scott Noomi Rapace, Logan Marshall-Green, Michael ... \n", - "2 M. Night Shyamalan James McAvoy, Anya Taylor-Joy, Haley Lu Richar... \n", - "3 Christophe Lourdelet Matthew McConaughey,Reese Witherspoon, Seth Ma... \n", - "4 David Ayer Will Smith, Jared Leto, Margot Robbie, Viola D... \n", - "... ... ... \n", - "1063 James Gunn Chris Pratt, Zoe Saldana, Dave Bautista, Vin D... \n", - "1064 Edgar Wright Ansel Elgort, Jon Bernthal, Jon Hamm, Eiza Gon... \n", - "1065 Joseph Kosinski Josh Brolin, Miles Teller, Jeff Bridges, Jenni... \n", - "1066 Brad Bird Craig T. Nelson, Holly Hunter, Sarah Vowell, H... \n", - "1067 Bradley Cooper Lady Gaga, Bradley Cooper, Sam Elliott, Greg G... \n", - "\n", - " Year Runtime Rating Revenue \n", - "0 2014 121 8.1 333.13 \n", - "1 2012 124 7.0 126.46M \n", - "2 2016 117 7.3 138.12M \n", - "3 2016 108 7.2 270.32 \n", - "4 2016 123 6.2 325.02 \n", - "... ... ... ... ... \n", - "1063 2017 136 7.6 389.81 \n", - "1064 2017 113 7.6 107.83 \n", - "1065 2017 134 7.6 18.34 \n", - "1066 2018 118 7.6 608.58 \n", - "1067 2018 136 7.6 215.29 \n", - "\n", - "[1068 rows x 9 columns]" - ] - }, - "execution_count": 46, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# it's that easy! \n", - "df = pd.read_csv(\"IMDB-Movie-Data.csv\")\n", - "df" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### View the first few lines of the DataFrame\n", - "- `.head(n)` gets the first n lines, 5 is the default" - ] - }, - { - "cell_type": "code", - "execution_count": 47, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "<div>\n", - "<style scoped>\n", - " .dataframe tbody tr th:only-of-type {\n", - " vertical-align: middle;\n", - " }\n", - "\n", - " .dataframe tbody tr th {\n", - " vertical-align: top;\n", - " }\n", - "\n", - " .dataframe thead th {\n", - " text-align: right;\n", - " }\n", - "</style>\n", - "<table border=\"1\" class=\"dataframe\">\n", - " <thead>\n", - " <tr style=\"text-align: right;\">\n", - " <th></th>\n", - " <th>Index</th>\n", - " <th>Title</th>\n", - " <th>Genre</th>\n", - " <th>Director</th>\n", - " <th>Cast</th>\n", - " <th>Year</th>\n", - " <th>Runtime</th>\n", - " <th>Rating</th>\n", - " <th>Revenue</th>\n", - " </tr>\n", - " </thead>\n", - " <tbody>\n", - " <tr>\n", - " <th>0</th>\n", - " <td>0</td>\n", - " <td>Guardians of the Galaxy</td>\n", - " <td>Action,Adventure,Sci-Fi</td>\n", - " <td>James Gunn</td>\n", - " <td>Chris Pratt, Vin Diesel, Bradley Cooper, Zoe S...</td>\n", - " <td>2014</td>\n", - " <td>121</td>\n", - " <td>8.1</td>\n", - " <td>333.13</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1</th>\n", - " <td>1</td>\n", - " <td>Prometheus</td>\n", - " <td>Adventure,Mystery,Sci-Fi</td>\n", - " <td>Ridley Scott</td>\n", - " <td>Noomi Rapace, Logan Marshall-Green, Michael ...</td>\n", - " <td>2012</td>\n", - " <td>124</td>\n", - " <td>7.0</td>\n", - " <td>126.46M</td>\n", - " </tr>\n", - " <tr>\n", - " <th>2</th>\n", - " <td>2</td>\n", - " <td>Split</td>\n", - " <td>Horror,Thriller</td>\n", - " <td>M. Night Shyamalan</td>\n", - " <td>James McAvoy, Anya Taylor-Joy, Haley Lu Richar...</td>\n", - " <td>2016</td>\n", - " <td>117</td>\n", - " <td>7.3</td>\n", - " <td>138.12M</td>\n", - " </tr>\n", - " <tr>\n", - " <th>3</th>\n", - " <td>3</td>\n", - " <td>Sing</td>\n", - " <td>Animation,Comedy,Family</td>\n", - " <td>Christophe Lourdelet</td>\n", - " <td>Matthew McConaughey,Reese Witherspoon, Seth Ma...</td>\n", - " <td>2016</td>\n", - " <td>108</td>\n", - " <td>7.2</td>\n", - " <td>270.32</td>\n", - " </tr>\n", - " <tr>\n", - " <th>4</th>\n", - " <td>4</td>\n", - " <td>Suicide Squad</td>\n", - " <td>Action,Adventure,Fantasy</td>\n", - " <td>David Ayer</td>\n", - " <td>Will Smith, Jared Leto, Margot Robbie, Viola D...</td>\n", - " <td>2016</td>\n", - " <td>123</td>\n", - " <td>6.2</td>\n", - " <td>325.02</td>\n", - " </tr>\n", - " </tbody>\n", - "</table>\n", - "</div>" - ], - "text/plain": [ - " Index Title Genre \\\n", - "0 0 Guardians of the Galaxy Action,Adventure,Sci-Fi \n", - "1 1 Prometheus Adventure,Mystery,Sci-Fi \n", - "2 2 Split Horror,Thriller \n", - "3 3 Sing Animation,Comedy,Family \n", - "4 4 Suicide Squad Action,Adventure,Fantasy \n", - "\n", - " Director Cast \\\n", - "0 James Gunn Chris Pratt, Vin Diesel, Bradley Cooper, Zoe S... \n", - "1 Ridley Scott Noomi Rapace, Logan Marshall-Green, Michael ... \n", - "2 M. Night Shyamalan James McAvoy, Anya Taylor-Joy, Haley Lu Richar... \n", - "3 Christophe Lourdelet Matthew McConaughey,Reese Witherspoon, Seth Ma... \n", - "4 David Ayer Will Smith, Jared Leto, Margot Robbie, Viola D... \n", - "\n", - " Year Runtime Rating Revenue \n", - "0 2014 121 8.1 333.13 \n", - "1 2012 124 7.0 126.46M \n", - "2 2016 117 7.3 138.12M \n", - "3 2016 108 7.2 270.32 \n", - "4 2016 123 6.2 325.02 " - ] - }, - "execution_count": 47, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "df.head()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### get the first 2 rows" - ] - }, - { - "cell_type": "code", - "execution_count": 48, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "<div>\n", - "<style scoped>\n", - " .dataframe tbody tr th:only-of-type {\n", - " vertical-align: middle;\n", - " }\n", - "\n", - " .dataframe tbody tr th {\n", - " vertical-align: top;\n", - " }\n", - "\n", - " .dataframe thead th {\n", - " text-align: right;\n", - " }\n", - "</style>\n", - "<table border=\"1\" class=\"dataframe\">\n", - " <thead>\n", - " <tr style=\"text-align: right;\">\n", - " <th></th>\n", - " <th>Index</th>\n", - " <th>Title</th>\n", - " <th>Genre</th>\n", - " <th>Director</th>\n", - " <th>Cast</th>\n", - " <th>Year</th>\n", - " <th>Runtime</th>\n", - " <th>Rating</th>\n", - " <th>Revenue</th>\n", - " </tr>\n", - " </thead>\n", - " <tbody>\n", - " <tr>\n", - " <th>0</th>\n", - " <td>0</td>\n", - " <td>Guardians of the Galaxy</td>\n", - " <td>Action,Adventure,Sci-Fi</td>\n", - " <td>James Gunn</td>\n", - " <td>Chris Pratt, Vin Diesel, Bradley Cooper, Zoe S...</td>\n", - " <td>2014</td>\n", - " <td>121</td>\n", - " <td>8.1</td>\n", - " <td>333.13</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1</th>\n", - " <td>1</td>\n", - " <td>Prometheus</td>\n", - " <td>Adventure,Mystery,Sci-Fi</td>\n", - " <td>Ridley Scott</td>\n", - " <td>Noomi Rapace, Logan Marshall-Green, Michael ...</td>\n", - " <td>2012</td>\n", - " <td>124</td>\n", - " <td>7.0</td>\n", - " <td>126.46M</td>\n", - " </tr>\n", - " </tbody>\n", - "</table>\n", - "</div>" - ], - "text/plain": [ - " Index Title Genre Director \\\n", - "0 0 Guardians of the Galaxy Action,Adventure,Sci-Fi James Gunn \n", - "1 1 Prometheus Adventure,Mystery,Sci-Fi Ridley Scott \n", - "\n", - " Cast Year Runtime Rating \\\n", - "0 Chris Pratt, Vin Diesel, Bradley Cooper, Zoe S... 2014 121 8.1 \n", - "1 Noomi Rapace, Logan Marshall-Green, Michael ... 2012 124 7.0 \n", - "\n", - " Revenue \n", - "0 333.13 \n", - "1 126.46M " - ] - }, - "execution_count": 48, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "df.head(2)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### View the first few lines of the DataFrame\n", - "- `.tail(n)` gets the last n lines, 5 is the default" - ] - }, - { - "cell_type": "code", - "execution_count": 49, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "<div>\n", - "<style scoped>\n", - " .dataframe tbody tr th:only-of-type {\n", - " vertical-align: middle;\n", - " }\n", - "\n", - " .dataframe tbody tr th {\n", - " vertical-align: top;\n", - " }\n", - "\n", - " .dataframe thead th {\n", - " text-align: right;\n", - " }\n", - "</style>\n", - "<table border=\"1\" class=\"dataframe\">\n", - " <thead>\n", - " <tr style=\"text-align: right;\">\n", - " <th></th>\n", - " <th>Index</th>\n", - " <th>Title</th>\n", - " <th>Genre</th>\n", - " <th>Director</th>\n", - " <th>Cast</th>\n", - " <th>Year</th>\n", - " <th>Runtime</th>\n", - " <th>Rating</th>\n", - " <th>Revenue</th>\n", - " </tr>\n", - " </thead>\n", - " <tbody>\n", - " <tr>\n", - " <th>1063</th>\n", - " <td>1063</td>\n", - " <td>Guardians of the Galaxy Vol. 2</td>\n", - " <td>Action, Adventure, Comedy</td>\n", - " <td>James Gunn</td>\n", - " <td>Chris Pratt, Zoe Saldana, Dave Bautista, Vin D...</td>\n", - " <td>2017</td>\n", - " <td>136</td>\n", - " <td>7.6</td>\n", - " <td>389.81</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1064</th>\n", - " <td>1064</td>\n", - " <td>Baby Driver</td>\n", - " <td>Action, Crime, Drama</td>\n", - " <td>Edgar Wright</td>\n", - " <td>Ansel Elgort, Jon Bernthal, Jon Hamm, Eiza Gon...</td>\n", - " <td>2017</td>\n", - " <td>113</td>\n", - " <td>7.6</td>\n", - " <td>107.83</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1065</th>\n", - " <td>1065</td>\n", - " <td>Only the Brave</td>\n", - " <td>Action, Biography, Drama</td>\n", - " <td>Joseph Kosinski</td>\n", - " <td>Josh Brolin, Miles Teller, Jeff Bridges, Jenni...</td>\n", - " <td>2017</td>\n", - " <td>134</td>\n", - " <td>7.6</td>\n", - " <td>18.34</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1066</th>\n", - " <td>1066</td>\n", - " <td>Incredibles 2</td>\n", - " <td>Animation, Action, Adventure</td>\n", - " <td>Brad Bird</td>\n", - " <td>Craig T. Nelson, Holly Hunter, Sarah Vowell, H...</td>\n", - " <td>2018</td>\n", - " <td>118</td>\n", - " <td>7.6</td>\n", - " <td>608.58</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1067</th>\n", - " <td>1067</td>\n", - " <td>A Star Is Born</td>\n", - " <td>Drama, Music, Romance</td>\n", - " <td>Bradley Cooper</td>\n", - " <td>Lady Gaga, Bradley Cooper, Sam Elliott, Greg G...</td>\n", - " <td>2018</td>\n", - " <td>136</td>\n", - " <td>7.6</td>\n", - " <td>215.29</td>\n", - " </tr>\n", - " </tbody>\n", - "</table>\n", - "</div>" - ], - "text/plain": [ - " Index Title Genre \\\n", - "1063 1063 Guardians of the Galaxy Vol. 2 Action, Adventure, Comedy \n", - "1064 1064 Baby Driver Action, Crime, Drama \n", - "1065 1065 Only the Brave Action, Biography, Drama \n", - "1066 1066 Incredibles 2 Animation, Action, Adventure \n", - "1067 1067 A Star Is Born Drama, Music, Romance \n", - "\n", - " Director Cast \\\n", - "1063 James Gunn Chris Pratt, Zoe Saldana, Dave Bautista, Vin D... \n", - "1064 Edgar Wright Ansel Elgort, Jon Bernthal, Jon Hamm, Eiza Gon... \n", - "1065 Joseph Kosinski Josh Brolin, Miles Teller, Jeff Bridges, Jenni... \n", - "1066 Brad Bird Craig T. Nelson, Holly Hunter, Sarah Vowell, H... \n", - "1067 Bradley Cooper Lady Gaga, Bradley Cooper, Sam Elliott, Greg G... \n", - "\n", - " Year Runtime Rating Revenue \n", - "1063 2017 136 7.6 389.81 \n", - "1064 2017 113 7.6 107.83 \n", - "1065 2017 134 7.6 18.34 \n", - "1066 2018 118 7.6 608.58 \n", - "1067 2018 136 7.6 215.29 " - ] - }, - "execution_count": 49, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "df.tail()" - ] - }, - { - "cell_type": "code", - "execution_count": 50, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "<div>\n", - "<style scoped>\n", - " .dataframe tbody tr th:only-of-type {\n", - " vertical-align: middle;\n", - " }\n", - "\n", - " .dataframe tbody tr th {\n", - " vertical-align: top;\n", - " }\n", - "\n", - " .dataframe thead th {\n", - " text-align: right;\n", - " }\n", - "</style>\n", - "<table border=\"1\" class=\"dataframe\">\n", - " <thead>\n", - " <tr style=\"text-align: right;\">\n", - " <th></th>\n", - " <th>Index</th>\n", - " <th>Title</th>\n", - " <th>Genre</th>\n", - " <th>Director</th>\n", - " <th>Cast</th>\n", - " <th>Year</th>\n", - " <th>Runtime</th>\n", - " <th>Rating</th>\n", - " <th>Revenue</th>\n", - " </tr>\n", - " </thead>\n", - " <tbody>\n", - " <tr>\n", - " <th>1065</th>\n", - " <td>1065</td>\n", - " <td>Only the Brave</td>\n", - " <td>Action, Biography, Drama</td>\n", - " <td>Joseph Kosinski</td>\n", - " <td>Josh Brolin, Miles Teller, Jeff Bridges, Jenni...</td>\n", - " <td>2017</td>\n", - " <td>134</td>\n", - " <td>7.6</td>\n", - " <td>18.34</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1066</th>\n", - " <td>1066</td>\n", - " <td>Incredibles 2</td>\n", - " <td>Animation, Action, Adventure</td>\n", - " <td>Brad Bird</td>\n", - " <td>Craig T. Nelson, Holly Hunter, Sarah Vowell, H...</td>\n", - " <td>2018</td>\n", - " <td>118</td>\n", - " <td>7.6</td>\n", - " <td>608.58</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1067</th>\n", - " <td>1067</td>\n", - " <td>A Star Is Born</td>\n", - " <td>Drama, Music, Romance</td>\n", - " <td>Bradley Cooper</td>\n", - " <td>Lady Gaga, Bradley Cooper, Sam Elliott, Greg G...</td>\n", - " <td>2018</td>\n", - " <td>136</td>\n", - " <td>7.6</td>\n", - " <td>215.29</td>\n", - " </tr>\n", - " </tbody>\n", - "</table>\n", - "</div>" - ], - "text/plain": [ - " Index Title Genre Director \\\n", - "1065 1065 Only the Brave Action, Biography, Drama Joseph Kosinski \n", - "1066 1066 Incredibles 2 Animation, Action, Adventure Brad Bird \n", - "1067 1067 A Star Is Born Drama, Music, Romance Bradley Cooper \n", - "\n", - " Cast Year Runtime \\\n", - "1065 Josh Brolin, Miles Teller, Jeff Bridges, Jenni... 2017 134 \n", - "1066 Craig T. Nelson, Holly Hunter, Sarah Vowell, H... 2018 118 \n", - "1067 Lady Gaga, Bradley Cooper, Sam Elliott, Greg G... 2018 136 \n", - "\n", - " Rating Revenue \n", - "1065 7.6 18.34 \n", - "1066 7.6 608.58 \n", - "1067 7.6 215.29 " - ] - }, - "execution_count": 50, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "df.tail(3)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### What are the first and the last years in our dataset?" - ] - }, - { - "cell_type": "code", - "execution_count": 51, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "First year: 2006, Last year: 2020\n" - ] - } - ], - "source": [ - "print(\"First year: {}, Last year: {}\".format(df[\"Year\"].min(), df[\"Year\"].max()))" - ] - }, - { - "cell_type": "code", - "execution_count": 52, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "<div>\n", - "<style scoped>\n", - " .dataframe tbody tr th:only-of-type {\n", - " vertical-align: middle;\n", - " }\n", - "\n", - " .dataframe tbody tr th {\n", - " vertical-align: top;\n", - " }\n", - "\n", - " .dataframe thead th {\n", - " text-align: right;\n", - " }\n", - "</style>\n", - "<table border=\"1\" class=\"dataframe\">\n", - " <thead>\n", - " <tr style=\"text-align: right;\">\n", - " <th></th>\n", - " <th>Index</th>\n", - " <th>Title</th>\n", - " <th>Genre</th>\n", - " <th>Director</th>\n", - " <th>Cast</th>\n", - " <th>Year</th>\n", - " <th>Runtime</th>\n", - " <th>Rating</th>\n", - " <th>Revenue</th>\n", - " </tr>\n", - " </thead>\n", - " <tbody>\n", - " <tr>\n", - " <th>114</th>\n", - " <td>114</td>\n", - " <td>Harry Potter and the Deathly Hallows: Part 2</td>\n", - " <td>Adventure,Drama,Fantasy</td>\n", - " <td>David Yates</td>\n", - " <td>Daniel Radcliffe, Emma Watson, Rupert Grint, M...</td>\n", - " <td>2011</td>\n", - " <td>130</td>\n", - " <td>8.1</td>\n", - " <td>380.96</td>\n", - " </tr>\n", - " <tr>\n", - " <th>314</th>\n", - " <td>314</td>\n", - " <td>Harry Potter and the Order of the Phoenix</td>\n", - " <td>Adventure,Family,Fantasy</td>\n", - " <td>David Yates</td>\n", - " <td>Daniel Radcliffe, Emma Watson, Rupert Grint, B...</td>\n", - " <td>2007</td>\n", - " <td>138</td>\n", - " <td>7.5</td>\n", - " <td>292</td>\n", - " </tr>\n", - " <tr>\n", - " <th>417</th>\n", - " <td>417</td>\n", - " <td>Harry Potter and the Deathly Hallows: Part 1</td>\n", - " <td>Adventure,Family,Fantasy</td>\n", - " <td>David Yates</td>\n", - " <td>Daniel Radcliffe, Emma Watson, Rupert Grint, B...</td>\n", - " <td>2010</td>\n", - " <td>146</td>\n", - " <td>7.7</td>\n", - " <td>294.98</td>\n", - " </tr>\n", - " <tr>\n", - " <th>472</th>\n", - " <td>472</td>\n", - " <td>Harry Potter and the Half-Blood Prince</td>\n", - " <td>Adventure,Family,Fantasy</td>\n", - " <td>David Yates</td>\n", - " <td>Daniel Radcliffe, Emma Watson, Rupert Grint, M...</td>\n", - " <td>2009</td>\n", - " <td>153</td>\n", - " <td>7.5</td>\n", - " <td>301.96</td>\n", - " </tr>\n", - " </tbody>\n", - "</table>\n", - "</div>" - ], - "text/plain": [ - " Index Title \\\n", - "114 114 Harry Potter and the Deathly Hallows: Part 2 \n", - "314 314 Harry Potter and the Order of the Phoenix \n", - "417 417 Harry Potter and the Deathly Hallows: Part 1 \n", - "472 472 Harry Potter and the Half-Blood Prince \n", - "\n", - " Genre Director \\\n", - "114 Adventure,Drama,Fantasy David Yates \n", - "314 Adventure,Family,Fantasy David Yates \n", - "417 Adventure,Family,Fantasy David Yates \n", - "472 Adventure,Family,Fantasy David Yates \n", - "\n", - " Cast Year Runtime Rating \\\n", - "114 Daniel Radcliffe, Emma Watson, Rupert Grint, M... 2011 130 8.1 \n", - "314 Daniel Radcliffe, Emma Watson, Rupert Grint, B... 2007 138 7.5 \n", - "417 Daniel Radcliffe, Emma Watson, Rupert Grint, B... 2010 146 7.7 \n", - "472 Daniel Radcliffe, Emma Watson, Rupert Grint, M... 2009 153 7.5 \n", - "\n", - " Revenue \n", - "114 380.96 \n", - "314 292 \n", - "417 294.98 \n", - "472 301.96 " - ] - }, - "execution_count": 52, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "### What are the rows that correspond to movies whose title contains \"Harry\" ? \n", - "df[df[\"Title\"].str.contains(\"Harry\")]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### What is the movie at index 6 ? " - ] - }, - { - "cell_type": "code", - "execution_count": 53, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "Index 6\n", - "Title La La Land\n", - "Genre Comedy,Drama,Music\n", - "Director Damien Chazelle\n", - "Cast Ryan Gosling, Emma Stone, Rosemarie DeWitt, J....\n", - "Year 2016\n", - "Runtime 128\n", - "Rating 8.3\n", - "Revenue 151.06M\n", - "Name: 6, dtype: object" - ] - }, - "execution_count": 53, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "df.iloc[6]" - ] - }, - { - "cell_type": "code", - "execution_count": 54, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "<div>\n", - "<style scoped>\n", - " .dataframe tbody tr th:only-of-type {\n", - " vertical-align: middle;\n", - " }\n", - "\n", - " .dataframe tbody tr th {\n", - " vertical-align: top;\n", - " }\n", - "\n", - " .dataframe thead th {\n", - " text-align: right;\n", - " }\n", - "</style>\n", - "<table border=\"1\" class=\"dataframe\">\n", - " <thead>\n", - " <tr style=\"text-align: right;\">\n", - " <th></th>\n", - " <th>Index</th>\n", - " <th>Title</th>\n", - " <th>Genre</th>\n", - " <th>Director</th>\n", - " <th>Cast</th>\n", - " <th>Year</th>\n", - " <th>Runtime</th>\n", - " <th>Rating</th>\n", - " <th>Revenue</th>\n", - " </tr>\n", - " </thead>\n", - " <tbody>\n", - " <tr>\n", - " <th>0</th>\n", - " <td>0</td>\n", - " <td>Guardians of the Galaxy</td>\n", - " <td>Action,Adventure,Sci-Fi</td>\n", - " <td>James Gunn</td>\n", - " <td>Chris Pratt, Vin Diesel, Bradley Cooper, Zoe S...</td>\n", - " <td>2014</td>\n", - " <td>121</td>\n", - " <td>8.1</td>\n", - " <td>333.13</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1</th>\n", - " <td>1</td>\n", - " <td>Prometheus</td>\n", - " <td>Adventure,Mystery,Sci-Fi</td>\n", - " <td>Ridley Scott</td>\n", - " <td>Noomi Rapace, Logan Marshall-Green, Michael ...</td>\n", - " <td>2012</td>\n", - " <td>124</td>\n", - " <td>7.0</td>\n", - " <td>126.46M</td>\n", - " </tr>\n", - " <tr>\n", - " <th>2</th>\n", - " <td>2</td>\n", - " <td>Split</td>\n", - " <td>Horror,Thriller</td>\n", - " <td>M. Night Shyamalan</td>\n", - " <td>James McAvoy, Anya Taylor-Joy, Haley Lu Richar...</td>\n", - " <td>2016</td>\n", - " <td>117</td>\n", - " <td>7.3</td>\n", - " <td>138.12M</td>\n", - " </tr>\n", - " <tr>\n", - " <th>3</th>\n", - " <td>3</td>\n", - " <td>Sing</td>\n", - " <td>Animation,Comedy,Family</td>\n", - " <td>Christophe Lourdelet</td>\n", - " <td>Matthew McConaughey,Reese Witherspoon, Seth Ma...</td>\n", - " <td>2016</td>\n", - " <td>108</td>\n", - " <td>7.2</td>\n", - " <td>270.32</td>\n", - " </tr>\n", - " <tr>\n", - " <th>4</th>\n", - " <td>4</td>\n", - " <td>Suicide Squad</td>\n", - " <td>Action,Adventure,Fantasy</td>\n", - " <td>David Ayer</td>\n", - " <td>Will Smith, Jared Leto, Margot Robbie, Viola D...</td>\n", - " <td>2016</td>\n", - " <td>123</td>\n", - " <td>6.2</td>\n", - " <td>325.02</td>\n", - " </tr>\n", - " <tr>\n", - " <th>...</th>\n", - " <td>...</td>\n", - " <td>...</td>\n", - " <td>...</td>\n", - " <td>...</td>\n", - " <td>...</td>\n", - " <td>...</td>\n", - " <td>...</td>\n", - " <td>...</td>\n", - " <td>...</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1063</th>\n", - " <td>1063</td>\n", - " <td>Guardians of the Galaxy Vol. 2</td>\n", - " <td>Action, Adventure, Comedy</td>\n", - " <td>James Gunn</td>\n", - " <td>Chris Pratt, Zoe Saldana, Dave Bautista, Vin D...</td>\n", - " <td>2017</td>\n", - " <td>136</td>\n", - " <td>7.6</td>\n", - " <td>389.81</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1064</th>\n", - " <td>1064</td>\n", - " <td>Baby Driver</td>\n", - " <td>Action, Crime, Drama</td>\n", - " <td>Edgar Wright</td>\n", - " <td>Ansel Elgort, Jon Bernthal, Jon Hamm, Eiza Gon...</td>\n", - " <td>2017</td>\n", - " <td>113</td>\n", - " <td>7.6</td>\n", - " <td>107.83</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1065</th>\n", - " <td>1065</td>\n", - " <td>Only the Brave</td>\n", - " <td>Action, Biography, Drama</td>\n", - " <td>Joseph Kosinski</td>\n", - " <td>Josh Brolin, Miles Teller, Jeff Bridges, Jenni...</td>\n", - " <td>2017</td>\n", - " <td>134</td>\n", - " <td>7.6</td>\n", - " <td>18.34</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1066</th>\n", - " <td>1066</td>\n", - " <td>Incredibles 2</td>\n", - " <td>Animation, Action, Adventure</td>\n", - " <td>Brad Bird</td>\n", - " <td>Craig T. Nelson, Holly Hunter, Sarah Vowell, H...</td>\n", - " <td>2018</td>\n", - " <td>118</td>\n", - " <td>7.6</td>\n", - " <td>608.58</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1067</th>\n", - " <td>1067</td>\n", - " <td>A Star Is Born</td>\n", - " <td>Drama, Music, Romance</td>\n", - " <td>Bradley Cooper</td>\n", - " <td>Lady Gaga, Bradley Cooper, Sam Elliott, Greg G...</td>\n", - " <td>2018</td>\n", - " <td>136</td>\n", - " <td>7.6</td>\n", - " <td>215.29</td>\n", - " </tr>\n", - " </tbody>\n", - "</table>\n", - "<p>1068 rows × 9 columns</p>\n", - "</div>" - ], - "text/plain": [ - " Index Title Genre \\\n", - "0 0 Guardians of the Galaxy Action,Adventure,Sci-Fi \n", - "1 1 Prometheus Adventure,Mystery,Sci-Fi \n", - "2 2 Split Horror,Thriller \n", - "3 3 Sing Animation,Comedy,Family \n", - "4 4 Suicide Squad Action,Adventure,Fantasy \n", - "... ... ... ... \n", - "1063 1063 Guardians of the Galaxy Vol. 2 Action, Adventure, Comedy \n", - "1064 1064 Baby Driver Action, Crime, Drama \n", - "1065 1065 Only the Brave Action, Biography, Drama \n", - "1066 1066 Incredibles 2 Animation, Action, Adventure \n", - "1067 1067 A Star Is Born Drama, Music, Romance \n", - "\n", - " Director Cast \\\n", - "0 James Gunn Chris Pratt, Vin Diesel, Bradley Cooper, Zoe S... \n", - "1 Ridley Scott Noomi Rapace, Logan Marshall-Green, Michael ... \n", - "2 M. Night Shyamalan James McAvoy, Anya Taylor-Joy, Haley Lu Richar... \n", - "3 Christophe Lourdelet Matthew McConaughey,Reese Witherspoon, Seth Ma... \n", - "4 David Ayer Will Smith, Jared Leto, Margot Robbie, Viola D... \n", - "... ... ... \n", - "1063 James Gunn Chris Pratt, Zoe Saldana, Dave Bautista, Vin D... \n", - "1064 Edgar Wright Ansel Elgort, Jon Bernthal, Jon Hamm, Eiza Gon... \n", - "1065 Joseph Kosinski Josh Brolin, Miles Teller, Jeff Bridges, Jenni... \n", - "1066 Brad Bird Craig T. Nelson, Holly Hunter, Sarah Vowell, H... \n", - "1067 Bradley Cooper Lady Gaga, Bradley Cooper, Sam Elliott, Greg G... \n", - "\n", - " Year Runtime Rating Revenue \n", - "0 2014 121 8.1 333.13 \n", - "1 2012 124 7.0 126.46M \n", - "2 2016 117 7.3 138.12M \n", - "3 2016 108 7.2 270.32 \n", - "4 2016 123 6.2 325.02 \n", - "... ... ... ... ... \n", - "1063 2017 136 7.6 389.81 \n", - "1064 2017 113 7.6 107.83 \n", - "1065 2017 134 7.6 18.34 \n", - "1066 2018 118 7.6 608.58 \n", - "1067 2018 136 7.6 215.29 \n", - "\n", - "[1068 rows x 9 columns]" - ] - }, - "execution_count": 54, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "df" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Notice that there are two index columns\n", - "- That happened because when you write a csv from pandas to a file, it writes a new index column\n", - "- So if the dataFrame already contains an index, you are going to get two index columns\n", - "- Let's fix that problem" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### How can you use slicing to get just columns with Title and Year?" - ] - }, - { - "cell_type": "code", - "execution_count": 55, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "<div>\n", - "<style scoped>\n", - " .dataframe tbody tr th:only-of-type {\n", - " vertical-align: middle;\n", - " }\n", - "\n", - " .dataframe tbody tr th {\n", - " vertical-align: top;\n", - " }\n", - "\n", - " .dataframe thead th {\n", - " text-align: right;\n", - " }\n", - "</style>\n", - "<table border=\"1\" class=\"dataframe\">\n", - " <thead>\n", - " <tr style=\"text-align: right;\">\n", - " <th></th>\n", - " <th>Title</th>\n", - " <th>Year</th>\n", - " </tr>\n", - " </thead>\n", - " <tbody>\n", - " <tr>\n", - " <th>0</th>\n", - " <td>Guardians of the Galaxy</td>\n", - " <td>2014</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1</th>\n", - " <td>Prometheus</td>\n", - " <td>2012</td>\n", - " </tr>\n", - " <tr>\n", - " <th>2</th>\n", - " <td>Split</td>\n", - " <td>2016</td>\n", - " </tr>\n", - " <tr>\n", - " <th>3</th>\n", - " <td>Sing</td>\n", - " <td>2016</td>\n", - " </tr>\n", - " <tr>\n", - " <th>4</th>\n", - " <td>Suicide Squad</td>\n", - " <td>2016</td>\n", - " </tr>\n", - " <tr>\n", - " <th>...</th>\n", - " <td>...</td>\n", - " <td>...</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1063</th>\n", - " <td>Guardians of the Galaxy Vol. 2</td>\n", - " <td>2017</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1064</th>\n", - " <td>Baby Driver</td>\n", - " <td>2017</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1065</th>\n", - " <td>Only the Brave</td>\n", - " <td>2017</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1066</th>\n", - " <td>Incredibles 2</td>\n", - " <td>2018</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1067</th>\n", - " <td>A Star Is Born</td>\n", - " <td>2018</td>\n", - " </tr>\n", - " </tbody>\n", - "</table>\n", - "<p>1068 rows × 2 columns</p>\n", - "</div>" - ], - "text/plain": [ - " Title Year\n", - "0 Guardians of the Galaxy 2014\n", - "1 Prometheus 2012\n", - "2 Split 2016\n", - "3 Sing 2016\n", - "4 Suicide Squad 2016\n", - "... ... ...\n", - "1063 Guardians of the Galaxy Vol. 2 2017\n", - "1064 Baby Driver 2017\n", - "1065 Only the Brave 2017\n", - "1066 Incredibles 2 2018\n", - "1067 A Star Is Born 2018\n", - "\n", - "[1068 rows x 2 columns]" - ] - }, - "execution_count": 55, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "df2 = df[[\"Title\", \"Year\"]]\n", - "df2\n", - "# notice that this does not have the 'index' column" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### How can you use slicing to get rid of the first column?" - ] - }, - { - "cell_type": "code", - "execution_count": 56, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "<div>\n", - "<style scoped>\n", - " .dataframe tbody tr th:only-of-type {\n", - " vertical-align: middle;\n", - " }\n", - "\n", - " .dataframe tbody tr th {\n", - " vertical-align: top;\n", - " }\n", - "\n", - " .dataframe thead th {\n", - " text-align: right;\n", - " }\n", - "</style>\n", - "<table border=\"1\" class=\"dataframe\">\n", - " <thead>\n", - " <tr style=\"text-align: right;\">\n", - " <th></th>\n", - " <th>Title</th>\n", - " <th>Genre</th>\n", - " <th>Director</th>\n", - " <th>Cast</th>\n", - " <th>Year</th>\n", - " <th>Runtime</th>\n", - " <th>Rating</th>\n", - " <th>Revenue</th>\n", - " </tr>\n", - " </thead>\n", - " <tbody>\n", - " <tr>\n", - " <th>0</th>\n", - " <td>Guardians of the Galaxy</td>\n", - " <td>Action,Adventure,Sci-Fi</td>\n", - " <td>James Gunn</td>\n", - " <td>Chris Pratt, Vin Diesel, Bradley Cooper, Zoe S...</td>\n", - " <td>2014</td>\n", - " <td>121</td>\n", - " <td>8.1</td>\n", - " <td>333.13</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1</th>\n", - " <td>Prometheus</td>\n", - " <td>Adventure,Mystery,Sci-Fi</td>\n", - " <td>Ridley Scott</td>\n", - " <td>Noomi Rapace, Logan Marshall-Green, Michael ...</td>\n", - " <td>2012</td>\n", - " <td>124</td>\n", - " <td>7.0</td>\n", - " <td>126.46M</td>\n", - " </tr>\n", - " <tr>\n", - " <th>2</th>\n", - " <td>Split</td>\n", - " <td>Horror,Thriller</td>\n", - " <td>M. Night Shyamalan</td>\n", - " <td>James McAvoy, Anya Taylor-Joy, Haley Lu Richar...</td>\n", - " <td>2016</td>\n", - " <td>117</td>\n", - " <td>7.3</td>\n", - " <td>138.12M</td>\n", - " </tr>\n", - " <tr>\n", - " <th>3</th>\n", - " <td>Sing</td>\n", - " <td>Animation,Comedy,Family</td>\n", - " <td>Christophe Lourdelet</td>\n", - " <td>Matthew McConaughey,Reese Witherspoon, Seth Ma...</td>\n", - " <td>2016</td>\n", - " <td>108</td>\n", - " <td>7.2</td>\n", - " <td>270.32</td>\n", - " </tr>\n", - " <tr>\n", - " <th>4</th>\n", - " <td>Suicide Squad</td>\n", - " <td>Action,Adventure,Fantasy</td>\n", - " <td>David Ayer</td>\n", - " <td>Will Smith, Jared Leto, Margot Robbie, Viola D...</td>\n", - " <td>2016</td>\n", - " <td>123</td>\n", - " <td>6.2</td>\n", - " <td>325.02</td>\n", - " </tr>\n", - " <tr>\n", - " <th>...</th>\n", - " <td>...</td>\n", - " <td>...</td>\n", - " <td>...</td>\n", - " <td>...</td>\n", - " <td>...</td>\n", - " <td>...</td>\n", - " <td>...</td>\n", - " <td>...</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1063</th>\n", - " <td>Guardians of the Galaxy Vol. 2</td>\n", - " <td>Action, Adventure, Comedy</td>\n", - " <td>James Gunn</td>\n", - " <td>Chris Pratt, Zoe Saldana, Dave Bautista, Vin D...</td>\n", - " <td>2017</td>\n", - " <td>136</td>\n", - " <td>7.6</td>\n", - " <td>389.81</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1064</th>\n", - " <td>Baby Driver</td>\n", - " <td>Action, Crime, Drama</td>\n", - " <td>Edgar Wright</td>\n", - " <td>Ansel Elgort, Jon Bernthal, Jon Hamm, Eiza Gon...</td>\n", - " <td>2017</td>\n", - " <td>113</td>\n", - " <td>7.6</td>\n", - " <td>107.83</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1065</th>\n", - " <td>Only the Brave</td>\n", - " <td>Action, Biography, Drama</td>\n", - " <td>Joseph Kosinski</td>\n", - " <td>Josh Brolin, Miles Teller, Jeff Bridges, Jenni...</td>\n", - " <td>2017</td>\n", - " <td>134</td>\n", - " <td>7.6</td>\n", - " <td>18.34</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1066</th>\n", - " <td>Incredibles 2</td>\n", - " <td>Animation, Action, Adventure</td>\n", - " <td>Brad Bird</td>\n", - " <td>Craig T. Nelson, Holly Hunter, Sarah Vowell, H...</td>\n", - " <td>2018</td>\n", - " <td>118</td>\n", - " <td>7.6</td>\n", - " <td>608.58</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1067</th>\n", - " <td>A Star Is Born</td>\n", - " <td>Drama, Music, Romance</td>\n", - " <td>Bradley Cooper</td>\n", - " <td>Lady Gaga, Bradley Cooper, Sam Elliott, Greg G...</td>\n", - " <td>2018</td>\n", - " <td>136</td>\n", - " <td>7.6</td>\n", - " <td>215.29</td>\n", - " </tr>\n", - " </tbody>\n", - "</table>\n", - "<p>1068 rows × 8 columns</p>\n", - "</div>" - ], - "text/plain": [ - " Title Genre \\\n", - "0 Guardians of the Galaxy Action,Adventure,Sci-Fi \n", - "1 Prometheus Adventure,Mystery,Sci-Fi \n", - "2 Split Horror,Thriller \n", - "3 Sing Animation,Comedy,Family \n", - "4 Suicide Squad Action,Adventure,Fantasy \n", - "... ... ... \n", - "1063 Guardians of the Galaxy Vol. 2 Action, Adventure, Comedy \n", - "1064 Baby Driver Action, Crime, Drama \n", - "1065 Only the Brave Action, Biography, Drama \n", - "1066 Incredibles 2 Animation, Action, Adventure \n", - "1067 A Star Is Born Drama, Music, Romance \n", - "\n", - " Director Cast \\\n", - "0 James Gunn Chris Pratt, Vin Diesel, Bradley Cooper, Zoe S... \n", - "1 Ridley Scott Noomi Rapace, Logan Marshall-Green, Michael ... \n", - "2 M. Night Shyamalan James McAvoy, Anya Taylor-Joy, Haley Lu Richar... \n", - "3 Christophe Lourdelet Matthew McConaughey,Reese Witherspoon, Seth Ma... \n", - "4 David Ayer Will Smith, Jared Leto, Margot Robbie, Viola D... \n", - "... ... ... \n", - "1063 James Gunn Chris Pratt, Zoe Saldana, Dave Bautista, Vin D... \n", - "1064 Edgar Wright Ansel Elgort, Jon Bernthal, Jon Hamm, Eiza Gon... \n", - "1065 Joseph Kosinski Josh Brolin, Miles Teller, Jeff Bridges, Jenni... \n", - "1066 Brad Bird Craig T. Nelson, Holly Hunter, Sarah Vowell, H... \n", - "1067 Bradley Cooper Lady Gaga, Bradley Cooper, Sam Elliott, Greg G... \n", - "\n", - " Year Runtime Rating Revenue \n", - "0 2014 121 8.1 333.13 \n", - "1 2012 124 7.0 126.46M \n", - "2 2016 117 7.3 138.12M \n", - "3 2016 108 7.2 270.32 \n", - "4 2016 123 6.2 325.02 \n", - "... ... ... ... ... \n", - "1063 2017 136 7.6 389.81 \n", - "1064 2017 113 7.6 107.83 \n", - "1065 2017 134 7.6 18.34 \n", - "1066 2018 118 7.6 608.58 \n", - "1067 2018 136 7.6 215.29 \n", - "\n", - "[1068 rows x 8 columns]" - ] - }, - "execution_count": 56, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "df = df.iloc[:, 1:] #all the rows, not column 0\n", - "df" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Write a df to a csv file" - ] - }, - { - "cell_type": "code", - "execution_count": 57, - "metadata": {}, - "outputs": [], - "source": [ - "df.to_csv(\"better_movies.csv\", index = False)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Practice on your own.....Data Analysis with Data Frames\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### What are all the movies that have above average run time (long movies)? " - ] - }, - { - "cell_type": "code", - "execution_count": 58, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "<div>\n", - "<style scoped>\n", - " .dataframe tbody tr th:only-of-type {\n", - " vertical-align: middle;\n", - " }\n", - "\n", - " .dataframe tbody tr th {\n", - " vertical-align: top;\n", - " }\n", - "\n", - " .dataframe thead th {\n", - " text-align: right;\n", - " }\n", - "</style>\n", - "<table border=\"1\" class=\"dataframe\">\n", - " <thead>\n", - " <tr style=\"text-align: right;\">\n", - " <th></th>\n", - " <th>Title</th>\n", - " <th>Genre</th>\n", - " <th>Director</th>\n", - " <th>Cast</th>\n", - " <th>Year</th>\n", - " <th>Runtime</th>\n", - " <th>Rating</th>\n", - " <th>Revenue</th>\n", - " </tr>\n", - " </thead>\n", - " <tbody>\n", - " <tr>\n", - " <th>0</th>\n", - " <td>Guardians of the Galaxy</td>\n", - " <td>Action,Adventure,Sci-Fi</td>\n", - " <td>James Gunn</td>\n", - " <td>Chris Pratt, Vin Diesel, Bradley Cooper, Zoe S...</td>\n", - " <td>2014</td>\n", - " <td>121</td>\n", - " <td>8.1</td>\n", - " <td>333.13</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1</th>\n", - " <td>Prometheus</td>\n", - " <td>Adventure,Mystery,Sci-Fi</td>\n", - " <td>Ridley Scott</td>\n", - " <td>Noomi Rapace, Logan Marshall-Green, Michael ...</td>\n", - " <td>2012</td>\n", - " <td>124</td>\n", - " <td>7.0</td>\n", - " <td>126.46M</td>\n", - " </tr>\n", - " <tr>\n", - " <th>2</th>\n", - " <td>Split</td>\n", - " <td>Horror,Thriller</td>\n", - " <td>M. Night Shyamalan</td>\n", - " <td>James McAvoy, Anya Taylor-Joy, Haley Lu Richar...</td>\n", - " <td>2016</td>\n", - " <td>117</td>\n", - " <td>7.3</td>\n", - " <td>138.12M</td>\n", - " </tr>\n", - " <tr>\n", - " <th>4</th>\n", - " <td>Suicide Squad</td>\n", - " <td>Action,Adventure,Fantasy</td>\n", - " <td>David Ayer</td>\n", - " <td>Will Smith, Jared Leto, Margot Robbie, Viola D...</td>\n", - " <td>2016</td>\n", - " <td>123</td>\n", - " <td>6.2</td>\n", - " <td>325.02</td>\n", - " </tr>\n", - " <tr>\n", - " <th>6</th>\n", - " <td>La La Land</td>\n", - " <td>Comedy,Drama,Music</td>\n", - " <td>Damien Chazelle</td>\n", - " <td>Ryan Gosling, Emma Stone, Rosemarie DeWitt, J....</td>\n", - " <td>2016</td>\n", - " <td>128</td>\n", - " <td>8.3</td>\n", - " <td>151.06M</td>\n", - " </tr>\n", - " <tr>\n", - " <th>...</th>\n", - " <td>...</td>\n", - " <td>...</td>\n", - " <td>...</td>\n", - " <td>...</td>\n", - " <td>...</td>\n", - " <td>...</td>\n", - " <td>...</td>\n", - " <td>...</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1060</th>\n", - " <td>Just Mercy</td>\n", - " <td>Biography, Crime, Drama</td>\n", - " <td>Destin Daniel Cretton</td>\n", - " <td>Michael B. Jordan, Jamie Foxx, Brie Larson, Ch...</td>\n", - " <td>2019</td>\n", - " <td>137</td>\n", - " <td>7.6</td>\n", - " <td>50.4</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1063</th>\n", - " <td>Guardians of the Galaxy Vol. 2</td>\n", - " <td>Action, Adventure, Comedy</td>\n", - " <td>James Gunn</td>\n", - " <td>Chris Pratt, Zoe Saldana, Dave Bautista, Vin D...</td>\n", - " <td>2017</td>\n", - " <td>136</td>\n", - " <td>7.6</td>\n", - " <td>389.81</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1065</th>\n", - " <td>Only the Brave</td>\n", - " <td>Action, Biography, Drama</td>\n", - " <td>Joseph Kosinski</td>\n", - " <td>Josh Brolin, Miles Teller, Jeff Bridges, Jenni...</td>\n", - " <td>2017</td>\n", - " <td>134</td>\n", - " <td>7.6</td>\n", - " <td>18.34</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1066</th>\n", - " <td>Incredibles 2</td>\n", - " <td>Animation, Action, Adventure</td>\n", - " <td>Brad Bird</td>\n", - " <td>Craig T. Nelson, Holly Hunter, Sarah Vowell, H...</td>\n", - " <td>2018</td>\n", - " <td>118</td>\n", - " <td>7.6</td>\n", - " <td>608.58</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1067</th>\n", - " <td>A Star Is Born</td>\n", - " <td>Drama, Music, Romance</td>\n", - " <td>Bradley Cooper</td>\n", - " <td>Lady Gaga, Bradley Cooper, Sam Elliott, Greg G...</td>\n", - " <td>2018</td>\n", - " <td>136</td>\n", - " <td>7.6</td>\n", - " <td>215.29</td>\n", - " </tr>\n", - " </tbody>\n", - "</table>\n", - "<p>463 rows × 8 columns</p>\n", - "</div>" - ], - "text/plain": [ - " Title Genre \\\n", - "0 Guardians of the Galaxy Action,Adventure,Sci-Fi \n", - "1 Prometheus Adventure,Mystery,Sci-Fi \n", - "2 Split Horror,Thriller \n", - "4 Suicide Squad Action,Adventure,Fantasy \n", - "6 La La Land Comedy,Drama,Music \n", - "... ... ... \n", - "1060 Just Mercy Biography, Crime, Drama \n", - "1063 Guardians of the Galaxy Vol. 2 Action, Adventure, Comedy \n", - "1065 Only the Brave Action, Biography, Drama \n", - "1066 Incredibles 2 Animation, Action, Adventure \n", - "1067 A Star Is Born Drama, Music, Romance \n", - "\n", - " Director \\\n", - "0 James Gunn \n", - "1 Ridley Scott \n", - "2 M. Night Shyamalan \n", - "4 David Ayer \n", - "6 Damien Chazelle \n", - "... ... \n", - "1060 Destin Daniel Cretton \n", - "1063 James Gunn \n", - "1065 Joseph Kosinski \n", - "1066 Brad Bird \n", - "1067 Bradley Cooper \n", - "\n", - " Cast Year Runtime \\\n", - "0 Chris Pratt, Vin Diesel, Bradley Cooper, Zoe S... 2014 121 \n", - "1 Noomi Rapace, Logan Marshall-Green, Michael ... 2012 124 \n", - "2 James McAvoy, Anya Taylor-Joy, Haley Lu Richar... 2016 117 \n", - "4 Will Smith, Jared Leto, Margot Robbie, Viola D... 2016 123 \n", - "6 Ryan Gosling, Emma Stone, Rosemarie DeWitt, J.... 2016 128 \n", - "... ... ... ... \n", - "1060 Michael B. Jordan, Jamie Foxx, Brie Larson, Ch... 2019 137 \n", - "1063 Chris Pratt, Zoe Saldana, Dave Bautista, Vin D... 2017 136 \n", - "1065 Josh Brolin, Miles Teller, Jeff Bridges, Jenni... 2017 134 \n", - "1066 Craig T. Nelson, Holly Hunter, Sarah Vowell, H... 2018 118 \n", - "1067 Lady Gaga, Bradley Cooper, Sam Elliott, Greg G... 2018 136 \n", - "\n", - " Rating Revenue \n", - "0 8.1 333.13 \n", - "1 7.0 126.46M \n", - "2 7.3 138.12M \n", - "4 6.2 325.02 \n", - "6 8.3 151.06M \n", - "... ... ... \n", - "1060 7.6 50.4 \n", - "1063 7.6 389.81 \n", - "1065 7.6 18.34 \n", - "1066 7.6 608.58 \n", - "1067 7.6 215.29 \n", - "\n", - "[463 rows x 8 columns]" - ] - }, - "execution_count": 58, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "long_movies = df [df[\"Runtime\"] > df[\"Runtime\"].mean()]\n", - "long_movies" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Which long movie has the lowest rating?" - ] - }, - { - "cell_type": "code", - "execution_count": 59, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "3.2" - ] - }, - "execution_count": 59, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "min_rating = long_movies[\"Rating\"].min()\n", - "min_rating" - ] - }, - { - "cell_type": "code", - "execution_count": 60, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "<div>\n", - "<style scoped>\n", - " .dataframe tbody tr th:only-of-type {\n", - " vertical-align: middle;\n", - " }\n", - "\n", - " .dataframe tbody tr th {\n", - " vertical-align: top;\n", - " }\n", - "\n", - " .dataframe thead th {\n", - " text-align: right;\n", - " }\n", - "</style>\n", - "<table border=\"1\" class=\"dataframe\">\n", - " <thead>\n", - " <tr style=\"text-align: right;\">\n", - " <th></th>\n", - " <th>Title</th>\n", - " <th>Genre</th>\n", - " <th>Director</th>\n", - " <th>Cast</th>\n", - " <th>Year</th>\n", - " <th>Runtime</th>\n", - " <th>Rating</th>\n", - " <th>Revenue</th>\n", - " </tr>\n", - " </thead>\n", - " <tbody>\n", - " <tr>\n", - " <th>646</th>\n", - " <td>Tall Men</td>\n", - " <td>Fantasy,Horror,Thriller</td>\n", - " <td>Jonathan Holbrook</td>\n", - " <td>Dan Crisafulli, Kay Whitney, Richard Garcia, P...</td>\n", - " <td>2016</td>\n", - " <td>133</td>\n", - " <td>3.2</td>\n", - " <td>0</td>\n", - " </tr>\n", - " </tbody>\n", - "</table>\n", - "</div>" - ], - "text/plain": [ - " Title Genre Director \\\n", - "646 Tall Men Fantasy,Horror,Thriller Jonathan Holbrook \n", - "\n", - " Cast Year Runtime Rating \\\n", - "646 Dan Crisafulli, Kay Whitney, Richard Garcia, P... 2016 133 3.2 \n", - "\n", - " Revenue \n", - "646 0 " - ] - }, - "execution_count": 60, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Which movies had this min rating?\n", - "long_movies[long_movies[\"Rating\"] == min_rating]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### What are all long movies with someone in the cast named \"Emma\" ? " - ] - }, - { - "cell_type": "code", - "execution_count": 61, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "<div>\n", - "<style scoped>\n", - " .dataframe tbody tr th:only-of-type {\n", - " vertical-align: middle;\n", - " }\n", - "\n", - " .dataframe tbody tr th {\n", - " vertical-align: top;\n", - " }\n", - "\n", - " .dataframe thead th {\n", - " text-align: right;\n", - " }\n", - "</style>\n", - "<table border=\"1\" class=\"dataframe\">\n", - " <thead>\n", - " <tr style=\"text-align: right;\">\n", - " <th></th>\n", - " <th>Title</th>\n", - " <th>Genre</th>\n", - " <th>Director</th>\n", - " <th>Cast</th>\n", - " <th>Year</th>\n", - " <th>Runtime</th>\n", - " <th>Rating</th>\n", - " <th>Revenue</th>\n", - " </tr>\n", - " </thead>\n", - " <tbody>\n", - " <tr>\n", - " <th>6</th>\n", - " <td>La La Land</td>\n", - " <td>Comedy,Drama,Music</td>\n", - " <td>Damien Chazelle</td>\n", - " <td>Ryan Gosling, Emma Stone, Rosemarie DeWitt, J....</td>\n", - " <td>2016</td>\n", - " <td>128</td>\n", - " <td>8.3</td>\n", - " <td>151.06M</td>\n", - " </tr>\n", - " <tr>\n", - " <th>92</th>\n", - " <td>The Help</td>\n", - " <td>Drama</td>\n", - " <td>Tate Taylor</td>\n", - " <td>Emma Stone, Viola Davis, Octavia Spencer, Bryc...</td>\n", - " <td>2011</td>\n", - " <td>146</td>\n", - " <td>8.1</td>\n", - " <td>169.71M</td>\n", - " </tr>\n", - " <tr>\n", - " <th>114</th>\n", - " <td>Harry Potter and the Deathly Hallows: Part 2</td>\n", - " <td>Adventure,Drama,Fantasy</td>\n", - " <td>David Yates</td>\n", - " <td>Daniel Radcliffe, Emma Watson, Rupert Grint, M...</td>\n", - " <td>2011</td>\n", - " <td>130</td>\n", - " <td>8.1</td>\n", - " <td>380.96</td>\n", - " </tr>\n", - " <tr>\n", - " <th>157</th>\n", - " <td>Crazy, Stupid, Love.</td>\n", - " <td>Comedy,Drama,Romance</td>\n", - " <td>Glenn Ficarra</td>\n", - " <td>Steve Carell, Ryan Gosling, Julianne Moore, Em...</td>\n", - " <td>2011</td>\n", - " <td>118</td>\n", - " <td>7.4</td>\n", - " <td>84.24</td>\n", - " </tr>\n", - " <tr>\n", - " <th>253</th>\n", - " <td>The Amazing Spider-Man 2</td>\n", - " <td>Action,Adventure,Sci-Fi</td>\n", - " <td>Marc Webb</td>\n", - " <td>Andrew Garfield, Emma Stone, Jamie Foxx, Paul ...</td>\n", - " <td>2014</td>\n", - " <td>142</td>\n", - " <td>6.7</td>\n", - " <td>202.85</td>\n", - " </tr>\n", - " <tr>\n", - " <th>314</th>\n", - " <td>Harry Potter and the Order of the Phoenix</td>\n", - " <td>Adventure,Family,Fantasy</td>\n", - " <td>David Yates</td>\n", - " <td>Daniel Radcliffe, Emma Watson, Rupert Grint, B...</td>\n", - " <td>2007</td>\n", - " <td>138</td>\n", - " <td>7.5</td>\n", - " <td>292</td>\n", - " </tr>\n", - " <tr>\n", - " <th>367</th>\n", - " <td>The Amazing Spider-Man</td>\n", - " <td>Action,Adventure</td>\n", - " <td>Marc Webb</td>\n", - " <td>Andrew Garfield, Emma Stone, Rhys Ifans, Irrfa...</td>\n", - " <td>2012</td>\n", - " <td>136</td>\n", - " <td>7.0</td>\n", - " <td>262.03</td>\n", - " </tr>\n", - " <tr>\n", - " <th>417</th>\n", - " <td>Harry Potter and the Deathly Hallows: Part 1</td>\n", - " <td>Adventure,Family,Fantasy</td>\n", - " <td>David Yates</td>\n", - " <td>Daniel Radcliffe, Emma Watson, Rupert Grint, B...</td>\n", - " <td>2010</td>\n", - " <td>146</td>\n", - " <td>7.7</td>\n", - " <td>294.98</td>\n", - " </tr>\n", - " <tr>\n", - " <th>472</th>\n", - " <td>Harry Potter and the Half-Blood Prince</td>\n", - " <td>Adventure,Family,Fantasy</td>\n", - " <td>David Yates</td>\n", - " <td>Daniel Radcliffe, Emma Watson, Rupert Grint, M...</td>\n", - " <td>2009</td>\n", - " <td>153</td>\n", - " <td>7.5</td>\n", - " <td>301.96</td>\n", - " </tr>\n", - " <tr>\n", - " <th>609</th>\n", - " <td>Beautiful Creatures</td>\n", - " <td>Drama,Fantasy,Romance</td>\n", - " <td>Richard LaGravenese</td>\n", - " <td>Alice Englert, Viola Davis, Emma Thompson,Alde...</td>\n", - " <td>2013</td>\n", - " <td>124</td>\n", - " <td>6.2</td>\n", - " <td>19.45</td>\n", - " </tr>\n", - " <tr>\n", - " <th>717</th>\n", - " <td>Noah</td>\n", - " <td>Action,Adventure,Drama</td>\n", - " <td>Darren Aronofsky</td>\n", - " <td>Russell Crowe, Jennifer Connelly, Anthony Hopk...</td>\n", - " <td>2014</td>\n", - " <td>138</td>\n", - " <td>5.8</td>\n", - " <td>101.16M</td>\n", - " </tr>\n", - " <tr>\n", - " <th>879</th>\n", - " <td>Saving Mr. Banks</td>\n", - " <td>Biography,Comedy,Drama</td>\n", - " <td>John Lee Hancock</td>\n", - " <td>Emma Thompson, Tom Hanks, Annie Rose Buckley, ...</td>\n", - " <td>2013</td>\n", - " <td>125</td>\n", - " <td>7.5</td>\n", - " <td>83.3</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1044</th>\n", - " <td>Little Women</td>\n", - " <td>Drama, Romance</td>\n", - " <td>Greta Gerwig</td>\n", - " <td>Saoirse Ronan, Emma Watson, Florence Pugh, Eli...</td>\n", - " <td>2019</td>\n", - " <td>135</td>\n", - " <td>7.8</td>\n", - " <td>108.1</td>\n", - " </tr>\n", - " </tbody>\n", - "</table>\n", - "</div>" - ], - "text/plain": [ - " Title Genre \\\n", - "6 La La Land Comedy,Drama,Music \n", - "92 The Help Drama \n", - "114 Harry Potter and the Deathly Hallows: Part 2 Adventure,Drama,Fantasy \n", - "157 Crazy, Stupid, Love. Comedy,Drama,Romance \n", - "253 The Amazing Spider-Man 2 Action,Adventure,Sci-Fi \n", - "314 Harry Potter and the Order of the Phoenix Adventure,Family,Fantasy \n", - "367 The Amazing Spider-Man Action,Adventure \n", - "417 Harry Potter and the Deathly Hallows: Part 1 Adventure,Family,Fantasy \n", - "472 Harry Potter and the Half-Blood Prince Adventure,Family,Fantasy \n", - "609 Beautiful Creatures Drama,Fantasy,Romance \n", - "717 Noah Action,Adventure,Drama \n", - "879 Saving Mr. Banks Biography,Comedy,Drama \n", - "1044 Little Women Drama, Romance \n", - "\n", - " Director Cast \\\n", - "6 Damien Chazelle Ryan Gosling, Emma Stone, Rosemarie DeWitt, J.... \n", - "92 Tate Taylor Emma Stone, Viola Davis, Octavia Spencer, Bryc... \n", - "114 David Yates Daniel Radcliffe, Emma Watson, Rupert Grint, M... \n", - "157 Glenn Ficarra Steve Carell, Ryan Gosling, Julianne Moore, Em... \n", - "253 Marc Webb Andrew Garfield, Emma Stone, Jamie Foxx, Paul ... \n", - "314 David Yates Daniel Radcliffe, Emma Watson, Rupert Grint, B... \n", - "367 Marc Webb Andrew Garfield, Emma Stone, Rhys Ifans, Irrfa... \n", - "417 David Yates Daniel Radcliffe, Emma Watson, Rupert Grint, B... \n", - "472 David Yates Daniel Radcliffe, Emma Watson, Rupert Grint, M... \n", - "609 Richard LaGravenese Alice Englert, Viola Davis, Emma Thompson,Alde... \n", - "717 Darren Aronofsky Russell Crowe, Jennifer Connelly, Anthony Hopk... \n", - "879 John Lee Hancock Emma Thompson, Tom Hanks, Annie Rose Buckley, ... \n", - "1044 Greta Gerwig Saoirse Ronan, Emma Watson, Florence Pugh, Eli... \n", - "\n", - " Year Runtime Rating Revenue \n", - "6 2016 128 8.3 151.06M \n", - "92 2011 146 8.1 169.71M \n", - "114 2011 130 8.1 380.96 \n", - "157 2011 118 7.4 84.24 \n", - "253 2014 142 6.7 202.85 \n", - "314 2007 138 7.5 292 \n", - "367 2012 136 7.0 262.03 \n", - "417 2010 146 7.7 294.98 \n", - "472 2009 153 7.5 301.96 \n", - "609 2013 124 6.2 19.45 \n", - "717 2014 138 5.8 101.16M \n", - "879 2013 125 7.5 83.3 \n", - "1044 2019 135 7.8 108.1 " - ] - }, - "execution_count": 61, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "long_movies[long_movies[\"Cast\"].str.contains(\"Emma\")]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### What is the title of the shortest movie?" - ] - }, - { - "cell_type": "code", - "execution_count": 62, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "792 Ma vie de Courgette\n", - "Name: Title, dtype: object" - ] - }, - "execution_count": 62, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "df[df[\"Runtime\"] == df[\"Runtime\"].min()][\"Title\"]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### What movie had the highest revenue?" - ] - }, - { - "cell_type": "code", - "execution_count": 63, - "metadata": {}, - "outputs": [], - "source": [ - "# What movie had the highest revenue?\n", - "# df[\"Revnue\"].max() did not work\n", - "# we need to clean our data\n", - "\n", - "def format_revenue(revenue):\n", - " #TODO: Check the last character of the string\n", - " if type(revenue) == float: # need this in here if we run code multiple times\n", - " return revenue\n", - " elif revenue[-1] == 'M': # some have an \"M\" at the end\n", - " return float(revenue[:-1]) * 1e6\n", - " else:\n", - " return float(revenue) * 1e6" - ] - }, - { - "cell_type": "code", - "execution_count": 64, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "0 333130000.0\n", - "1 126460000.0\n", - "2 138120000.0\n", - "3 270320000.0\n", - "4 325020000.0\n", - "Name: Revenue, dtype: float64\n" - ] - }, - { - "data": { - "text/html": [ - "<div>\n", - "<style scoped>\n", - " .dataframe tbody tr th:only-of-type {\n", - " vertical-align: middle;\n", - " }\n", - "\n", - " .dataframe tbody tr th {\n", - " vertical-align: top;\n", - " }\n", - "\n", - " .dataframe thead th {\n", - " text-align: right;\n", - " }\n", - "</style>\n", - "<table border=\"1\" class=\"dataframe\">\n", - " <thead>\n", - " <tr style=\"text-align: right;\">\n", - " <th></th>\n", - " <th>Title</th>\n", - " <th>Genre</th>\n", - " <th>Director</th>\n", - " <th>Cast</th>\n", - " <th>Year</th>\n", - " <th>Runtime</th>\n", - " <th>Rating</th>\n", - " <th>Revenue</th>\n", - " <th>Revenue (float)</th>\n", - " </tr>\n", - " </thead>\n", - " <tbody>\n", - " <tr>\n", - " <th>0</th>\n", - " <td>Guardians of the Galaxy</td>\n", - " <td>Action,Adventure,Sci-Fi</td>\n", - " <td>James Gunn</td>\n", - " <td>Chris Pratt, Vin Diesel, Bradley Cooper, Zoe S...</td>\n", - " <td>2014</td>\n", - " <td>121</td>\n", - " <td>8.1</td>\n", - " <td>333.13</td>\n", - " <td>333130000.0</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1</th>\n", - " <td>Prometheus</td>\n", - " <td>Adventure,Mystery,Sci-Fi</td>\n", - " <td>Ridley Scott</td>\n", - " <td>Noomi Rapace, Logan Marshall-Green, Michael ...</td>\n", - " <td>2012</td>\n", - " <td>124</td>\n", - " <td>7.0</td>\n", - " <td>126.46M</td>\n", - " <td>126460000.0</td>\n", - " </tr>\n", - " <tr>\n", - " <th>2</th>\n", - " <td>Split</td>\n", - " <td>Horror,Thriller</td>\n", - " <td>M. Night Shyamalan</td>\n", - " <td>James McAvoy, Anya Taylor-Joy, Haley Lu Richar...</td>\n", - " <td>2016</td>\n", - " <td>117</td>\n", - " <td>7.3</td>\n", - " <td>138.12M</td>\n", - " <td>138120000.0</td>\n", - " </tr>\n", - " <tr>\n", - " <th>3</th>\n", - " <td>Sing</td>\n", - " <td>Animation,Comedy,Family</td>\n", - " <td>Christophe Lourdelet</td>\n", - " <td>Matthew McConaughey,Reese Witherspoon, Seth Ma...</td>\n", - " <td>2016</td>\n", - " <td>108</td>\n", - " <td>7.2</td>\n", - " <td>270.32</td>\n", - " <td>270320000.0</td>\n", - " </tr>\n", - " <tr>\n", - " <th>4</th>\n", - " <td>Suicide Squad</td>\n", - " <td>Action,Adventure,Fantasy</td>\n", - " <td>David Ayer</td>\n", - " <td>Will Smith, Jared Leto, Margot Robbie, Viola D...</td>\n", - " <td>2016</td>\n", - " <td>123</td>\n", - " <td>6.2</td>\n", - " <td>325.02</td>\n", - " <td>325020000.0</td>\n", - " </tr>\n", - " <tr>\n", - " <th>...</th>\n", - " <td>...</td>\n", - " <td>...</td>\n", - " <td>...</td>\n", - " <td>...</td>\n", - " <td>...</td>\n", - " <td>...</td>\n", - " <td>...</td>\n", - " <td>...</td>\n", - " <td>...</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1063</th>\n", - " <td>Guardians of the Galaxy Vol. 2</td>\n", - " <td>Action, Adventure, Comedy</td>\n", - " <td>James Gunn</td>\n", - " <td>Chris Pratt, Zoe Saldana, Dave Bautista, Vin D...</td>\n", - " <td>2017</td>\n", - " <td>136</td>\n", - " <td>7.6</td>\n", - " <td>389.81</td>\n", - " <td>389810000.0</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1064</th>\n", - " <td>Baby Driver</td>\n", - " <td>Action, Crime, Drama</td>\n", - " <td>Edgar Wright</td>\n", - " <td>Ansel Elgort, Jon Bernthal, Jon Hamm, Eiza Gon...</td>\n", - " <td>2017</td>\n", - " <td>113</td>\n", - " <td>7.6</td>\n", - " <td>107.83</td>\n", - " <td>107830000.0</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1065</th>\n", - " <td>Only the Brave</td>\n", - " <td>Action, Biography, Drama</td>\n", - " <td>Joseph Kosinski</td>\n", - " <td>Josh Brolin, Miles Teller, Jeff Bridges, Jenni...</td>\n", - " <td>2017</td>\n", - " <td>134</td>\n", - " <td>7.6</td>\n", - " <td>18.34</td>\n", - " <td>18340000.0</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1066</th>\n", - " <td>Incredibles 2</td>\n", - " <td>Animation, Action, Adventure</td>\n", - " <td>Brad Bird</td>\n", - " <td>Craig T. Nelson, Holly Hunter, Sarah Vowell, H...</td>\n", - " <td>2018</td>\n", - " <td>118</td>\n", - " <td>7.6</td>\n", - " <td>608.58</td>\n", - " <td>608580000.0</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1067</th>\n", - " <td>A Star Is Born</td>\n", - " <td>Drama, Music, Romance</td>\n", - " <td>Bradley Cooper</td>\n", - " <td>Lady Gaga, Bradley Cooper, Sam Elliott, Greg G...</td>\n", - " <td>2018</td>\n", - " <td>136</td>\n", - " <td>7.6</td>\n", - " <td>215.29</td>\n", - " <td>215290000.0</td>\n", - " </tr>\n", - " </tbody>\n", - "</table>\n", - "<p>1068 rows × 9 columns</p>\n", - "</div>" - ], - "text/plain": [ - " Title Genre \\\n", - "0 Guardians of the Galaxy Action,Adventure,Sci-Fi \n", - "1 Prometheus Adventure,Mystery,Sci-Fi \n", - "2 Split Horror,Thriller \n", - "3 Sing Animation,Comedy,Family \n", - "4 Suicide Squad Action,Adventure,Fantasy \n", - "... ... ... \n", - "1063 Guardians of the Galaxy Vol. 2 Action, Adventure, Comedy \n", - "1064 Baby Driver Action, Crime, Drama \n", - "1065 Only the Brave Action, Biography, Drama \n", - "1066 Incredibles 2 Animation, Action, Adventure \n", - "1067 A Star Is Born Drama, Music, Romance \n", - "\n", - " Director Cast \\\n", - "0 James Gunn Chris Pratt, Vin Diesel, Bradley Cooper, Zoe S... \n", - "1 Ridley Scott Noomi Rapace, Logan Marshall-Green, Michael ... \n", - "2 M. Night Shyamalan James McAvoy, Anya Taylor-Joy, Haley Lu Richar... \n", - "3 Christophe Lourdelet Matthew McConaughey,Reese Witherspoon, Seth Ma... \n", - "4 David Ayer Will Smith, Jared Leto, Margot Robbie, Viola D... \n", - "... ... ... \n", - "1063 James Gunn Chris Pratt, Zoe Saldana, Dave Bautista, Vin D... \n", - "1064 Edgar Wright Ansel Elgort, Jon Bernthal, Jon Hamm, Eiza Gon... \n", - "1065 Joseph Kosinski Josh Brolin, Miles Teller, Jeff Bridges, Jenni... \n", - "1066 Brad Bird Craig T. Nelson, Holly Hunter, Sarah Vowell, H... \n", - "1067 Bradley Cooper Lady Gaga, Bradley Cooper, Sam Elliott, Greg G... \n", - "\n", - " Year Runtime Rating Revenue Revenue (float) \n", - "0 2014 121 8.1 333.13 333130000.0 \n", - "1 2012 124 7.0 126.46M 126460000.0 \n", - "2 2016 117 7.3 138.12M 138120000.0 \n", - "3 2016 108 7.2 270.32 270320000.0 \n", - "4 2016 123 6.2 325.02 325020000.0 \n", - "... ... ... ... ... ... \n", - "1063 2017 136 7.6 389.81 389810000.0 \n", - "1064 2017 113 7.6 107.83 107830000.0 \n", - "1065 2017 134 7.6 18.34 18340000.0 \n", - "1066 2018 118 7.6 608.58 608580000.0 \n", - "1067 2018 136 7.6 215.29 215290000.0 \n", - "\n", - "[1068 rows x 9 columns]" - ] - }, - "execution_count": 64, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# What movie had the highest revenue?\n", - "revenue = df[\"Revenue\"].apply(format_revenue) # apply a function to a column\n", - "print(revenue.head())\n", - "max_revenue = revenue.max()\n", - "\n", - "# make a copy of our df\n", - "rev_df = df.copy()\n", - "rev_df[\"Revenue (float)\"] = revenue\n", - "rev_df" - ] - }, - { - "cell_type": "code", - "execution_count": 65, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "<div>\n", - "<style scoped>\n", - " .dataframe tbody tr th:only-of-type {\n", - " vertical-align: middle;\n", - " }\n", - "\n", - " .dataframe tbody tr th {\n", - " vertical-align: top;\n", - " }\n", - "\n", - " .dataframe thead th {\n", - " text-align: right;\n", - " }\n", - "</style>\n", - "<table border=\"1\" class=\"dataframe\">\n", - " <thead>\n", - " <tr style=\"text-align: right;\">\n", - " <th></th>\n", - " <th>Title</th>\n", - " <th>Genre</th>\n", - " <th>Director</th>\n", - " <th>Cast</th>\n", - " <th>Year</th>\n", - " <th>Runtime</th>\n", - " <th>Rating</th>\n", - " <th>Revenue</th>\n", - " <th>Revenue (float)</th>\n", - " </tr>\n", - " </thead>\n", - " <tbody>\n", - " <tr>\n", - " <th>50</th>\n", - " <td>Star Wars: Episode VII - The Force Awakens</td>\n", - " <td>Action,Adventure,Fantasy</td>\n", - " <td>J.J. Abrams</td>\n", - " <td>Daisy Ridley, John Boyega, Oscar Isaac, Domhna...</td>\n", - " <td>2015</td>\n", - " <td>136</td>\n", - " <td>8.1</td>\n", - " <td>936.63</td>\n", - " <td>936630000.0</td>\n", - " </tr>\n", - " </tbody>\n", - "</table>\n", - "</div>" - ], - "text/plain": [ - " Title Genre \\\n", - "50 Star Wars: Episode VII - The Force Awakens Action,Adventure,Fantasy \n", - "\n", - " Director Cast Year \\\n", - "50 J.J. Abrams Daisy Ridley, John Boyega, Oscar Isaac, Domhna... 2015 \n", - "\n", - " Runtime Rating Revenue Revenue (float) \n", - "50 136 8.1 936.63 936630000.0 " - ] - }, - "execution_count": 65, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Now we can answer the question!\n", - "rev_df[rev_df[\"Revenue (float)\"] == max_revenue]" - ] - }, - { - "cell_type": "code", - "execution_count": 66, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "<div>\n", - "<style scoped>\n", - " .dataframe tbody tr th:only-of-type {\n", - " vertical-align: middle;\n", - " }\n", - "\n", - " .dataframe tbody tr th {\n", - " vertical-align: top;\n", - " }\n", - "\n", - " .dataframe thead th {\n", - " text-align: right;\n", - " }\n", - "</style>\n", - "<table border=\"1\" class=\"dataframe\">\n", - " <thead>\n", - " <tr style=\"text-align: right;\">\n", - " <th></th>\n", - " <th>Title</th>\n", - " <th>Genre</th>\n", - " <th>Director</th>\n", - " <th>Cast</th>\n", - " <th>Year</th>\n", - " <th>Runtime</th>\n", - " <th>Rating</th>\n", - " <th>Revenue</th>\n", - " <th>Revenue (float)</th>\n", - " </tr>\n", - " </thead>\n", - " <tbody>\n", - " <tr>\n", - " <th>50</th>\n", - " <td>Star Wars: Episode VII - The Force Awakens</td>\n", - " <td>Action,Adventure,Fantasy</td>\n", - " <td>J.J. Abrams</td>\n", - " <td>Daisy Ridley, John Boyega, Oscar Isaac, Domhna...</td>\n", - " <td>2015</td>\n", - " <td>136</td>\n", - " <td>8.1</td>\n", - " <td>936.63</td>\n", - " <td>936630000.0</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1006</th>\n", - " <td>Avengers: Endgame</td>\n", - " <td>Action, Adventure, Drama</td>\n", - " <td>Anthony Russo</td>\n", - " <td>Joe Russo, Robert Downey Jr., Chris Evans, Mar...</td>\n", - " <td>2019</td>\n", - " <td>181</td>\n", - " <td>8.4</td>\n", - " <td>858.37</td>\n", - " <td>858370000.0</td>\n", - " </tr>\n", - " <tr>\n", - " <th>87</th>\n", - " <td>Avatar</td>\n", - " <td>Action,Adventure,Fantasy</td>\n", - " <td>James Cameron</td>\n", - " <td>Sam Worthington, Zoe Saldana, Sigourney Weaver...</td>\n", - " <td>2009</td>\n", - " <td>162</td>\n", - " <td>7.8</td>\n", - " <td>760.51</td>\n", - " <td>760510000.0</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1007</th>\n", - " <td>Avengers: Infinity War</td>\n", - " <td>Action, Adventure, Sci-Fi</td>\n", - " <td>Anthony Russo</td>\n", - " <td>Joe Russo, Robert Downey Jr., Chris Hemsworth,...</td>\n", - " <td>2018</td>\n", - " <td>149</td>\n", - " <td>8.4</td>\n", - " <td>678.82</td>\n", - " <td>678820000.0</td>\n", - " </tr>\n", - " <tr>\n", - " <th>85</th>\n", - " <td>Jurassic World</td>\n", - " <td>Action,Adventure,Sci-Fi</td>\n", - " <td>Colin Trevorrow</td>\n", - " <td>Chris Pratt, Bryce Dallas Howard, Ty Simpkins,...</td>\n", - " <td>2015</td>\n", - " <td>124</td>\n", - " <td>7.0</td>\n", - " <td>652.18</td>\n", - " <td>652180000.0</td>\n", - " </tr>\n", - " <tr>\n", - " <th>...</th>\n", - " <td>...</td>\n", - " <td>...</td>\n", - " <td>...</td>\n", - " <td>...</td>\n", - " <td>...</td>\n", - " <td>...</td>\n", - " <td>...</td>\n", - " <td>...</td>\n", - " <td>...</td>\n", - " </tr>\n", - " <tr>\n", - " <th>974</th>\n", - " <td>Dark Places</td>\n", - " <td>Drama,Mystery,Thriller</td>\n", - " <td>Gilles Paquet-Brenner</td>\n", - " <td>Charlize Theron, Nicholas Hoult, Christina Hen...</td>\n", - " <td>2015</td>\n", - " <td>113</td>\n", - " <td>6.2</td>\n", - " <td>0</td>\n", - " <td>0.0</td>\n", - " </tr>\n", - " <tr>\n", - " <th>183</th>\n", - " <td>Realive</td>\n", - " <td>Sci-Fi</td>\n", - " <td>Mateo Gil</td>\n", - " <td>Tom Hughes, Charlotte Le Bon, Oona Chaplin, Ba...</td>\n", - " <td>2016</td>\n", - " <td>112</td>\n", - " <td>5.9</td>\n", - " <td>0</td>\n", - " <td>0.0</td>\n", - " </tr>\n", - " <tr>\n", - " <th>218</th>\n", - " <td>A Dark Song</td>\n", - " <td>Drama,Horror</td>\n", - " <td>Liam Gavin</td>\n", - " <td>Mark Huberman, Susan Loughnane, Steve Oram,Cat...</td>\n", - " <td>2016</td>\n", - " <td>100</td>\n", - " <td>6.1</td>\n", - " <td>0</td>\n", - " <td>0.0</td>\n", - " </tr>\n", - " <tr>\n", - " <th>397</th>\n", - " <td>Absolutely Anything</td>\n", - " <td>Comedy,Sci-Fi</td>\n", - " <td>Terry Jones</td>\n", - " <td>Simon Pegg, Kate Beckinsale, Sanjeev Bhaskar, ...</td>\n", - " <td>2015</td>\n", - " <td>85</td>\n", - " <td>6.0</td>\n", - " <td>0</td>\n", - " <td>0.0</td>\n", - " </tr>\n", - " <tr>\n", - " <th>815</th>\n", - " <td>I.T.</td>\n", - " <td>Crime,Drama,Mystery</td>\n", - " <td>John Moore</td>\n", - " <td>Pierce Brosnan, Jason Barry, Karen Moskow, Kai...</td>\n", - " <td>2016</td>\n", - " <td>95</td>\n", - " <td>5.4</td>\n", - " <td>0</td>\n", - " <td>0.0</td>\n", - " </tr>\n", - " </tbody>\n", - "</table>\n", - "<p>1068 rows × 9 columns</p>\n", - "</div>" - ], - "text/plain": [ - " Title Genre \\\n", - "50 Star Wars: Episode VII - The Force Awakens Action,Adventure,Fantasy \n", - "1006 Avengers: Endgame Action, Adventure, Drama \n", - "87 Avatar Action,Adventure,Fantasy \n", - "1007 Avengers: Infinity War Action, Adventure, Sci-Fi \n", - "85 Jurassic World Action,Adventure,Sci-Fi \n", - "... ... ... \n", - "974 Dark Places Drama,Mystery,Thriller \n", - "183 Realive Sci-Fi \n", - "218 A Dark Song Drama,Horror \n", - "397 Absolutely Anything Comedy,Sci-Fi \n", - "815 I.T. Crime,Drama,Mystery \n", - "\n", - " Director \\\n", - "50 J.J. Abrams \n", - "1006 Anthony Russo \n", - "87 James Cameron \n", - "1007 Anthony Russo \n", - "85 Colin Trevorrow \n", - "... ... \n", - "974 Gilles Paquet-Brenner \n", - "183 Mateo Gil \n", - "218 Liam Gavin \n", - "397 Terry Jones \n", - "815 John Moore \n", - "\n", - " Cast Year Runtime \\\n", - "50 Daisy Ridley, John Boyega, Oscar Isaac, Domhna... 2015 136 \n", - "1006 Joe Russo, Robert Downey Jr., Chris Evans, Mar... 2019 181 \n", - "87 Sam Worthington, Zoe Saldana, Sigourney Weaver... 2009 162 \n", - "1007 Joe Russo, Robert Downey Jr., Chris Hemsworth,... 2018 149 \n", - "85 Chris Pratt, Bryce Dallas Howard, Ty Simpkins,... 2015 124 \n", - "... ... ... ... \n", - "974 Charlize Theron, Nicholas Hoult, Christina Hen... 2015 113 \n", - "183 Tom Hughes, Charlotte Le Bon, Oona Chaplin, Ba... 2016 112 \n", - "218 Mark Huberman, Susan Loughnane, Steve Oram,Cat... 2016 100 \n", - "397 Simon Pegg, Kate Beckinsale, Sanjeev Bhaskar, ... 2015 85 \n", - "815 Pierce Brosnan, Jason Barry, Karen Moskow, Kai... 2016 95 \n", - "\n", - " Rating Revenue Revenue (float) \n", - "50 8.1 936.63 936630000.0 \n", - "1006 8.4 858.37 858370000.0 \n", - "87 7.8 760.51 760510000.0 \n", - "1007 8.4 678.82 678820000.0 \n", - "85 7.0 652.18 652180000.0 \n", - "... ... ... ... \n", - "974 6.2 0 0.0 \n", - "183 5.9 0 0.0 \n", - "218 6.1 0 0.0 \n", - "397 6.0 0 0.0 \n", - "815 5.4 0 0.0 \n", - "\n", - "[1068 rows x 9 columns]" - ] - }, - "execution_count": 66, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Or more generally...\n", - "rev_df.sort_values(by=\"Revenue (float)\", ascending=False)" - ] - }, - { - "cell_type": "code", - "execution_count": 67, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "<div>\n", - "<style scoped>\n", - " .dataframe tbody tr th:only-of-type {\n", - " vertical-align: middle;\n", - " }\n", - "\n", - " .dataframe tbody tr th {\n", - " vertical-align: top;\n", - " }\n", - "\n", - " .dataframe thead th {\n", - " text-align: right;\n", - " }\n", - "</style>\n", - "<table border=\"1\" class=\"dataframe\">\n", - " <thead>\n", - " <tr style=\"text-align: right;\">\n", - " <th></th>\n", - " <th>Title</th>\n", - " <th>Genre</th>\n", - " <th>Director</th>\n", - " <th>Cast</th>\n", - " <th>Year</th>\n", - " <th>Runtime</th>\n", - " <th>Rating</th>\n", - " <th>Revenue</th>\n", - " </tr>\n", - " </thead>\n", - " <tbody>\n", - " <tr>\n", - " <th>0</th>\n", - " <td>Guardians of the Galaxy</td>\n", - " <td>Action,Adventure,Sci-Fi</td>\n", - " <td>James Gunn</td>\n", - " <td>Chris Pratt, Vin Diesel, Bradley Cooper, Zoe S...</td>\n", - " <td>2014</td>\n", - " <td>121</td>\n", - " <td>8.1</td>\n", - " <td>333.13</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1</th>\n", - " <td>Prometheus</td>\n", - " <td>Adventure,Mystery,Sci-Fi</td>\n", - " <td>Ridley Scott</td>\n", - " <td>Noomi Rapace, Logan Marshall-Green, Michael ...</td>\n", - " <td>2012</td>\n", - " <td>124</td>\n", - " <td>7.0</td>\n", - " <td>126.46M</td>\n", - " </tr>\n", - " <tr>\n", - " <th>2</th>\n", - " <td>Split</td>\n", - " <td>Horror,Thriller</td>\n", - " <td>M. Night Shyamalan</td>\n", - " <td>James McAvoy, Anya Taylor-Joy, Haley Lu Richar...</td>\n", - " <td>2016</td>\n", - " <td>117</td>\n", - " <td>7.3</td>\n", - " <td>138.12M</td>\n", - " </tr>\n", - " <tr>\n", - " <th>3</th>\n", - " <td>Sing</td>\n", - " <td>Animation,Comedy,Family</td>\n", - " <td>Christophe Lourdelet</td>\n", - " <td>Matthew McConaughey,Reese Witherspoon, Seth Ma...</td>\n", - " <td>2016</td>\n", - " <td>108</td>\n", - " <td>7.2</td>\n", - " <td>270.32</td>\n", - " </tr>\n", - " <tr>\n", - " <th>4</th>\n", - " <td>Suicide Squad</td>\n", - " <td>Action,Adventure,Fantasy</td>\n", - " <td>David Ayer</td>\n", - " <td>Will Smith, Jared Leto, Margot Robbie, Viola D...</td>\n", - " <td>2016</td>\n", - " <td>123</td>\n", - " <td>6.2</td>\n", - " <td>325.02</td>\n", - " </tr>\n", - " <tr>\n", - " <th>...</th>\n", - " <td>...</td>\n", - " <td>...</td>\n", - " <td>...</td>\n", - " <td>...</td>\n", - " <td>...</td>\n", - " <td>...</td>\n", - " <td>...</td>\n", - " <td>...</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1063</th>\n", - " <td>Guardians of the Galaxy Vol. 2</td>\n", - " <td>Action, Adventure, Comedy</td>\n", - " <td>James Gunn</td>\n", - " <td>Chris Pratt, Zoe Saldana, Dave Bautista, Vin D...</td>\n", - " <td>2017</td>\n", - " <td>136</td>\n", - " <td>7.6</td>\n", - " <td>389.81</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1064</th>\n", - " <td>Baby Driver</td>\n", - " <td>Action, Crime, Drama</td>\n", - " <td>Edgar Wright</td>\n", - " <td>Ansel Elgort, Jon Bernthal, Jon Hamm, Eiza Gon...</td>\n", - " <td>2017</td>\n", - " <td>113</td>\n", - " <td>7.6</td>\n", - " <td>107.83</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1065</th>\n", - " <td>Only the Brave</td>\n", - " <td>Action, Biography, Drama</td>\n", - " <td>Joseph Kosinski</td>\n", - " <td>Josh Brolin, Miles Teller, Jeff Bridges, Jenni...</td>\n", - " <td>2017</td>\n", - " <td>134</td>\n", - " <td>7.6</td>\n", - " <td>18.34</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1066</th>\n", - " <td>Incredibles 2</td>\n", - " <td>Animation, Action, Adventure</td>\n", - " <td>Brad Bird</td>\n", - " <td>Craig T. Nelson, Holly Hunter, Sarah Vowell, H...</td>\n", - " <td>2018</td>\n", - " <td>118</td>\n", - " <td>7.6</td>\n", - " <td>608.58</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1067</th>\n", - " <td>A Star Is Born</td>\n", - " <td>Drama, Music, Romance</td>\n", - " <td>Bradley Cooper</td>\n", - " <td>Lady Gaga, Bradley Cooper, Sam Elliott, Greg G...</td>\n", - " <td>2018</td>\n", - " <td>136</td>\n", - " <td>7.6</td>\n", - " <td>215.29</td>\n", - " </tr>\n", - " </tbody>\n", - "</table>\n", - "<p>1068 rows × 8 columns</p>\n", - "</div>" - ], - "text/plain": [ - " Title Genre \\\n", - "0 Guardians of the Galaxy Action,Adventure,Sci-Fi \n", - "1 Prometheus Adventure,Mystery,Sci-Fi \n", - "2 Split Horror,Thriller \n", - "3 Sing Animation,Comedy,Family \n", - "4 Suicide Squad Action,Adventure,Fantasy \n", - "... ... ... \n", - "1063 Guardians of the Galaxy Vol. 2 Action, Adventure, Comedy \n", - "1064 Baby Driver Action, Crime, Drama \n", - "1065 Only the Brave Action, Biography, Drama \n", - "1066 Incredibles 2 Animation, Action, Adventure \n", - "1067 A Star Is Born Drama, Music, Romance \n", - "\n", - " Director Cast \\\n", - "0 James Gunn Chris Pratt, Vin Diesel, Bradley Cooper, Zoe S... \n", - "1 Ridley Scott Noomi Rapace, Logan Marshall-Green, Michael ... \n", - "2 M. Night Shyamalan James McAvoy, Anya Taylor-Joy, Haley Lu Richar... \n", - "3 Christophe Lourdelet Matthew McConaughey,Reese Witherspoon, Seth Ma... \n", - "4 David Ayer Will Smith, Jared Leto, Margot Robbie, Viola D... \n", - "... ... ... \n", - "1063 James Gunn Chris Pratt, Zoe Saldana, Dave Bautista, Vin D... \n", - "1064 Edgar Wright Ansel Elgort, Jon Bernthal, Jon Hamm, Eiza Gon... \n", - "1065 Joseph Kosinski Josh Brolin, Miles Teller, Jeff Bridges, Jenni... \n", - "1066 Brad Bird Craig T. Nelson, Holly Hunter, Sarah Vowell, H... \n", - "1067 Bradley Cooper Lady Gaga, Bradley Cooper, Sam Elliott, Greg G... \n", - "\n", - " Year Runtime Rating Revenue \n", - "0 2014 121 8.1 333.13 \n", - "1 2012 124 7.0 126.46M \n", - "2 2016 117 7.3 138.12M \n", - "3 2016 108 7.2 270.32 \n", - "4 2016 123 6.2 325.02 \n", - "... ... ... ... ... \n", - "1063 2017 136 7.6 389.81 \n", - "1064 2017 113 7.6 107.83 \n", - "1065 2017 134 7.6 18.34 \n", - "1066 2018 118 7.6 608.58 \n", - "1067 2018 136 7.6 215.29 \n", - "\n", - "[1068 rows x 8 columns]" - ] - }, - "execution_count": 67, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "df" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### What is the average runtime for movies by \"Francis Lawrence\"?" - ] - }, - { - "cell_type": "code", - "execution_count": 68, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "126.75" - ] - }, - "execution_count": 68, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "fl_movies = df[df[\"Director\"] == \"Francis Lawrence\"]\n", - "fl_movies[\"Runtime\"].mean()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Which director had the highest average rating? " - ] - }, - { - "cell_type": "code", - "execution_count": 69, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'Christopher Nolan': 8.533333333333333,\n", - " 'Martin Scorsese': 7.916666666666667,\n", - " 'Quentin Tarantino': 7.840000000000001,\n", - " 'David Fincher': 7.8199999999999985,\n", - " 'Denis Villeneuve': 7.8,\n", - " 'J.J. Abrams': 7.58,\n", - " 'Guy Ritchie': 7.5,\n", - " 'David Yates': 7.433333333333334,\n", - " 'Danny Boyle': 7.42,\n", - " 'Antoine Fuqua': 7.040000000000001,\n", - " 'Zack Snyder': 7.040000000000001,\n", - " 'Woody Allen': 7.019999999999999,\n", - " 'Peter Berg': 6.860000000000001,\n", - " 'Ridley Scott': 6.85,\n", - " 'Justin Lin': 6.82,\n", - " 'Michael Bay': 6.483333333333334,\n", - " 'Paul W.S. Anderson': 5.766666666666666,\n", - " 'M. Night Shyamalan': 5.533333333333332}" - ] - }, - "execution_count": 69, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# one way is to make a python dict of director, list of ratings\n", - "director_dict = dict()\n", - "\n", - "# make the dictionary: key is director, value is list of ratings\n", - "for i in range(len(df)):\n", - " director = df.loc[i, \"Director\"]\n", - " rating = df.loc[i, \"Rating\"]\n", - " #print(i, director, rating)\n", - " if director not in director_dict:\n", - " director_dict[director] = []\n", - " director_dict[director].append(rating)\n", - "\n", - "# make a ratings dict key is directory, value is average\n", - "# only include directors with > 4 movies\n", - "ratings_dict = {k: sum(v) / len(v) for (k, v) in director_dict.items() if len(v) > 4}\n", - "\n", - "#sort a dict by values\n", - "dict(sorted(ratings_dict.items(), key = lambda t:t[-1], reverse = True))" - ] - }, - { - "cell_type": "code", - "execution_count": 70, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "Director\n", - "Christopher Nolan 8.533333\n", - "Martin Scorsese 7.916667\n", - "Quentin Tarantino 7.840000\n", - "David Fincher 7.820000\n", - "Denis Villeneuve 7.800000\n", - "J.J. Abrams 7.580000\n", - "Guy Ritchie 7.500000\n", - "David Yates 7.433333\n", - "Danny Boyle 7.420000\n", - "Antoine Fuqua 7.040000\n", - "Zack Snyder 7.040000\n", - "Woody Allen 7.020000\n", - "Peter Berg 6.860000\n", - "Ridley Scott 6.850000\n", - "Justin Lin 6.820000\n", - "Michael Bay 6.483333\n", - "Paul W.S. Anderson 5.766667\n", - "M. Night Shyamalan 5.533333\n", - "Name: Rating, dtype: float64" - ] - }, - "execution_count": 70, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# FOR DEMONSTRATION PURPOSES ONLY\n", - "# We haven't learnt about \"groupby\"\n", - "# Pandas has many operations which will be helpful!\n", - "\n", - "# Consider what you already know, and what Pandas can solve\n", - "# when formulating your solutions.\n", - "rating_groups = df.groupby(\"Director\")[\"Rating\"]\n", - "rating_groups.mean()[rating_groups.count() > 4].sort_values(ascending=False)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Extra Practice: Make up some of your own questions about the movies" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "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.9.7" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/f22/meena_lec_notes/lec-28/.ipynb_checkpoints/lec_28_pandas2_template-checkpoint.ipynb b/f22/meena_lec_notes/lec-28/.ipynb_checkpoints/lec_28_pandas2_template-checkpoint.ipynb deleted file mode 100644 index b775fd1..0000000 --- a/f22/meena_lec_notes/lec-28/.ipynb_checkpoints/lec_28_pandas2_template-checkpoint.ipynb +++ /dev/null @@ -1,1208 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import pandas as pd\n", - "from pandas import Series, DataFrame\n", - "# We can explictly import Series and DataFrame, why might we do this?" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Series Review\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Series from `list`" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "scores_list = [54, 22, 19, 73, 80]\n", - "scores_series = Series(scores_list)\n", - "scores_series\n", - "\n", - "# What is the terminology for: 0, 1, 2, ... ?? A: \n", - "# What is the terminology for: 54, 22, 19, .... ?? A: " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Selecting certain scores.\n", - "What are all the scores `> 50`?" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Answer:** Boolean indexing. Try the following..." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "scores_series[[True, True, False, False, True]] # often called a \"mask\"" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We are really writing a \"mask\" for our data." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Series from `dict`" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Imagine we hire students and track their weekly hours\n", - "week1 = Series({\"Rita\":5, \"Therese\":3, \"Janice\": 6})\n", - "week2 = Series({\"Rita\":3, \"Therese\":7, \"Janice\": 4})\n", - "week3 = Series({\"Therese\":5, \"Janice\":5, \"Rita\": 8}) # Wrong order! Will this matter?\n", - "print(week1)\n", - "print(week2)\n", - "print(week3)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### For everyone in Week 1, add 3 to their hours " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "\n", - "week1" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Total up everyone's hours" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "total_hours = ???\n", - "total_hours" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### What is week1 / week3 ?" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "???\n", - "# Notice that we didn't have to worry about the order of indices" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### What type of values are stored in week1 > week2?" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "print(week1)\n", - "print(week2)\n", - "???\n", - "# Notice that indices are ordered the same" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### What is week1 > week3?" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "print(week1)\n", - "print(week3)\n", - "??? # Does it work?\n", - "\n", - "# How can we fix this?" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "\n", - "# Lecture 28: Pandas 2 - DataFrames\n", - "\n", - "\n", - "Learning Objectives:\n", - "- Create a DataFrame from \n", - " - a dictionary of Series, lists, or dicts\n", - " - a list of Series, lists, dicts\n", - "- Select a column, row, cell, or rectangular region of a DataFrame\n", - "- Convert CSV files into DataFrames and DataFrames into CSV Files\n", - "- Access the head or tail of a DataFrame" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Big Idea**: Data Frames store 2-dimensional data in tables! It is a collection of Series." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## You can create a DataFrame in a variety of ways!\n", - "\n", - "- dictionary of Series\n", - "- dictionary of lists\n", - "- dictionary of dictionaries\n", - "- list of dictionarines\n", - "- list of lists\n", - "\n", - "### From a dictionary of Series" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "names = Series([\"Alice\", \"Bob\", \"Cindy\", \"Dan\"])\n", - "scores = Series([6, 7, 8, 9])\n", - "\n", - "# to make a dictionary of Series, need to write column names for the keys\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### From a dictionary of lists" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "name_list = [\"Alice\", \"Bob\", \"Cindy\", \"Dan\"]\n", - "score_list = [6, 7, 8, 9]\n", - "\n", - "# this is the same as above, reminding us that Series act like lists\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### From a dictionary of dictionaries\n", - "We need to make up keys to match the things in each column" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "data = {\n", - " \"Player name\": {0: \"Alice\", 1: \"Bob\", 2: \"Cindy\", 3: \"Dan\"},\n", - " \"Score\": {0: 6, 1: 7, 2: 8, 3: 9}\n", - "}\n", - "data" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### From a list of dicts" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "data = [\n", - " {\"Player name\": \"Alice\", \"Score\": 6},\n", - " {\"Player name\": \"Bob\", \"Score\": 7},\n", - " {\"Player name\": \"Cindy\", \"Score\": 8},\n", - " {\"Player name\": \"Dan\", \"Score\": 9}\n", - "]\n", - "data" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### From a list of lists" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "data = [\n", - " [\"Alice\", 6],\n", - " [\"Bob\", 7],\n", - " [\"Cindy\", 8],\n", - " [\"Dan\", 9]\n", - "]\n", - "data\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Explicitly naming the columns\n", - "We have to add the column names, we do this with `columns = [name1, name2, ....]`" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "data = [\n", - " [\"Alice\", 6],\n", - " [\"Bob\", 7],\n", - " [\"Cindy\", 8],\n", - " [\"Dan\", 9]\n", - "]\n", - "data" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Explicitly naming the indices\n", - "We can use `index = [name1, name2, ...]` to rename the index of each row" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "data = [\n", - " {\"Player name\": \"Alice\", \"Score\": 6},\n", - " {\"Player name\": \"Bob\", \"Score\": 7},\n", - " {\"Player name\": \"Cindy\", \"Score\": 8},\n", - " {\"Player name\": \"Dan\", \"Score\": 9}\n", - "]\n", - "data" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# TODO: \n", - "# Make a DataFrame of 4 people you know with different ages\n", - "# Give names to both the columns and rows\n", - "\n", - "# Share how you did with this with your neighbor\n", - "# If you both did it the same way, try it a different way." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Select a column, row, cell, or rectangular region of a DataFrame\n", - "### Data lookup: Series\n", - "- `s.loc[X]` <- lookup by pandas index\n", - "- `s.iloc[X]` <- lookup by integer position" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "hours = Series({\"Alice\": 6, \"Bob\": 7, \"Cindy\": 8, \"Dan\": 9})\n", - "hours" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Lookup Bob's hours by pandas index.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Lookup Bob's hours by integer position.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Lookup Cindy's hours by pandas index.\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Data lookup: DataFrame\n", - "\n", - "\n", - "- `d.loc[r]` lookup ROW by pandas ROW index\n", - "- `d.iloc[r]` lookup ROW by ROW integer position\n", - "- `d[c]` lookup COL by pandas COL index\n", - "- `d.loc[r, c]` lookup by pandas ROW index and pandas COL index\n", - "- `d.iloc[r, c]` lookup by ROW integer position and COL integer position" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# We often call the object that we make df\n", - "data = [\n", - " [\"Hope\", 10],\n", - " [\"Peace\", 7],\n", - " [\"Joy\", 4],\n", - " [\"Love\", 11]\n", - "]\n", - "df = DataFrame(data, index = [\"H\", \"P\", \"J\", \"L\"], columns = [\"Player name\", \"Score\"])\n", - "df" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### What are 3 different ways of accessing row L? " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### How about accessing a column?" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "df" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### What are 3 different ways to access a single cell?" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "df" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## How to set values for a specific entry?\n", - "\n", - "- `d.loc[r, c] = new_val`\n", - "- `d.iloc[r, c] = new_val`" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "#change player D's name\n", - "df.loc[\"L\", \"Player name\"] = \"Luisa\"\n", - "df" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# then add 3 to that player's score using .loc\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# add 7 to a different player's score using .iloc\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Find the max score and the mean score" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# find the max and mean of the \"Score\" column\n", - "print(df[\"Score\"].max(), df[\"Score\"].mean())" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Find the highest scoring player" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Slicing a DataFrame\n", - "\n", - "- `df.iloc[ROW_SLICE, COL_SLICE]` <- make a rectangular slice from the DataFrame using integer positions\n", - "- `df.loc[ROW_SLICE, COL_SLICE]` <- make a rectangular slice from the DataFrame using index" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "df.iloc[1:3, 0:2]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "df.loc[\"P\":\"J\", \"Player name\":\"Score\"] # notice that this way is inclusive of endpoints" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Set values for sliced DataFrame\n", - "\n", - "- `d.loc[ROW_SLICE, COL_SLICE] = new_val` <- set value by ROW INDEX and COL INDEX\n", - "- `d.iloc[ROW_SLICE, COL_SLICE] = new_val` <- set value by ROW Integer position and COL Integer position" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "df" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "df.loc[\"P\":\"J\", \"Score\"] += 5\n", - "df" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Pandas allows slicing of non-contiguous columns" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# just get Player name for Index P and L\n", - "df.loc[[\"P\", \"L\"],\"Player name\"]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# add 2 to the people in rows P and L\n", - "df.loc[[\"P\", \"L\"],\"Score\"] += 2\n", - "df" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Boolean indexing on a DataFrame\n", - "\n", - "- `d[BOOL SERIES]` <- makes a new DF of all rows that lined up were True" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "df" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Make a Series of Booleans based on Score >= 15" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "\n", - "b" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### use b to slice the DataFrame\n", - "if b is true, include this row in the new df" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### do the last two things in a single step" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Creating DataFrame from csv" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# it's that easy! \n", - "df = pd.read_csv(\"IMDB-Movie-Data.csv\")\n", - "df" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### View the first few lines of the DataFrame\n", - "- `.head(n)` gets the first n lines, 5 is the default" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### get the first 2 rows" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### View the first few lines of the DataFrame\n", - "- `.tail(n)` gets the last n lines, 5 is the default" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### What are the first and last years in our dataset?" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Extract Year column\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "print(\"First year: {}, Last year: {}\".format(???))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### What are the rows that correspond to movies whose title contains \"Harry\" ? \n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### What is the movie at index 6 ? " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "df" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Notice that there are two index columns\n", - "- That happened because when you write a csv from pandas to a file, it writes a new index column\n", - "- So if the dataFrame already contains an index, you are going to get two index columns\n", - "- Let's fix that problem" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### How can you use slicing to get just columns with Title and Year?" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "df2 = ???\n", - "df2\n", - "# notice that this does not have the 'index' column" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### How can you use slicing to get rid of the first column?" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "df = df.iloc[???] #all the rows, not column 0\n", - "df" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Write a df to a csv file" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "df.to_csv(\"better_movies.csv\", index = False)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Practice on your own.....Data Analysis with Data Frames\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### What are all the movies that have above average run time (long movies)? " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "long_movies = ???\n", - "long_movies" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Which long movie has the lowest rating?" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# of these movies, what was the min rating? \n", - "min_rating = ???\n", - "min_rating" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Which movies had this min rating?\n", - "???" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### What are all long movies with someone in the cast named \"Emma\" ? " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "???" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### What is the title of the shortest movie?" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "???" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### What movie had the highest revenue?" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "df[\"Revnue\"].max() # does not work, Why?" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# We need to clean our data\n", - "# Some movies have M at the end and others don't.\n", - "# All revenues are in millions of dollars.\n", - "def format_revenue(revenue):\n", - " \"\"\" \n", - " Checks the last character of the string and formats accordingly\n", - " \"\"\"\n", - " if type(revenue) == float: # need this in here if we run code multiple times\n", - " return revenue\n", - " elif revenue[-1] == 'M': # some have an \"M\" at the end\n", - " return ??? # TODO: convert relevant part of the string to float and multiple by 1e6\n", - " else:\n", - " return ??? # TODO: convert to float and multiple by 1e6" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# What movie had the highest revenue?\n", - "revenue = df[\"Revenue\"].apply(format_revenue) # apply a function to a column; returns a Series\n", - "print(revenue.head())\n", - "max_revenue = revenue.max()\n", - "\n", - "# make a copy of our df\n", - "rev_df = df.copy()\n", - "rev_df[\"Revenue (float)\"] = revenue\n", - "rev_df" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Now we can answer the question!\n", - "???" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Or more generally...\n", - "rev_df.sort_values(by = \"Revenue (float)\", ascending = False)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "df" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### What is the average runtime for movies by \"Francis Lawrence\"?" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### More complicated questions..." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Which director had the highest average rating? \n", - "\n", - "# one way is to make a python dict of director, list of ratings\n", - "director_dict = dict()\n", - "\n", - "# make the dictionary: key is director, value is list of ratings\n", - "for i in range(len(df)):\n", - " director = df.loc[i, \"Director\"]\n", - " rating = df.loc[i, \"Rating\"]\n", - " #print(i, director, rating)\n", - " if director not in director_dict:\n", - " director_dict[director] = []\n", - " director_dict[director].append(rating)\n", - "\n", - "# make a ratings dict key is directory, value is average\n", - "# only include directors with > 4 movies\n", - "ratings_dict = {k:sum(v)/len(v) for (k,v) in director_dict.items() if len(v) > 4}\n", - "\n", - "#sort a dict by values\n", - "dict(sorted(ratings_dict.items(), key=lambda t:t[-1], reverse=True))\n", - " " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# FOR DEMONSTRATION PURPOSES ONLY\n", - "# We haven't (and will not) learn about \"groupby\"\n", - "# Pandas has many operations which will be helpful!\n", - "\n", - "# Consider what you already know, and what Pandas can solve\n", - "# when formulating your solutions.\n", - "rating_groups = df.groupby(\"Director\")[\"Rating\"]\n", - "rating_groups.mean()[rating_groups.count() > 4].sort_values(ascending=False)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Extra Practice: Make up some of your own questions about the movies" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "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.9.7" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/f22/meena_lec_notes/lec-29/.ipynb_checkpoints/demo_lec_28-checkpoint.ipynb b/f22/meena_lec_notes/lec-29/.ipynb_checkpoints/demo_lec_28-checkpoint.ipynb deleted file mode 100644 index 7cdd847..0000000 --- a/f22/meena_lec_notes/lec-29/.ipynb_checkpoints/demo_lec_28-checkpoint.ipynb +++ /dev/null @@ -1,1038 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Pandas 1 worksheet\n", - "\n", - "- Observe syntax, predict output and run cell to confirm your output" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from IPython.core.display import display, HTML\n", - "display(HTML(\"<style>.container { width:100% !important; }</style>\"))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Learning objectives" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " - Pandas helps deal with tabular (tables) data\n", - " - List of list is not adequate alternative to excel\n", - " - Series: new data structure\n", - " - hybrid of a dict and a list\n", - " - Python dict \"key\" equivalent to \"index\" in pandas\n", - " - Python list \"index\" quivalent to \"integer position\" in pandas\n", - " - supports complicated expressions within lookup [...]\n", - " - element-wise operation\n", - " - boolean indexing\n", - " - DataFrames aka tables (next lecture)\n", - " - built from series\n", - " - each series will be a column in the table" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# pandas comes with Anaconda installation\n", - "If for some reason, you don't have pandas installed, run the following command in terminal or powershell\n", - "<pre> pip install pandas </pre>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import pandas" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "pandas.Series" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Module naming abbreviation" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import pandas as pd" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "pd.Series" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Create a series from a dict" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "#create a series from a dict\n", - "d = {\"one\":7, \"two\":8, \"three\":9}\n", - "d" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "s = pd.Series({\"one\":7, \"two\":8, \"three\":9})\n", - "s" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# IP index value\n", - "# 0 one 7\n", - "# 1 two 8\n", - "# 2 three 9\n", - "\n", - "# dtype: int64" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Accessing values with index (.loc[...])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# dict access with key\n", - "d[\"one\"]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "s.loc[\"one\"]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "s.loc[\"two\"]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Accessing values with integer position (.iloc[...])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "s.iloc[0]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "s.iloc[1]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "s.iloc[-1]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "s[\"one\"]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "s[0]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Accessing multiple values with a list of integer positions" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "s[[0, 2]]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "#series access with a list of indexes\n", - "s[[\"one\", \"three\"]]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Create a series from a list" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Series created from a list\n", - "num_list = [100, 200, 300]\n", - "s = pd.Series([100, 200, 300])\n", - "s" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# IP index value\n", - "# 0 0 100\n", - "# 1 1 200\n", - "# 2 2 300\n", - "# dtype: int64" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "print(s.loc[1])\n", - "print(s.iloc[1])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "letters_list = [\"A\", \"B\", \"C\", \"D\"]\n", - "letters = pd.Series(letters_list)\n", - "# letters[-1] #Avoid negative indexes, unless we use .iloc" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Slicing series using integer positions" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "letters_list = [\"A\", \"B\", \"C\", \"D\"]\n", - "letters = pd.Series(letters_list)\n", - "letters" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "#list slicing reveiw\n", - "letters_list" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "sliced_letter_list = letters_list[2:]\n", - "sliced_letter_list" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "sliced_letter_list[0]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "#series slicing\n", - "letters" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "sliced_letters = letters[2:]\n", - "sliced_letters" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "sliced_letters.loc[2]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "sliced_letters.iloc[0]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# sliced_letter.loc[0] # index 0 doesn't exist in the sliced series!" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "sliced_letters[2]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Note: integer positions get renumbered, whereas indexes do not.\n", - "\n", - "# IP Index values\n", - "# 0 2 c\n", - "# 1 3 d\n", - "# 2 4 e\n", - "# 3 5 f\n", - "# dtype: object" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Slicing series using index" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "s = pd.Series({\"one\":7, \"two\":8, \"three\":9})\n", - "s" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "#slicing with indexes\n", - "s[\"two\":]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Element-wise operations\n", - "1. SERIES op SCALAR\n", - "2. SERIES op SERIES" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "#list recap\n", - "nums = [1, 2, 3]\n", - "nums * 3" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "snum = pd.Series(nums)\n", - "snum" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "snum * 3" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "snum + 3" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "snum / 3" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "nums" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# nums / 3 # doesn't work with lists" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "snum" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "snum += 2\n", - "snum" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "#list recap\n", - "l1 = [1, 2, 3]\n", - "l2 = [4, 5, 6]\n", - "l1 + l2" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "s1 = pd.Series(l1)\n", - "s2 = pd.Series(l2)\n", - "print(s1)\n", - "print(s2)\n", - "s1 + s2" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "print(s1)\n", - "print(s2)\n", - "s1 * s2" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "print(s1)\n", - "print(s2)\n", - "s1 / s2" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "print(s1)\n", - "print(s2)\n", - "s2 ** s1" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "print(s1)\n", - "print(s2)\n", - "s1 < s2" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## What happens to element-wise operation if we have two series with different sizes?" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "pd.Series([1,2,3]) + pd.Series([4,5])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Series with different types" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "pd.Series([\"a\", \"Alice\", True, 1, 4.5, [1,2], {\"a\":\"Alice\"}])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## How do you merge two series?" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "s1 = pd.Series([1,2,3]) \n", - "s2 = pd.Series([4,5])\n", - "print(s1)\n", - "print(s2)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "s = pd.concat( [s1, s2] )\n", - "s" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "s.loc[0]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Element-wise Ambiguity" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "s1 = pd.Series({\"A\":10, \"B\": 20 })\n", - "s2 = pd.Series({\"B\":1, \"A\": 2 })\n", - "print(s1)\n", - "print(s2)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# INDEX ALIGNMENT\n", - "s1 + s2" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## How to insert an index-value pair?" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "s = pd.Series({\"A\":10, \"B\": 20 })\n", - "print(s)\n", - "s[\"Z\"] = 100\n", - "s" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Boolean indexing" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "s = pd.Series([10, 2, 3, 15])\n", - "s" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## How to extract numbers > 8?" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "b = pd.Series([True, False, False, True])\n", - "b" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "s[b]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "s" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "b = s > 8\n", - "b" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "s[b]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "s[s > 8]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "s[pd.Series([True, False, False, True])]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Element-wise String operations" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "words = pd.Series([\"APPLE\", \"boy\", \"CAT\", \"dog\"])\n", - "words" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# words.upper() # can't call string functions on Series" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "words.str.upper()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "#words[BOOLEAN SERIES]\n", - "#How do we get BOOLEAN SERIES?\n", - "b = words == words.str.upper()\n", - "b" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "words[b]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "words[words == words.str.upper()]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## How to get the odd numbers from a list?" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "s = pd.Series([10, 19, 11, 30, 35])\n", - "s" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "s % 2" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "b = s % 2 == 1\n", - "b" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "s" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "s[b]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## BOOLEAN OPERATORS on series: and, or, not " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## How to get numbers < 12 or numbers > 33?" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "s" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# s[s < 12 or s > 33] # doesn't work with or, and, not" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# use | instead of or\n", - "s[ s < 12 | s > 33]\n", - "# error because precedence is so high\n", - "# s[ s < (12 | s) > 33]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Use lots of parenthesis\n", - "s[ (s < 12) | (s > 33)]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# AND is &\n", - "s[ (s > 12) & (s < 33)]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# NOT is ~\n", - "s[ ~((s > 12) & (s < 33))]" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "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.8.8" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/f22/meena_lec_notes/lec-29/.ipynb_checkpoints/demo_lec_28_template-checkpoint.ipynb b/f22/meena_lec_notes/lec-29/.ipynb_checkpoints/demo_lec_28_template-checkpoint.ipynb deleted file mode 100644 index a7984f8..0000000 --- a/f22/meena_lec_notes/lec-29/.ipynb_checkpoints/demo_lec_28_template-checkpoint.ipynb +++ /dev/null @@ -1,1151 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Pandas 1" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "<style>.container { width:100% !important; }</style>" - ], - "text/plain": [ - "<IPython.core.display.HTML object>" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "from IPython.core.display import display, HTML\n", - "display(HTML(\"<style>.container { width:100% !important; }</style>\"))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Learning objectives" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " - Pandas:\n", - " - Python module: tools for doing Data Science\n", - " - helps deal with tabular (tables) data\n", - " - List of list is not adequate alternative to excel\n", - " - Series: new data structure\n", - " - hybrid of a dict and a list\n", - " - Python dict \"key\" equivalent to \"index\" in pandas\n", - " - Python list \"index\" quivalent to \"integer position\" in pandas\n", - " - supports complicated expressions within lookup [...]\n", - " - element-wise operation\n", - " - boolean indexing\n", - " - DataFrames aka tables (next lecture)\n", - " - built from series\n", - " - each series will be a column in the table" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# pandas comes with Anaconda installation\n", - "If for some reason, you don't have pandas installed, run the following command in terminal or powershell\n", - "<pre> pip install pandas </pre>" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [], - "source": [ - "# importing pandas module\n", - "import pandas" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Module naming abbreviation" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [], - "source": [ - "# Common abbrievation for pandas module\n", - "import pandas as pd" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Create a series from a dict" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'one': 7, 'two': 8, 'three': 9}" - ] - }, - "execution_count": 4, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# create a series from a dict\n", - "d = {\"one\": 7, \"two\": 8, \"three\": 9}\n", - "d" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "one 7\n", - "two 8\n", - "three 9\n", - "dtype: int64" - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s = pd.Series(d)\n", - "s" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "one 7\n", - "two 8\n", - "three 9\n", - "dtype: int64" - ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s = pd.Series({\"one\": 7, \"two\": 8, \"three\": 9}) # equivalent to the above example\n", - "s" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [], - "source": [ - "# IP index value\n", - "# 0 one 7\n", - "# 1 two 8\n", - "# 2 three 9\n", - "\n", - "# dtype: int64" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Accessing values with index (.loc[...])" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "7" - ] - }, - "execution_count": 8, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# dict access with key\n", - "d[\"one\"]" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "7" - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s.loc[\"one\"]" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "8" - ] - }, - "execution_count": 10, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s.loc[\"two\"]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Accessing values with integer position (.iloc[...])" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "7" - ] - }, - "execution_count": 11, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s.iloc[0]" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "9" - ] - }, - "execution_count": 12, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s.iloc[-1]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Regular lookups with just [ ]" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "7" - ] - }, - "execution_count": 13, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s[\"one\"]" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "7" - ] - }, - "execution_count": 14, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s[0]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Accessing multiple values with a list of integer positions" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "two 8\n", - "three 9\n", - "dtype: int64" - ] - }, - "execution_count": 15, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s[[1, 2]]" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "two 8\n", - "three 9\n", - "dtype: int64" - ] - }, - "execution_count": 16, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# series access with a list of indexes\n", - "s[[\"two\", \"three\"]]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Create a series from a list" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "0 100\n", - "1 200\n", - "2 300\n", - "dtype: int64" - ] - }, - "execution_count": 17, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Series created from a list\n", - "num_list = [100, 200, 300]\n", - "s = pd.Series(num_list)\n", - "s" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "metadata": {}, - "outputs": [], - "source": [ - "# IP index value\n", - "# 0 0 100\n", - "# 1 1 200\n", - "# 2 2 300\n", - "# dtype: int64" - ] - }, - { - "cell_type": "code", - "execution_count": 19, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "200\n", - "200\n" - ] - } - ], - "source": [ - "print(s.loc[1])\n", - "print(s.iloc[1])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "pandas looks for an index when we do a [ ] lookup, by default" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "metadata": {}, - "outputs": [], - "source": [ - "letters_list = [\"A\", \"B\", \"C\", \"D\"]\n", - "letters = pd.Series(letters_list)\n", - "# letters[-1] # Avoid negative indexes, unless we use .iloc" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Slicing series using integer positions" - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "0 A\n", - "1 B\n", - "2 C\n", - "3 D\n", - "dtype: object" - ] - }, - "execution_count": 21, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "letters_list = [\"A\", \"B\", \"C\", \"D\"]\n", - "letters = pd.Series(letters_list)\n", - "letters" - ] - }, - { - "cell_type": "code", - "execution_count": 22, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "['C', 'D']" - ] - }, - "execution_count": 22, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# list slicing\n", - "sliced_letter_list = letters_list[2:]\n", - "sliced_letter_list" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Sliced Series retains original Series index, whereas integer positions are renumbered." - ] - }, - { - "cell_type": "code", - "execution_count": 23, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "2 C\n", - "3 D\n", - "dtype: object" - ] - }, - "execution_count": 23, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "sliced_letters = letters[2:]\n", - "sliced_letters" - ] - }, - { - "cell_type": "code", - "execution_count": 24, - "metadata": {}, - "outputs": [], - "source": [ - "# Note: integer positions get renumbered, whereas indexes do not.\n", - "\n", - "# IP Index values\n", - "# 0 2 C\n", - "# 1 3 D\n", - "# dtype: object" - ] - }, - { - "cell_type": "code", - "execution_count": 25, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "C\n", - "C\n" - ] - } - ], - "source": [ - "print(sliced_letters.loc[2])\n", - "print(sliced_letters.iloc[0])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Slicing series using index" - ] - }, - { - "cell_type": "code", - "execution_count": 26, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "one 7\n", - "two 8\n", - "three 9\n", - "dtype: int64" - ] - }, - "execution_count": 26, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s = pd.Series({\"one\": 7, \"two\": 8, \"three\": 9})\n", - "s" - ] - }, - { - "cell_type": "code", - "execution_count": 27, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "two 8\n", - "three 9\n", - "dtype: int64" - ] - }, - "execution_count": 27, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "#slicing with indexes\n", - "s[\"two\":]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Statistics on Series" - ] - }, - { - "cell_type": "code", - "execution_count": 28, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "0 44\n", - "1 32\n", - "2 19\n", - "3 67\n", - "4 23\n", - "5 23\n", - "6 92\n", - "7 47\n", - "8 47\n", - "9 78\n", - "10 84\n", - "dtype: int64" - ] - }, - "execution_count": 28, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "scores = pd.Series([44, 32, 19, 67, 23, 23, 92, 47, 47, 78, 84])\n", - "scores" - ] - }, - { - "cell_type": "code", - "execution_count": 29, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "50.54545454545455" - ] - }, - "execution_count": 29, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "scores.mean()" - ] - }, - { - "cell_type": "code", - "execution_count": 30, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "26.051347897426098" - ] - }, - "execution_count": 30, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "scores.std()" - ] - }, - { - "cell_type": "code", - "execution_count": 31, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "47.0" - ] - }, - "execution_count": 31, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "scores.median()" - ] - }, - { - "cell_type": "code", - "execution_count": 32, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "0 23\n", - "1 47\n", - "dtype: int64" - ] - }, - "execution_count": 32, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "scores.mode()" - ] - }, - { - "cell_type": "code", - "execution_count": 33, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "1.00 92.0\n", - "0.75 72.5\n", - "0.50 47.0\n", - "0.25 27.5\n", - "0.00 19.0\n", - "dtype: float64" - ] - }, - "execution_count": 33, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "scores.quantile([1.0, 0.75, 0.5, 0.25, 0])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## CS220 information survey data" - ] - }, - { - "cell_type": "code", - "execution_count": 34, - "metadata": {}, - "outputs": [], - "source": [ - "# Modified from https://automatetheboringstuff.com/chapter14/\n", - "import csv\n", - "def process_csv(filename):\n", - " example_file = open(filename, encoding=\"utf-8\")\n", - " example_reader = csv.reader(example_file)\n", - " example_data = list(example_reader)\n", - " example_file.close()\n", - " return example_data\n", - "\n", - "data = process_csv(\"cs220_survey_data.csv\")\n", - "header = data[0]\n", - "data = data[1:]" - ] - }, - { - "cell_type": "code", - "execution_count": 35, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "['lecture', 'age', 'major', 'topping']" - ] - }, - "execution_count": 35, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "header" - ] - }, - { - "cell_type": "code", - "execution_count": 39, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[['LEC001', '19', 'Computer Science', 'basil/spinach'],\n", - " ['LEC002', '18', 'Engineering', 'pineapple'],\n", - " ['LEC003', '19', 'Business', 'pepperoni']]" - ] - }, - "execution_count": 39, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "data[:3]" - ] - }, - { - "cell_type": "code", - "execution_count": 37, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[19, 18, 19, 19, 19]" - ] - }, - "execution_count": 37, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# use list comprehension to extract just ages\n", - "age_list = [int(row[1]) for row in data if row[1] != \"\"]" - ] - }, - { - "cell_type": "code", - "execution_count": 41, - "metadata": {}, - "outputs": [], - "source": [ - "cs220_ages = pd.Series(age_list)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Unique values in a Series" - ] - }, - { - "cell_type": "code", - "execution_count": 42, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "19 290\n", - "18 214\n", - "20 178\n", - "21 101\n", - "22 41\n", - "23 13\n", - "17 11\n", - "25 7\n", - "24 6\n", - "26 4\n", - "28 3\n", - "29 2\n", - "30 2\n", - "27 2\n", - "34 1\n", - "37 1\n", - "35 1\n", - "16 1\n", - "33 1\n", - "32 1\n", - "31 1\n", - "46 1\n", - "dtype: int64" - ] - }, - "execution_count": 42, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "cs220_ages.value_counts()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Series sorting\n", - "- can be done using index or values" - ] - }, - { - "cell_type": "code", - "execution_count": 43, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "16 1\n", - "17 11\n", - "18 214\n", - "19 290\n", - "20 178\n", - "21 101\n", - "22 41\n", - "23 13\n", - "24 6\n", - "25 7\n", - "26 4\n", - "27 2\n", - "28 3\n", - "29 2\n", - "30 2\n", - "31 1\n", - "32 1\n", - "33 1\n", - "34 1\n", - "35 1\n", - "37 1\n", - "46 1\n", - "dtype: int64" - ] - }, - "execution_count": 43, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "cs220_ages.value_counts().sort_index()" - ] - }, - { - "cell_type": "code", - "execution_count": 44, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "46 1\n", - "32 1\n", - "33 1\n", - "16 1\n", - "35 1\n", - "37 1\n", - "34 1\n", - "31 1\n", - "27 2\n", - "30 2\n", - "29 2\n", - "28 3\n", - "26 4\n", - "24 6\n", - "25 7\n", - "17 11\n", - "23 13\n", - "22 41\n", - "21 101\n", - "20 178\n", - "18 214\n", - "19 290\n", - "dtype: int64" - ] - }, - "execution_count": 44, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "cs220_ages.value_counts().sort_values()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Statistics" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# find the mode\n", - "print(cs220_ages.mode())\n", - "\n", - "# find the age of the 75th percentile\n", - "print(ages.quantile(.75))\n", - "\n", - "# how many ages are > 25 ? \n", - "print(len(cs220_ages[cs220_ages > 25]))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# We can plot the data\n", - "age_plot = cs220_ages.value_counts().sort_index().plot.bar()\n", - "age_plot.set(xlabel = \"age\", ylabel = \"count\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Element-wise operations\n", - "1. SERIES op SCALAR\n", - "2. SERIES op SERIES" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "## Series from a dict\n", - "game1_points = pd.Series({\"Chris\": 10, \"Kiara\": 3, \"Mikayla\": 7, \"Ann\": 8, \"Trish\": 6})\n", - "print(game1points)\n", - "game2_points = pd.Series({\"Kiara\": 7, \"Chris\": 3, \"Trish\": 11, \"Mikayla\": 2, \"Ann\": 5})\n", - "print(game2points)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Pandas can perform operations on two series by matching up their indices\n", - "total = game1_points + game2_points\n", - "total" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "## Who has the most points?\n", - "print(total.max())\n", - "print(total.idxmax())" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "print(total['Kiara'], total[2])" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "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.8.8" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/f22/meena_lec_notes/lec-29/.ipynb_checkpoints/lec_29_web1-checkpoint.ipynb b/f22/meena_lec_notes/lec-29/.ipynb_checkpoints/lec_29_web1-checkpoint.ipynb deleted file mode 100644 index e214a4a..0000000 --- a/f22/meena_lec_notes/lec-29/.ipynb_checkpoints/lec_29_web1-checkpoint.ipynb +++ /dev/null @@ -1,3255 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Web 1 - How to get data from the Internet" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [], - "source": [ - "import requests\n", - "import json\n", - "import pandas as pd\n", - "from pandas import Series, DataFrame" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### P10 check-in" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [], - "source": [ - "# It is very important to check auto-grader test results on p10 in a timely manner.\n", - "# Take a few minutes to verify if you hardcoded the slashes in P10 rather than using os.path.join? \n", - " # Your code won't clear auto-grader if you hardcode either \"/\" or \"\\\" \n", - " # for *ANY* relative path in the entire project\n", - "# Check your code and check the autograder as soon as possible." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Warmup 1: Read the data from \"IMDB-Movie-Data.csv\" into a pandas DataFrame called \"movies\"" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "<div>\n", - "<style scoped>\n", - " .dataframe tbody tr th:only-of-type {\n", - " vertical-align: middle;\n", - " }\n", - "\n", - " .dataframe tbody tr th {\n", - " vertical-align: top;\n", - " }\n", - "\n", - " .dataframe thead th {\n", - " text-align: right;\n", - " }\n", - "</style>\n", - "<table border=\"1\" class=\"dataframe\">\n", - " <thead>\n", - " <tr style=\"text-align: right;\">\n", - " <th></th>\n", - " <th>Index</th>\n", - " <th>Title</th>\n", - " <th>Genre</th>\n", - " <th>Director</th>\n", - " <th>Cast</th>\n", - " <th>Year</th>\n", - " <th>Runtime</th>\n", - " <th>Rating</th>\n", - " <th>Revenue</th>\n", - " </tr>\n", - " </thead>\n", - " <tbody>\n", - " <tr>\n", - " <th>0</th>\n", - " <td>0</td>\n", - " <td>Guardians of the Galaxy</td>\n", - " <td>Action,Adventure,Sci-Fi</td>\n", - " <td>James Gunn</td>\n", - " <td>Chris Pratt, Vin Diesel, Bradley Cooper, Zoe S...</td>\n", - " <td>2014</td>\n", - " <td>121</td>\n", - " <td>8.1</td>\n", - " <td>333.13</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1</th>\n", - " <td>1</td>\n", - " <td>Prometheus</td>\n", - " <td>Adventure,Mystery,Sci-Fi</td>\n", - " <td>Ridley Scott</td>\n", - " <td>Noomi Rapace, Logan Marshall-Green, Michael ...</td>\n", - " <td>2012</td>\n", - " <td>124</td>\n", - " <td>7.0</td>\n", - " <td>126.46M</td>\n", - " </tr>\n", - " <tr>\n", - " <th>2</th>\n", - " <td>2</td>\n", - " <td>Split</td>\n", - " <td>Horror,Thriller</td>\n", - " <td>M. Night Shyamalan</td>\n", - " <td>James McAvoy, Anya Taylor-Joy, Haley Lu Richar...</td>\n", - " <td>2016</td>\n", - " <td>117</td>\n", - " <td>7.3</td>\n", - " <td>138.12M</td>\n", - " </tr>\n", - " <tr>\n", - " <th>3</th>\n", - " <td>3</td>\n", - " <td>Sing</td>\n", - " <td>Animation,Comedy,Family</td>\n", - " <td>Christophe Lourdelet</td>\n", - " <td>Matthew McConaughey,Reese Witherspoon, Seth Ma...</td>\n", - " <td>2016</td>\n", - " <td>108</td>\n", - " <td>7.2</td>\n", - " <td>270.32</td>\n", - " </tr>\n", - " <tr>\n", - " <th>4</th>\n", - " <td>4</td>\n", - " <td>Suicide Squad</td>\n", - " <td>Action,Adventure,Fantasy</td>\n", - " <td>David Ayer</td>\n", - " <td>Will Smith, Jared Leto, Margot Robbie, Viola D...</td>\n", - " <td>2016</td>\n", - " <td>123</td>\n", - " <td>6.2</td>\n", - " <td>325.02</td>\n", - " </tr>\n", - " <tr>\n", - " <th>...</th>\n", - " <td>...</td>\n", - " <td>...</td>\n", - " <td>...</td>\n", - " <td>...</td>\n", - " <td>...</td>\n", - " <td>...</td>\n", - " <td>...</td>\n", - " <td>...</td>\n", - " <td>...</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1063</th>\n", - " <td>1063</td>\n", - " <td>Guardians of the Galaxy Vol. 2</td>\n", - " <td>Action, Adventure, Comedy</td>\n", - " <td>James Gunn</td>\n", - " <td>Chris Pratt, Zoe Saldana, Dave Bautista, Vin D...</td>\n", - " <td>2017</td>\n", - " <td>136</td>\n", - " <td>7.6</td>\n", - " <td>389.81</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1064</th>\n", - " <td>1064</td>\n", - " <td>Baby Driver</td>\n", - " <td>Action, Crime, Drama</td>\n", - " <td>Edgar Wright</td>\n", - " <td>Ansel Elgort, Jon Bernthal, Jon Hamm, Eiza Gon...</td>\n", - " <td>2017</td>\n", - " <td>113</td>\n", - " <td>7.6</td>\n", - " <td>107.83</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1065</th>\n", - " <td>1065</td>\n", - " <td>Only the Brave</td>\n", - " <td>Action, Biography, Drama</td>\n", - " <td>Joseph Kosinski</td>\n", - " <td>Josh Brolin, Miles Teller, Jeff Bridges, Jenni...</td>\n", - " <td>2017</td>\n", - " <td>134</td>\n", - " <td>7.6</td>\n", - " <td>18.34</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1066</th>\n", - " <td>1066</td>\n", - " <td>Incredibles 2</td>\n", - " <td>Animation, Action, Adventure</td>\n", - " <td>Brad Bird</td>\n", - " <td>Craig T. Nelson, Holly Hunter, Sarah Vowell, H...</td>\n", - " <td>2018</td>\n", - " <td>118</td>\n", - " <td>7.6</td>\n", - " <td>608.58</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1067</th>\n", - " <td>1067</td>\n", - " <td>A Star Is Born</td>\n", - " <td>Drama, Music, Romance</td>\n", - " <td>Bradley Cooper</td>\n", - " <td>Lady Gaga, Bradley Cooper, Sam Elliott, Greg G...</td>\n", - " <td>2018</td>\n", - " <td>136</td>\n", - " <td>7.6</td>\n", - " <td>215.29</td>\n", - " </tr>\n", - " </tbody>\n", - "</table>\n", - "<p>1068 rows × 9 columns</p>\n", - "</div>" - ], - "text/plain": [ - " Index Title Genre \\\n", - "0 0 Guardians of the Galaxy Action,Adventure,Sci-Fi \n", - "1 1 Prometheus Adventure,Mystery,Sci-Fi \n", - "2 2 Split Horror,Thriller \n", - "3 3 Sing Animation,Comedy,Family \n", - "4 4 Suicide Squad Action,Adventure,Fantasy \n", - "... ... ... ... \n", - "1063 1063 Guardians of the Galaxy Vol. 2 Action, Adventure, Comedy \n", - "1064 1064 Baby Driver Action, Crime, Drama \n", - "1065 1065 Only the Brave Action, Biography, Drama \n", - "1066 1066 Incredibles 2 Animation, Action, Adventure \n", - "1067 1067 A Star Is Born Drama, Music, Romance \n", - "\n", - " Director Cast \\\n", - "0 James Gunn Chris Pratt, Vin Diesel, Bradley Cooper, Zoe S... \n", - "1 Ridley Scott Noomi Rapace, Logan Marshall-Green, Michael ... \n", - "2 M. Night Shyamalan James McAvoy, Anya Taylor-Joy, Haley Lu Richar... \n", - "3 Christophe Lourdelet Matthew McConaughey,Reese Witherspoon, Seth Ma... \n", - "4 David Ayer Will Smith, Jared Leto, Margot Robbie, Viola D... \n", - "... ... ... \n", - "1063 James Gunn Chris Pratt, Zoe Saldana, Dave Bautista, Vin D... \n", - "1064 Edgar Wright Ansel Elgort, Jon Bernthal, Jon Hamm, Eiza Gon... \n", - "1065 Joseph Kosinski Josh Brolin, Miles Teller, Jeff Bridges, Jenni... \n", - "1066 Brad Bird Craig T. Nelson, Holly Hunter, Sarah Vowell, H... \n", - "1067 Bradley Cooper Lady Gaga, Bradley Cooper, Sam Elliott, Greg G... \n", - "\n", - " Year Runtime Rating Revenue \n", - "0 2014 121 8.1 333.13 \n", - "1 2012 124 7.0 126.46M \n", - "2 2016 117 7.3 138.12M \n", - "3 2016 108 7.2 270.32 \n", - "4 2016 123 6.2 325.02 \n", - "... ... ... ... ... \n", - "1063 2017 136 7.6 389.81 \n", - "1064 2017 113 7.6 107.83 \n", - "1065 2017 134 7.6 18.34 \n", - "1066 2018 118 7.6 608.58 \n", - "1067 2018 136 7.6 215.29 \n", - "\n", - "[1068 rows x 9 columns]" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "movies = pd.read_csv(\"IMDB-Movie-Data.csv\")\n", - "movies" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Warmup 2: fixing duplicate index columns\n", - "\n", - "Notice that there are two index columns\n", - "- That happened because when you write a csv from pandas to a file, it writes a new index column\n", - "- So if the DataFrame already contains an index, you are going to get two index columns\n", - "- Let's fix that problem" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "<div>\n", - "<style scoped>\n", - " .dataframe tbody tr th:only-of-type {\n", - " vertical-align: middle;\n", - " }\n", - "\n", - " .dataframe tbody tr th {\n", - " vertical-align: top;\n", - " }\n", - "\n", - " .dataframe thead th {\n", - " text-align: right;\n", - " }\n", - "</style>\n", - "<table border=\"1\" class=\"dataframe\">\n", - " <thead>\n", - " <tr style=\"text-align: right;\">\n", - " <th></th>\n", - " <th>Title</th>\n", - " <th>Genre</th>\n", - " <th>Director</th>\n", - " <th>Cast</th>\n", - " <th>Year</th>\n", - " <th>Runtime</th>\n", - " <th>Rating</th>\n", - " <th>Revenue</th>\n", - " </tr>\n", - " </thead>\n", - " <tbody>\n", - " <tr>\n", - " <th>0</th>\n", - " <td>Guardians of the Galaxy</td>\n", - " <td>Action,Adventure,Sci-Fi</td>\n", - " <td>James Gunn</td>\n", - " <td>Chris Pratt, Vin Diesel, Bradley Cooper, Zoe S...</td>\n", - " <td>2014</td>\n", - " <td>121</td>\n", - " <td>8.1</td>\n", - " <td>333.13</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1</th>\n", - " <td>Prometheus</td>\n", - " <td>Adventure,Mystery,Sci-Fi</td>\n", - " <td>Ridley Scott</td>\n", - " <td>Noomi Rapace, Logan Marshall-Green, Michael ...</td>\n", - " <td>2012</td>\n", - " <td>124</td>\n", - " <td>7.0</td>\n", - " <td>126.46M</td>\n", - " </tr>\n", - " <tr>\n", - " <th>2</th>\n", - " <td>Split</td>\n", - " <td>Horror,Thriller</td>\n", - " <td>M. Night Shyamalan</td>\n", - " <td>James McAvoy, Anya Taylor-Joy, Haley Lu Richar...</td>\n", - " <td>2016</td>\n", - " <td>117</td>\n", - " <td>7.3</td>\n", - " <td>138.12M</td>\n", - " </tr>\n", - " <tr>\n", - " <th>3</th>\n", - " <td>Sing</td>\n", - " <td>Animation,Comedy,Family</td>\n", - " <td>Christophe Lourdelet</td>\n", - " <td>Matthew McConaughey,Reese Witherspoon, Seth Ma...</td>\n", - " <td>2016</td>\n", - " <td>108</td>\n", - " <td>7.2</td>\n", - " <td>270.32</td>\n", - " </tr>\n", - " <tr>\n", - " <th>4</th>\n", - " <td>Suicide Squad</td>\n", - " <td>Action,Adventure,Fantasy</td>\n", - " <td>David Ayer</td>\n", - " <td>Will Smith, Jared Leto, Margot Robbie, Viola D...</td>\n", - " <td>2016</td>\n", - " <td>123</td>\n", - " <td>6.2</td>\n", - " <td>325.02</td>\n", - " </tr>\n", - " <tr>\n", - " <th>...</th>\n", - " <td>...</td>\n", - " <td>...</td>\n", - " <td>...</td>\n", - " <td>...</td>\n", - " <td>...</td>\n", - " <td>...</td>\n", - " <td>...</td>\n", - " <td>...</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1063</th>\n", - " <td>Guardians of the Galaxy Vol. 2</td>\n", - " <td>Action, Adventure, Comedy</td>\n", - " <td>James Gunn</td>\n", - " <td>Chris Pratt, Zoe Saldana, Dave Bautista, Vin D...</td>\n", - " <td>2017</td>\n", - " <td>136</td>\n", - " <td>7.6</td>\n", - " <td>389.81</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1064</th>\n", - " <td>Baby Driver</td>\n", - " <td>Action, Crime, Drama</td>\n", - " <td>Edgar Wright</td>\n", - " <td>Ansel Elgort, Jon Bernthal, Jon Hamm, Eiza Gon...</td>\n", - " <td>2017</td>\n", - " <td>113</td>\n", - " <td>7.6</td>\n", - " <td>107.83</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1065</th>\n", - " <td>Only the Brave</td>\n", - " <td>Action, Biography, Drama</td>\n", - " <td>Joseph Kosinski</td>\n", - " <td>Josh Brolin, Miles Teller, Jeff Bridges, Jenni...</td>\n", - " <td>2017</td>\n", - " <td>134</td>\n", - " <td>7.6</td>\n", - " <td>18.34</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1066</th>\n", - " <td>Incredibles 2</td>\n", - " <td>Animation, Action, Adventure</td>\n", - " <td>Brad Bird</td>\n", - " <td>Craig T. Nelson, Holly Hunter, Sarah Vowell, H...</td>\n", - " <td>2018</td>\n", - " <td>118</td>\n", - " <td>7.6</td>\n", - " <td>608.58</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1067</th>\n", - " <td>A Star Is Born</td>\n", - " <td>Drama, Music, Romance</td>\n", - " <td>Bradley Cooper</td>\n", - " <td>Lady Gaga, Bradley Cooper, Sam Elliott, Greg G...</td>\n", - " <td>2018</td>\n", - " <td>136</td>\n", - " <td>7.6</td>\n", - " <td>215.29</td>\n", - " </tr>\n", - " </tbody>\n", - "</table>\n", - "<p>1068 rows × 8 columns</p>\n", - "</div>" - ], - "text/plain": [ - " Title Genre \\\n", - "0 Guardians of the Galaxy Action,Adventure,Sci-Fi \n", - "1 Prometheus Adventure,Mystery,Sci-Fi \n", - "2 Split Horror,Thriller \n", - "3 Sing Animation,Comedy,Family \n", - "4 Suicide Squad Action,Adventure,Fantasy \n", - "... ... ... \n", - "1063 Guardians of the Galaxy Vol. 2 Action, Adventure, Comedy \n", - "1064 Baby Driver Action, Crime, Drama \n", - "1065 Only the Brave Action, Biography, Drama \n", - "1066 Incredibles 2 Animation, Action, Adventure \n", - "1067 A Star Is Born Drama, Music, Romance \n", - "\n", - " Director Cast \\\n", - "0 James Gunn Chris Pratt, Vin Diesel, Bradley Cooper, Zoe S... \n", - "1 Ridley Scott Noomi Rapace, Logan Marshall-Green, Michael ... \n", - "2 M. Night Shyamalan James McAvoy, Anya Taylor-Joy, Haley Lu Richar... \n", - "3 Christophe Lourdelet Matthew McConaughey,Reese Witherspoon, Seth Ma... \n", - "4 David Ayer Will Smith, Jared Leto, Margot Robbie, Viola D... \n", - "... ... ... \n", - "1063 James Gunn Chris Pratt, Zoe Saldana, Dave Bautista, Vin D... \n", - "1064 Edgar Wright Ansel Elgort, Jon Bernthal, Jon Hamm, Eiza Gon... \n", - "1065 Joseph Kosinski Josh Brolin, Miles Teller, Jeff Bridges, Jenni... \n", - "1066 Brad Bird Craig T. Nelson, Holly Hunter, Sarah Vowell, H... \n", - "1067 Bradley Cooper Lady Gaga, Bradley Cooper, Sam Elliott, Greg G... \n", - "\n", - " Year Runtime Rating Revenue \n", - "0 2014 121 8.1 333.13 \n", - "1 2012 124 7.0 126.46M \n", - "2 2016 117 7.3 138.12M \n", - "3 2016 108 7.2 270.32 \n", - "4 2016 123 6.2 325.02 \n", - "... ... ... ... ... \n", - "1063 2017 136 7.6 389.81 \n", - "1064 2017 113 7.6 107.83 \n", - "1065 2017 134 7.6 18.34 \n", - "1066 2018 118 7.6 608.58 \n", - "1067 2018 136 7.6 215.29 \n", - "\n", - "[1068 rows x 8 columns]" - ] - }, - "execution_count": 4, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "#use slicing to retain all the rows and columns excepting for column with integer position 0\n", - "movies = movies.iloc[:, 1:] \n", - "movies" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [], - "source": [ - "movies.to_csv(\"better_movies.csv\", index = False)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Warmup 3: Which movie has highest rating?" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "<div>\n", - "<style scoped>\n", - " .dataframe tbody tr th:only-of-type {\n", - " vertical-align: middle;\n", - " }\n", - "\n", - " .dataframe tbody tr th {\n", - " vertical-align: top;\n", - " }\n", - "\n", - " .dataframe thead th {\n", - " text-align: right;\n", - " }\n", - "</style>\n", - "<table border=\"1\" class=\"dataframe\">\n", - " <thead>\n", - " <tr style=\"text-align: right;\">\n", - " <th></th>\n", - " <th>Title</th>\n", - " <th>Genre</th>\n", - " <th>Director</th>\n", - " <th>Cast</th>\n", - " <th>Year</th>\n", - " <th>Runtime</th>\n", - " <th>Rating</th>\n", - " <th>Revenue</th>\n", - " </tr>\n", - " </thead>\n", - " <tbody>\n", - " <tr>\n", - " <th>54</th>\n", - " <td>The Dark Knight</td>\n", - " <td>Action,Crime,Drama</td>\n", - " <td>Christopher Nolan</td>\n", - " <td>Christian Bale, Heath Ledger, Aaron Eckhart,Mi...</td>\n", - " <td>2008</td>\n", - " <td>152</td>\n", - " <td>9.0</td>\n", - " <td>533.32</td>\n", - " </tr>\n", - " </tbody>\n", - "</table>\n", - "</div>" - ], - "text/plain": [ - " Title Genre Director \\\n", - "54 The Dark Knight Action,Crime,Drama Christopher Nolan \n", - "\n", - " Cast Year Runtime Rating \\\n", - "54 Christian Bale, Heath Ledger, Aaron Eckhart,Mi... 2008 152 9.0 \n", - "\n", - " Revenue \n", - "54 533.32 " - ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "max_rating = movies[\"Rating\"].max()\n", - "movies[movies[\"Rating\"] == max_rating]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Warmup 4: Which movies were released in 2020?" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "<div>\n", - "<style scoped>\n", - " .dataframe tbody tr th:only-of-type {\n", - " vertical-align: middle;\n", - " }\n", - "\n", - " .dataframe tbody tr th {\n", - " vertical-align: top;\n", - " }\n", - "\n", - " .dataframe thead th {\n", - " text-align: right;\n", - " }\n", - "</style>\n", - "<table border=\"1\" class=\"dataframe\">\n", - " <thead>\n", - " <tr style=\"text-align: right;\">\n", - " <th></th>\n", - " <th>Title</th>\n", - " <th>Genre</th>\n", - " <th>Director</th>\n", - " <th>Cast</th>\n", - " <th>Year</th>\n", - " <th>Runtime</th>\n", - " <th>Rating</th>\n", - " <th>Revenue</th>\n", - " </tr>\n", - " </thead>\n", - " <tbody>\n", - " <tr>\n", - " <th>998</th>\n", - " <td>Hamilton</td>\n", - " <td>Biography, Drama, History</td>\n", - " <td>Thomas Kail</td>\n", - " <td>Lin-Manuel Miranda, Phillipa Soo, Leslie Odom ...</td>\n", - " <td>2020</td>\n", - " <td>160</td>\n", - " <td>8.6</td>\n", - " <td>612.82</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1000</th>\n", - " <td>Soorarai Pottru</td>\n", - " <td>Drama</td>\n", - " <td>Sudha Kongara</td>\n", - " <td>Suriya, Madhavan, Paresh Rawal, Aparna Balamurali</td>\n", - " <td>2020</td>\n", - " <td>153</td>\n", - " <td>8.6</td>\n", - " <td>5.93</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1022</th>\n", - " <td>Soul</td>\n", - " <td>Animation, Adventure, Comedy</td>\n", - " <td>Pete Docter</td>\n", - " <td>Kemp Powers, Jamie Foxx, Tina Fey, Graham Norton</td>\n", - " <td>2020</td>\n", - " <td>100</td>\n", - " <td>8.1</td>\n", - " <td>121.0</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1031</th>\n", - " <td>Dil Bechara</td>\n", - " <td>Comedy, Drama, Romance</td>\n", - " <td>Mukesh Chhabra</td>\n", - " <td>Sushant Singh Rajput, Sanjana Sanghi, Sahil Va...</td>\n", - " <td>2020</td>\n", - " <td>101</td>\n", - " <td>7.9</td>\n", - " <td>263.61</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1047</th>\n", - " <td>The Trial of the Chicago 7</td>\n", - " <td>Drama, History, Thriller</td>\n", - " <td>Aaron Sorkin</td>\n", - " <td>Eddie Redmayne, Alex Sharp, Sacha Baron Cohen,...</td>\n", - " <td>2020</td>\n", - " <td>129</td>\n", - " <td>7.8</td>\n", - " <td>0.12</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1048</th>\n", - " <td>Druk</td>\n", - " <td>Comedy, Drama</td>\n", - " <td>Thomas Vinterberg</td>\n", - " <td>Mads Mikkelsen, Thomas Bo Larsen, Magnus Milla...</td>\n", - " <td>2020</td>\n", - " <td>117</td>\n", - " <td>7.8</td>\n", - " <td>21.71</td>\n", - " </tr>\n", - " </tbody>\n", - "</table>\n", - "</div>" - ], - "text/plain": [ - " Title Genre \\\n", - "998 Hamilton Biography, Drama, History \n", - "1000 Soorarai Pottru Drama \n", - "1022 Soul Animation, Adventure, Comedy \n", - "1031 Dil Bechara Comedy, Drama, Romance \n", - "1047 The Trial of the Chicago 7 Drama, History, Thriller \n", - "1048 Druk Comedy, Drama \n", - "\n", - " Director Cast \\\n", - "998 Thomas Kail Lin-Manuel Miranda, Phillipa Soo, Leslie Odom ... \n", - "1000 Sudha Kongara Suriya, Madhavan, Paresh Rawal, Aparna Balamurali \n", - "1022 Pete Docter Kemp Powers, Jamie Foxx, Tina Fey, Graham Norton \n", - "1031 Mukesh Chhabra Sushant Singh Rajput, Sanjana Sanghi, Sahil Va... \n", - "1047 Aaron Sorkin Eddie Redmayne, Alex Sharp, Sacha Baron Cohen,... \n", - "1048 Thomas Vinterberg Mads Mikkelsen, Thomas Bo Larsen, Magnus Milla... \n", - "\n", - " Year Runtime Rating Revenue \n", - "998 2020 160 8.6 612.82 \n", - "1000 2020 153 8.6 5.93 \n", - "1022 2020 100 8.1 121.0 \n", - "1031 2020 101 7.9 263.61 \n", - "1047 2020 129 7.8 0.12 \n", - "1048 2020 117 7.8 21.71 " - ] - }, - "execution_count": 7, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "movies[movies[\"Year\"] == 2020]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Warmup 5a: What does this function do?" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [], - "source": [ - "def format_revenue(revenue):\n", - " if type(revenue) == float: # need this in here if we run code multiple times\n", - " return revenue\n", - " elif revenue[-1] == 'M': # some have an \"M\" at the end\n", - " return float(revenue[:-1]) * 1e6\n", - " else: # otherwise, assume millions.\n", - " return float(revenue) * 1e6" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Warmup 5b: Using the above function, create a new column called \"Revenue in dollars\" by applying appropriate conversion to Revenue column." - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "<div>\n", - "<style scoped>\n", - " .dataframe tbody tr th:only-of-type {\n", - " vertical-align: middle;\n", - " }\n", - "\n", - " .dataframe tbody tr th {\n", - " vertical-align: top;\n", - " }\n", - "\n", - " .dataframe thead th {\n", - " text-align: right;\n", - " }\n", - "</style>\n", - "<table border=\"1\" class=\"dataframe\">\n", - " <thead>\n", - " <tr style=\"text-align: right;\">\n", - " <th></th>\n", - " <th>Title</th>\n", - " <th>Genre</th>\n", - " <th>Director</th>\n", - " <th>Cast</th>\n", - " <th>Year</th>\n", - " <th>Runtime</th>\n", - " <th>Rating</th>\n", - " <th>Revenue</th>\n", - " <th>Revenue in dollars</th>\n", - " </tr>\n", - " </thead>\n", - " <tbody>\n", - " <tr>\n", - " <th>0</th>\n", - " <td>Guardians of the Galaxy</td>\n", - " <td>Action,Adventure,Sci-Fi</td>\n", - " <td>James Gunn</td>\n", - " <td>Chris Pratt, Vin Diesel, Bradley Cooper, Zoe S...</td>\n", - " <td>2014</td>\n", - " <td>121</td>\n", - " <td>8.1</td>\n", - " <td>333.13</td>\n", - " <td>333130000.0</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1</th>\n", - " <td>Prometheus</td>\n", - " <td>Adventure,Mystery,Sci-Fi</td>\n", - " <td>Ridley Scott</td>\n", - " <td>Noomi Rapace, Logan Marshall-Green, Michael ...</td>\n", - " <td>2012</td>\n", - " <td>124</td>\n", - " <td>7.0</td>\n", - " <td>126.46M</td>\n", - " <td>126460000.0</td>\n", - " </tr>\n", - " <tr>\n", - " <th>2</th>\n", - " <td>Split</td>\n", - " <td>Horror,Thriller</td>\n", - " <td>M. Night Shyamalan</td>\n", - " <td>James McAvoy, Anya Taylor-Joy, Haley Lu Richar...</td>\n", - " <td>2016</td>\n", - " <td>117</td>\n", - " <td>7.3</td>\n", - " <td>138.12M</td>\n", - " <td>138120000.0</td>\n", - " </tr>\n", - " <tr>\n", - " <th>3</th>\n", - " <td>Sing</td>\n", - " <td>Animation,Comedy,Family</td>\n", - " <td>Christophe Lourdelet</td>\n", - " <td>Matthew McConaughey,Reese Witherspoon, Seth Ma...</td>\n", - " <td>2016</td>\n", - " <td>108</td>\n", - " <td>7.2</td>\n", - " <td>270.32</td>\n", - " <td>270320000.0</td>\n", - " </tr>\n", - " <tr>\n", - " <th>4</th>\n", - " <td>Suicide Squad</td>\n", - " <td>Action,Adventure,Fantasy</td>\n", - " <td>David Ayer</td>\n", - " <td>Will Smith, Jared Leto, Margot Robbie, Viola D...</td>\n", - " <td>2016</td>\n", - " <td>123</td>\n", - " <td>6.2</td>\n", - " <td>325.02</td>\n", - " <td>325020000.0</td>\n", - " </tr>\n", - " <tr>\n", - " <th>...</th>\n", - " <td>...</td>\n", - " <td>...</td>\n", - " <td>...</td>\n", - " <td>...</td>\n", - " <td>...</td>\n", - " <td>...</td>\n", - " <td>...</td>\n", - " <td>...</td>\n", - " <td>...</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1063</th>\n", - " <td>Guardians of the Galaxy Vol. 2</td>\n", - " <td>Action, Adventure, Comedy</td>\n", - " <td>James Gunn</td>\n", - " <td>Chris Pratt, Zoe Saldana, Dave Bautista, Vin D...</td>\n", - " <td>2017</td>\n", - " <td>136</td>\n", - " <td>7.6</td>\n", - " <td>389.81</td>\n", - " <td>389810000.0</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1064</th>\n", - " <td>Baby Driver</td>\n", - " <td>Action, Crime, Drama</td>\n", - " <td>Edgar Wright</td>\n", - " <td>Ansel Elgort, Jon Bernthal, Jon Hamm, Eiza Gon...</td>\n", - " <td>2017</td>\n", - " <td>113</td>\n", - " <td>7.6</td>\n", - " <td>107.83</td>\n", - " <td>107830000.0</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1065</th>\n", - " <td>Only the Brave</td>\n", - " <td>Action, Biography, Drama</td>\n", - " <td>Joseph Kosinski</td>\n", - " <td>Josh Brolin, Miles Teller, Jeff Bridges, Jenni...</td>\n", - " <td>2017</td>\n", - " <td>134</td>\n", - " <td>7.6</td>\n", - " <td>18.34</td>\n", - " <td>18340000.0</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1066</th>\n", - " <td>Incredibles 2</td>\n", - " <td>Animation, Action, Adventure</td>\n", - " <td>Brad Bird</td>\n", - " <td>Craig T. Nelson, Holly Hunter, Sarah Vowell, H...</td>\n", - " <td>2018</td>\n", - " <td>118</td>\n", - " <td>7.6</td>\n", - " <td>608.58</td>\n", - " <td>608580000.0</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1067</th>\n", - " <td>A Star Is Born</td>\n", - " <td>Drama, Music, Romance</td>\n", - " <td>Bradley Cooper</td>\n", - " <td>Lady Gaga, Bradley Cooper, Sam Elliott, Greg G...</td>\n", - " <td>2018</td>\n", - " <td>136</td>\n", - " <td>7.6</td>\n", - " <td>215.29</td>\n", - " <td>215290000.0</td>\n", - " </tr>\n", - " </tbody>\n", - "</table>\n", - "<p>1068 rows × 9 columns</p>\n", - "</div>" - ], - "text/plain": [ - " Title Genre \\\n", - "0 Guardians of the Galaxy Action,Adventure,Sci-Fi \n", - "1 Prometheus Adventure,Mystery,Sci-Fi \n", - "2 Split Horror,Thriller \n", - "3 Sing Animation,Comedy,Family \n", - "4 Suicide Squad Action,Adventure,Fantasy \n", - "... ... ... \n", - "1063 Guardians of the Galaxy Vol. 2 Action, Adventure, Comedy \n", - "1064 Baby Driver Action, Crime, Drama \n", - "1065 Only the Brave Action, Biography, Drama \n", - "1066 Incredibles 2 Animation, Action, Adventure \n", - "1067 A Star Is Born Drama, Music, Romance \n", - "\n", - " Director Cast \\\n", - "0 James Gunn Chris Pratt, Vin Diesel, Bradley Cooper, Zoe S... \n", - "1 Ridley Scott Noomi Rapace, Logan Marshall-Green, Michael ... \n", - "2 M. Night Shyamalan James McAvoy, Anya Taylor-Joy, Haley Lu Richar... \n", - "3 Christophe Lourdelet Matthew McConaughey,Reese Witherspoon, Seth Ma... \n", - "4 David Ayer Will Smith, Jared Leto, Margot Robbie, Viola D... \n", - "... ... ... \n", - "1063 James Gunn Chris Pratt, Zoe Saldana, Dave Bautista, Vin D... \n", - "1064 Edgar Wright Ansel Elgort, Jon Bernthal, Jon Hamm, Eiza Gon... \n", - "1065 Joseph Kosinski Josh Brolin, Miles Teller, Jeff Bridges, Jenni... \n", - "1066 Brad Bird Craig T. Nelson, Holly Hunter, Sarah Vowell, H... \n", - "1067 Bradley Cooper Lady Gaga, Bradley Cooper, Sam Elliott, Greg G... \n", - "\n", - " Year Runtime Rating Revenue Revenue in dollars \n", - "0 2014 121 8.1 333.13 333130000.0 \n", - "1 2012 124 7.0 126.46M 126460000.0 \n", - "2 2016 117 7.3 138.12M 138120000.0 \n", - "3 2016 108 7.2 270.32 270320000.0 \n", - "4 2016 123 6.2 325.02 325020000.0 \n", - "... ... ... ... ... ... \n", - "1063 2017 136 7.6 389.81 389810000.0 \n", - "1064 2017 113 7.6 107.83 107830000.0 \n", - "1065 2017 134 7.6 18.34 18340000.0 \n", - "1066 2018 118 7.6 608.58 608580000.0 \n", - "1067 2018 136 7.6 215.29 215290000.0 \n", - "\n", - "[1068 rows x 9 columns]" - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "movies[\"Revenue in dollars\"] = movies[\"Revenue\"].apply(format_revenue)\n", - "movies" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Warmup 6: What are the top 10 highest-revenue movies?" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "<div>\n", - "<style scoped>\n", - " .dataframe tbody tr th:only-of-type {\n", - " vertical-align: middle;\n", - " }\n", - "\n", - " .dataframe tbody tr th {\n", - " vertical-align: top;\n", - " }\n", - "\n", - " .dataframe thead th {\n", - " text-align: right;\n", - " }\n", - "</style>\n", - "<table border=\"1\" class=\"dataframe\">\n", - " <thead>\n", - " <tr style=\"text-align: right;\">\n", - " <th></th>\n", - " <th>Title</th>\n", - " <th>Genre</th>\n", - " <th>Director</th>\n", - " <th>Cast</th>\n", - " <th>Year</th>\n", - " <th>Runtime</th>\n", - " <th>Rating</th>\n", - " <th>Revenue</th>\n", - " <th>Revenue in dollars</th>\n", - " </tr>\n", - " </thead>\n", - " <tbody>\n", - " <tr>\n", - " <th>50</th>\n", - " <td>Star Wars: Episode VII - The Force Awakens</td>\n", - " <td>Action,Adventure,Fantasy</td>\n", - " <td>J.J. Abrams</td>\n", - " <td>Daisy Ridley, John Boyega, Oscar Isaac, Domhna...</td>\n", - " <td>2015</td>\n", - " <td>136</td>\n", - " <td>8.1</td>\n", - " <td>936.63</td>\n", - " <td>936630000.0</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1006</th>\n", - " <td>Avengers: Endgame</td>\n", - " <td>Action, Adventure, Drama</td>\n", - " <td>Anthony Russo</td>\n", - " <td>Joe Russo, Robert Downey Jr., Chris Evans, Mar...</td>\n", - " <td>2019</td>\n", - " <td>181</td>\n", - " <td>8.4</td>\n", - " <td>858.37</td>\n", - " <td>858370000.0</td>\n", - " </tr>\n", - " <tr>\n", - " <th>87</th>\n", - " <td>Avatar</td>\n", - " <td>Action,Adventure,Fantasy</td>\n", - " <td>James Cameron</td>\n", - " <td>Sam Worthington, Zoe Saldana, Sigourney Weaver...</td>\n", - " <td>2009</td>\n", - " <td>162</td>\n", - " <td>7.8</td>\n", - " <td>760.51</td>\n", - " <td>760510000.0</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1007</th>\n", - " <td>Avengers: Infinity War</td>\n", - " <td>Action, Adventure, Sci-Fi</td>\n", - " <td>Anthony Russo</td>\n", - " <td>Joe Russo, Robert Downey Jr., Chris Hemsworth,...</td>\n", - " <td>2018</td>\n", - " <td>149</td>\n", - " <td>8.4</td>\n", - " <td>678.82</td>\n", - " <td>678820000.0</td>\n", - " </tr>\n", - " <tr>\n", - " <th>85</th>\n", - " <td>Jurassic World</td>\n", - " <td>Action,Adventure,Sci-Fi</td>\n", - " <td>Colin Trevorrow</td>\n", - " <td>Chris Pratt, Bryce Dallas Howard, Ty Simpkins,...</td>\n", - " <td>2015</td>\n", - " <td>124</td>\n", - " <td>7.0</td>\n", - " <td>652.18</td>\n", - " <td>652180000.0</td>\n", - " </tr>\n", - " <tr>\n", - " <th>76</th>\n", - " <td>The Avengers</td>\n", - " <td>Action,Sci-Fi</td>\n", - " <td>Joss Whedon</td>\n", - " <td>Robert Downey Jr., Chris Evans, Scarlett Johan...</td>\n", - " <td>2012</td>\n", - " <td>143</td>\n", - " <td>8.1</td>\n", - " <td>623.28</td>\n", - " <td>623280000.0</td>\n", - " </tr>\n", - " <tr>\n", - " <th>998</th>\n", - " <td>Hamilton</td>\n", - " <td>Biography, Drama, History</td>\n", - " <td>Thomas Kail</td>\n", - " <td>Lin-Manuel Miranda, Phillipa Soo, Leslie Odom ...</td>\n", - " <td>2020</td>\n", - " <td>160</td>\n", - " <td>8.6</td>\n", - " <td>612.82</td>\n", - " <td>612820000.0</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1066</th>\n", - " <td>Incredibles 2</td>\n", - " <td>Animation, Action, Adventure</td>\n", - " <td>Brad Bird</td>\n", - " <td>Craig T. Nelson, Holly Hunter, Sarah Vowell, H...</td>\n", - " <td>2018</td>\n", - " <td>118</td>\n", - " <td>7.6</td>\n", - " <td>608.58</td>\n", - " <td>608580000.0</td>\n", - " </tr>\n", - " <tr>\n", - " <th>54</th>\n", - " <td>The Dark Knight</td>\n", - " <td>Action,Crime,Drama</td>\n", - " <td>Christopher Nolan</td>\n", - " <td>Christian Bale, Heath Ledger, Aaron Eckhart,Mi...</td>\n", - " <td>2008</td>\n", - " <td>152</td>\n", - " <td>9.0</td>\n", - " <td>533.32</td>\n", - " <td>533320000.0</td>\n", - " </tr>\n", - " <tr>\n", - " <th>12</th>\n", - " <td>Rogue One</td>\n", - " <td>Action,Adventure,Sci-Fi</td>\n", - " <td>Gareth Edwards</td>\n", - " <td>Felicity Jones, Diego Luna, Alan Tudyk, Donnie...</td>\n", - " <td>2016</td>\n", - " <td>133</td>\n", - " <td>7.9</td>\n", - " <td>532.17</td>\n", - " <td>532170000.0</td>\n", - " </tr>\n", - " </tbody>\n", - "</table>\n", - "</div>" - ], - "text/plain": [ - " Title \\\n", - "50 Star Wars: Episode VII - The Force Awakens \n", - "1006 Avengers: Endgame \n", - "87 Avatar \n", - "1007 Avengers: Infinity War \n", - "85 Jurassic World \n", - "76 The Avengers \n", - "998 Hamilton \n", - "1066 Incredibles 2 \n", - "54 The Dark Knight \n", - "12 Rogue One \n", - "\n", - " Genre Director \\\n", - "50 Action,Adventure,Fantasy J.J. Abrams \n", - "1006 Action, Adventure, Drama Anthony Russo \n", - "87 Action,Adventure,Fantasy James Cameron \n", - "1007 Action, Adventure, Sci-Fi Anthony Russo \n", - "85 Action,Adventure,Sci-Fi Colin Trevorrow \n", - "76 Action,Sci-Fi Joss Whedon \n", - "998 Biography, Drama, History Thomas Kail \n", - "1066 Animation, Action, Adventure Brad Bird \n", - "54 Action,Crime,Drama Christopher Nolan \n", - "12 Action,Adventure,Sci-Fi Gareth Edwards \n", - "\n", - " Cast Year Runtime \\\n", - "50 Daisy Ridley, John Boyega, Oscar Isaac, Domhna... 2015 136 \n", - "1006 Joe Russo, Robert Downey Jr., Chris Evans, Mar... 2019 181 \n", - "87 Sam Worthington, Zoe Saldana, Sigourney Weaver... 2009 162 \n", - "1007 Joe Russo, Robert Downey Jr., Chris Hemsworth,... 2018 149 \n", - "85 Chris Pratt, Bryce Dallas Howard, Ty Simpkins,... 2015 124 \n", - "76 Robert Downey Jr., Chris Evans, Scarlett Johan... 2012 143 \n", - "998 Lin-Manuel Miranda, Phillipa Soo, Leslie Odom ... 2020 160 \n", - "1066 Craig T. Nelson, Holly Hunter, Sarah Vowell, H... 2018 118 \n", - "54 Christian Bale, Heath Ledger, Aaron Eckhart,Mi... 2008 152 \n", - "12 Felicity Jones, Diego Luna, Alan Tudyk, Donnie... 2016 133 \n", - "\n", - " Rating Revenue Revenue in dollars \n", - "50 8.1 936.63 936630000.0 \n", - "1006 8.4 858.37 858370000.0 \n", - "87 7.8 760.51 760510000.0 \n", - "1007 8.4 678.82 678820000.0 \n", - "85 7.0 652.18 652180000.0 \n", - "76 8.1 623.28 623280000.0 \n", - "998 8.6 612.82 612820000.0 \n", - "1066 7.6 608.58 608580000.0 \n", - "54 9.0 533.32 533320000.0 \n", - "12 7.9 532.17 532170000.0 " - ] - }, - "execution_count": 10, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "movies.sort_values(by = \"Revenue in dollars\", ascending = False).head(10)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Warmup 7: Which shortest movies (below average runtime) have highest rating?" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "<div>\n", - "<style scoped>\n", - " .dataframe tbody tr th:only-of-type {\n", - " vertical-align: middle;\n", - " }\n", - "\n", - " .dataframe tbody tr th {\n", - " vertical-align: top;\n", - " }\n", - "\n", - " .dataframe thead th {\n", - " text-align: right;\n", - " }\n", - "</style>\n", - "<table border=\"1\" class=\"dataframe\">\n", - " <thead>\n", - " <tr style=\"text-align: right;\">\n", - " <th></th>\n", - " <th>Title</th>\n", - " <th>Genre</th>\n", - " <th>Director</th>\n", - " <th>Cast</th>\n", - " <th>Year</th>\n", - " <th>Runtime</th>\n", - " <th>Rating</th>\n", - " <th>Revenue</th>\n", - " <th>Revenue in dollars</th>\n", - " </tr>\n", - " </thead>\n", - " <tbody>\n", - " <tr>\n", - " <th>96</th>\n", - " <td>Kimi no na wa</td>\n", - " <td>Animation,Drama,Fantasy</td>\n", - " <td>Makoto Shinkai</td>\n", - " <td>Ryûnosuke Kamiki, Mone Kamishiraishi, Ryô Nari...</td>\n", - " <td>2016</td>\n", - " <td>106</td>\n", - " <td>8.6</td>\n", - " <td>4.68</td>\n", - " <td>4680000.0</td>\n", - " </tr>\n", - " <tr>\n", - " <th>249</th>\n", - " <td>The Intouchables</td>\n", - " <td>Biography,Comedy,Drama</td>\n", - " <td>Olivier Nakache</td>\n", - " <td>François Cluzet, Omar Sy, Anne Le Ny, Audrey F...</td>\n", - " <td>2011</td>\n", - " <td>112</td>\n", - " <td>8.6</td>\n", - " <td>13.18</td>\n", - " <td>13180000.0</td>\n", - " </tr>\n", - " </tbody>\n", - "</table>\n", - "</div>" - ], - "text/plain": [ - " Title Genre Director \\\n", - "96 Kimi no na wa Animation,Drama,Fantasy Makoto Shinkai \n", - "249 The Intouchables Biography,Comedy,Drama Olivier Nakache \n", - "\n", - " Cast Year Runtime Rating \\\n", - "96 Ryûnosuke Kamiki, Mone Kamishiraishi, Ryô Nari... 2016 106 8.6 \n", - "249 François Cluzet, Omar Sy, Anne Le Ny, Audrey F... 2011 112 8.6 \n", - "\n", - " Revenue Revenue in dollars \n", - "96 4.68 4680000.0 \n", - "249 13.18 13180000.0 " - ] - }, - "execution_count": 11, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "short_movies = movies[movies[\"Runtime\"] < movies[\"Runtime\"].mean()]\n", - "short_movies[short_movies[\"Rating\"] == short_movies[\"Rating\"].max()]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Learning Objectives\n", - "\n", - "- Make a request for data using requests.get(URL)\n", - "- Check the status of a request/response\n", - "- Extract the text of a response\n", - "- Create a json file from a response\n", - "- State and practice good etiquette when getting data" - ] - }, - { - "attachments": { - "Client_server.png": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAABSIAAAJQCAYAAACaZRpjAAAMa2lDQ1BJQ0MgUHJvZmlsZQAASImVVwdYU8kWnluSkJDQAhGQEnoTRHqREkKLICBVsBGSQEKJMSGI2NFFBXtBFCu6KqLoWgBZVMReFsXeF2VRWVkXdVEUlTcpoOu+8r3zfXPnv2fO/KfcmXvvAKDdx5VIclEdAPLE+dL4iBDm+NQ0JukZQAEOKMAZ6HB5MgkrLi4aQBns/y7vbgNE0d9wVnD9c/y/ih5fIOMBgEyEOIMv4+VB3AwAvoknkeYDQFTorabnSxR4HsT6UhggxGsVOEuF9yhwhgo3KW0S49kQXwNAg8rlSrMA0HoI9cwCXhbk0foEsauYLxIDoD0C4kCekMuHWBH7iLy8qQpcAbE9tJdADOMBPhnfcGb9jT9jiJ/LzRrCqryUohEqkklyuTP+z9L8b8nLlQ/6sIWNKpRGxivyhzW8mzM1SoGpEHeLM2JiFbWGuE/EV9UdAJQilEcmqexRE56MDesHGBC78rmhURCbQBwuzo2JVuszMkXhHIjhakELRfmcRIgNIV4skIUlqG22SafGq32hdZlSNkutv8CVKv0qfD2W5ySx1PxvhAKOmh/TKhImpkBMgdi6QJQcA7EWxC6ynIQotc3oIiE7ZtBGKo9XxG8NcbxAHBGi4scKMqXh8Wr70jzZYL7YNqGIE6PGh/KFiZGq+mBneFxl/DAX7JpAzEoa5BHIxkcP5sIXhIapcsdeCMRJCWqePkl+SLxqLk6R5Map7XFLQW6EQm8JsYesIEE9F0/Oh4tTxY9nSvLjElVx4kXZ3DFxqnjwlSAasEEoYAI5bBlgKsgGotbu+m54pxoJB1wgBVlAAHeoSjM4I0U5IobXBFAE/oBIAGRD80KUowJQAPWfh7SqqzPIVI4WKGfkgGcQ54EokAvv5cpZ4iFvyeA3qBH9wzsXNh6MNxc2xfi/1w9qv2pYUBOt1sgHPTK1By2JYcRQYiQxnOiAG+OBuD8eDa/BsLnhPrjvYB5f7QnPCG2Ep4RbhHbCvSmiYul3UY4F7ZA/XF2LjG9rgdtCTk88BA+A7JAZZ+DGwBn3gH5YeBD07Am1bHXciqowv+P+WwbfPA21HdmVjJKHkYPJ9t/P1HLU8hxiUdT62/qoYs0Yqjd7aOR7/+xvqs+HfdT3lthi7DB2HjuFXcSasHrAxE5iDdgV7LgCD62u35Sra9BbvDKeHMgj+oc/rtqnopIy1xrXLtdPqrF8QWG+YuOxp0pmSEVZwnwmC34dBEyOmOcygunm6uYGgOJbo3p9vWUovyEI49JXXfEyAAI8BgYGmr7qorUBOAL3DKXjq87eD74mCgG4sJwnlxaodLjiQoBvCW2404yAGbAC9jAfN+AF/EEwCANjQCxIBKlgMqyyEK5zKZgOZoH5oASUgZVgHdgItoIdYA/YDw6BetAEToFz4DK4Bm6BB3D1dIKXoAe8A/0IgpAQGkJHjBBzxAZxQtwQHyQQCUOikXgkFUlHshAxIkdmIQuQMmQ1shHZjlQjPyHHkFPIRaQNuYc8QbqQN8hHFEOpqD5qitqiI1EflIVGoYnoJDQLnYYWoQvR5WgFWoXuQ+vQU+hl9Bbajr5EezGAaWIMzAJzxnwwNhaLpWGZmBSbg5Vi5VgVVos1wud8A2vHurEPOBGn40zcGa7gSDwJ5+HT8Dn4Unwjvgevw8/gN/AneA/+hUAjmBCcCH4EDmE8IYswnVBCKCfsIhwlnIV7qZPwjkgkMoh2RG+4F1OJ2cSZxKXEzcQDxGZiG7GD2EsikYxITqQAUiyJS8onlZA2kPaRTpKukzpJfRqaGuYabhrhGmkaYo1ijXKNvRonNK5rPNfoJ+uQbch+5FgynzyDvIK8k9xIvkruJPdTdCl2lABKIiWbMp9SQamlnKU8pLzV1NS01PTVHKcp0pynWaF5UPOC5hPND1Q9qiOVTZ1IlVOXU3dTm6n3qG9pNJotLZiWRsunLadV007THtP6tOhaLlocLb7WXK1KrTqt61qvtMnaNtos7cnaRdrl2oe1r2p365B1bHXYOlydOTqVOsd07uj06tJ1R+nG6ubpLtXdq3tR94UeSc9WL0yPr7dQb4feab0OOka3orPpPPoC+k76WXqnPlHfTp+jn61fpr9fv1W/x0DPwMMg2aDQoNLguEE7A2PYMjiMXMYKxiHGbcbHYabDWMMEw5YMqx12fdh7w+GGwYYCw1LDA4a3DD8aMY3CjHKMVhnVGz0yxo0djccZTzfeYnzWuHu4/nD/4bzhpcMPDb9vgpo4msSbzDTZYXLFpNfUzDTCVGK6wfS0abcZwyzYLNtsrdkJsy5zunmguch8rflJ89+ZBkwWM5dZwTzD7LEwsYi0kFtst2i16Le0s0yyLLY8YPnIimLlY5VptdaqxarH2tx6rPUs6xrr+zZkGx8boc16m/M2723tbFNsF9nW276wM7Tj2BXZ1dg9tKfZB9lPs6+yv+lAdPBxyHHY7HDNEXX0dBQ6VjpedUKdvJxETpud2kYQRviOEI+oGnHHmerMci5wrnF+4sJwiXYpdql3eTXSemTayFUjz4/84urpmuu60/XBKL1RY0YVj2oc9cbN0Y3nVul2053mHu4+173B/bWHk4fAY4vHXU+651jPRZ4tnp+9vL2kXrVeXd7W3unem7zv+Oj7xPks9bngS/AN8Z3r2+T7wc/LL9/vkN+f/s7+Of57/V+MthstGL1zdEeAZQA3YHtAeyAzMD1wW2B7kEUQN6gq6GmwVTA/eFfwc5YDK5u1j/UqxDVEGnI05D3bjz2b3RyKhUaEloa2humFJYVtDHscbhmeFV4T3hPhGTEzojmSEBkVuSryDseUw+NUc3rGeI+ZPeZMFDUqIWpj1NNox2hpdONYdOyYsWvGPoyxiRHH1MeCWE7smthHcXZx0+J+HkccFzeuctyz+FHxs+LPJ9ATpiTsTXiXGJK4IvFBkn2SPKklWTt5YnJ18vuU0JTVKe3jR46fPf5yqnGqKLUhjZSWnLYrrXdC2IR1Ezonek4smXh7kt2kwkkXJxtPzp18fIr2FO6Uw+mE9JT0vemfuLHcKm5vBidjU0YPj81bz3vJD+av5XcJAgSrBc8zAzJXZ77ICshak9UlDBKWC7tFbNFG0evsyOyt2e9zYnN25wzkpuQeyNPIS887JtYT54jPTDWbWji1TeIkKZG0T/Obtm5ajzRKukuGyCbJGvL14U/9Fbm9/Af5k4LAgsqCvunJ0w8X6haKC6/McJyxZMbzovCiH2fiM3kzW2ZZzJo/68ls1uztc5A5GXNa5lrNXTi3c17EvD3zKfNz5v9S7Fq8uvivBSkLGheaLpy3sOOHiB9qSrRKpCV3Fvkv2roYXyxa3LrEfcmGJV9K+aWXylzLyss+LeUtvbRs1LKKZQPLM5e3rvBasWUlcaV45e1VQav2rNZdXbS6Y83YNXVrmWtL1/61bsq6i+Ue5VvXU9bL17dXRFc0bLDesHLDp43CjbcqQyoPbDLZtGTT+838zde3BG+p3Wq6tWzrx22ibXe3R2yvq7KtKt9B3FGw49nO5J3nf/T5sXqX8a6yXZ93i3e374nfc6bau7p6r8neFTVojbyma9/Efdf2h+5vqHWu3X6AcaDsIDgoP/j7T+k/3T4UdajlsM/h2iM2RzYdpR8trUPqZtT11Avr2xtSG9qOjTnW0ujfePRnl593N1k0VR43OL7iBOXEwhMDJ4tO9jZLmrtPZZ3qaJnS8uD0+NM3z4w703o26uyFc+HnTp9nnT95IeBC00W/i8cu+Vyqv+x1ue6K55Wjv3j+crTVq7XuqvfVhmu+1xrbRreduB50/dSN0BvnbnJuXr4Vc6vtdtLtu3cm3mm/y7/74l7uvdf3C+73P5j3kPCw9JHOo/LHJo+rfnX49UC7V/vxJ6FPrjxNePqgg9fx8jfZb586Fz6jPSt/bv68+oXbi6au8K5rv0/4vfOl5GV/d8kfun9semX/6sifwX9e6Rnf0/la+nrgzdK3Rm93/+XxV0tvXO/jd3nv+t+X9hn17fng8+H8x5SPz/unfyJ9qvjs8LnxS9SXhwN5AwMSrpSr/BXAYEMzMwF4sxsAWioAdHhuo0xQnQWVgqjOr0oE/hNWnReV4gVALewUv/HsZgAOwmYLG20eAIpf+MRggLq7DzW1yDLd3VRcVHgSIvQNDLw1BYDUCMBn6cBA/+aBgc87YbD3AGiepjqDKoQIzwzblBzXGYXzwHeiOp9+k+P3PVBE4AG+7/8FlTiO10mPo7EAAACKZVhJZk1NACoAAAAIAAQBGgAFAAAAAQAAAD4BGwAFAAAAAQAAAEYBKAADAAAAAQACAACHaQAEAAAAAQAAAE4AAAAAAAAAkAAAAAEAAACQAAAAAQADkoYABwAAABIAAAB4oAIABAAAAAEAAAUioAMABAAAAAEAAAJQAAAAAEFTQ0lJAAAAU2NyZWVuc2hvdHZ0poQAAAAJcEhZcwAAFiUAABYlAUlSJPAAAAHXaVRYdFhNTDpjb20uYWRvYmUueG1wAAAAAAA8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJYTVAgQ29yZSA2LjAuMCI+CiAgIDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+CiAgICAgIDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiCiAgICAgICAgICAgIHhtbG5zOmV4aWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vZXhpZi8xLjAvIj4KICAgICAgICAgPGV4aWY6UGl4ZWxZRGltZW5zaW9uPjU5MjwvZXhpZjpQaXhlbFlEaW1lbnNpb24+CiAgICAgICAgIDxleGlmOlBpeGVsWERpbWVuc2lvbj4xMzE0PC9leGlmOlBpeGVsWERpbWVuc2lvbj4KICAgICAgICAgPGV4aWY6VXNlckNvbW1lbnQ+U2NyZWVuc2hvdDwvZXhpZjpVc2VyQ29tbWVudD4KICAgICAgPC9yZGY6RGVzY3JpcHRpb24+CiAgIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+CtqejFIAAAAcaURPVAAAAAIAAAAAAAABKAAAACgAAAEoAAABKAAAQx+mtpFGAABAAElEQVR4AezdCZgkRYEv8OiZYRguQVEQueTc5VI5lBV0YcGncu0CisKDVRHR1QURP3UVXVgQL56+p4DKtyCKgg93HuKK8JZbn6AsKsixoHKoIPcpwtzd+TJqrKuru6en64yoX33f0FVZmRkRv8gkvvh/mZUjRfkKXgQIECBAgAABAgQIECBAgAABAgQIEOiiwIggsou6dk2AAAECBAgQIECAAAECBAgQIECAQEVAEOlAIECAAAECBAgQIECAAAECBAgQIECg6wKCyK4TK4AAAQIECBAgQIAAAQIECBAgQIAAAUGkY4AAAQIECBAgQIAAAQIECBAgQIAAga4LCCK7TqwAAgQIECBAgAABAgQIECBAgAABAgQEkY4BAgQIECBAgAABAgQIECBAgAABAgS6LiCI7DqxAggQIECAAAECBAgQIECAAAECBAgQEEQ6BggQIECAAAECBAgQIECAAAECBAgQ6LqAILLrxAogQIAAAQIECBAgQIAAAQIECBAgQEAQ6RggQIAAAQIECBAgQIAAAQIECBAgQKDrAoLIrhMrgAABAgQIECBAgAABAgQIECBAgAABQaRjgAABAgQIECBAgAABAgQIECBAgACBrgsIIrtOrAACBAgQIECAAAECBAgQIECAAAECBASRjgECBAgQIECAAAECBAgQIECAAAECBLouIIjsOrECCBAgQIAAAQIECBAgQIAAAQIECBAQRDoGCBAgQIAAAQIECBAgQIAAAQIECBDouoAgsuvECiBAgAABAgQIECBAgAABAgQIECBAQBDpGCBAgAABAgQIECBAgAABAgQIECBAoOsCgsiuEyuAAAECBAgQIECAAAECBAgQIECAAAFBpGOAAAECBAgQIECAAAECBAgQIECAAIGuCwgiu06sAAIECBAgQIAAAQIECBAgQIAAAQIEBJGOAQIECBAgQIAAAQIECBAgQIAAAQIEui4giOw6sQIIECBAgAABAgQIECBAgAABAgQIEBBEOgYIECBAgAABAgQIECBAgAABAgQIEOi6gCCy68QKIECAAAECBAgQIECAAAECBAgQIEBAEOkYIECAAAECBAgQIECAAAECBAgQIECg6wKCyK4TK4AAAQIECBAgQIAAAQIECBAgQIAAAUGkY4AAAQIECBAgQIAAAQIECBAgQIAAga4LCCK7TqwAAgQIECBAgAABAgQIECBAgAABAgQEkY4BAgQIECBAgAABAgQIECBAgAABAgS6LiCI7DqxAggQIECAAAECBAgQIECAAAECBAgQEEQ6BggQIECAAAECBAgQIECAAAECBAgQ6LqAILLrxAogQIAAAQIECBAgQIAAAQIECBAgQEAQ6RggQIAAAQIECBAgQIAAAQIECBAgQKDrAoLIrhMrgAABAgQIECBAgAABAgQIECBAgAABQaRjgAABAgQIECBAgAABAgQIECBAgACBrgsIIrtOrAACBAgQIECAAAECBAgQIECAAAECBASRjgECBAgQIECAAAECBAgQ6LjAqaeeGh588MHKfl//+teHAw88sONl2CGBVAWOP3VJWLxkee0P/7s5YfedZ6XaFPUmsFICgsiV4rIyAQIECBAgQIAAAQIECExHYMsttwz33HNPZdVjjz02nH766dPZLNt1FixYEFZfffVs26dhKycwe6sFYWxs+TannzQ3HPu2OSu3A2sTSFRAEJlox6k2AQIECBAgQIAAAQIEBllAEFnvnWOOOSacffbZYbPNNgvz588PO+ywQ/1L74ZSQBA5lN2u0aWAINJhQIAAAQIECBAgQIAAAQIdFxBELif91a9+FbbZZpua71FHHRXOOeec2mdvhlNAEDmc/a7VgkjHAAECBAgQIECAAAECBAh0QUAQuRz14YcfDptssklYunRpZcFHP/rR8JnPfKYL4naZkoAgMqXeUtdOCrgispOa9kWAAAECBAgQIECAAAECFQFBZP1A+MY3vhG++MUvhh133DF89rOfDeuvv379S++GUkAQOZTdrtGlgCDSYUCAAAECBAgQIECAAAECHRcQRHac1A4zEhBEZtSZmrJSAoLIleKyMgECBAgQIECAAAECBAhMR0AQOR0l6wyrgCByWHteuwWRjgECBAgQIECAAAECBAgQmJHAddddFy688MJw6623Vv7FncTbj3faaadwxhln1H4X8dhjjw2nn376pGWMjo6GG2+8Mdx+++3htttuC0888UTYYIMNKk+XftnLXlbZ52QbP/DAA+H444+vfR1vfV533XUr5V999dXhpptuCnEfr3vd68IRRxwRtthii9q6F198cbjkkkvClVdeGZ5++ulKOQcffHA47rjjwsjISG296pvHH3+8st9bbrmlUs/4OT4Je9tttw0f/vCHJ61nLHfJkiWV3bz73e+u1KW6z1huXFZ9ffCDH6w83Cb6Rd/osvHGG4c3vvGNIdZt1113ra7a9Dfe+n3mmWdWbvv+1Kc+Ffbcc8+m71fmQ1GE8I2LloX/d+NYuPmOsXDvfWNhi01nhZ22mxX22WN2ePM+s2u7++OfinD0CcvbVl34sfeuEnbcdlb1Y8vfEz6/JNz9+7KQP79es8vs8P63z6l8evypIpxx3rJwy6/Gwm2/HguPP1mEzTaeFbbdciR8+N0T7/eBR4pw/Kn1Onz2I3PDuuuEcMY3l4WrfzIabrp9LLzsL2eF1+0+Oxxx4JywxSb1vr34itFwydWj4crrRsPTZVtivQ9+w+xw3DtWKY+Bag3rf3/z27Hwif+5/Pc+60tDWKWsfqxn3PeWpdUrXzYrzFu1cY3m99MJIlemH5r3Pv1Psf3R6JY7x8J/3TVWafNGL15e/yMOnB32eNXsCR1iCeVpG268dSzc/pvlffVE2XcbrDcSdviLWRXvyY6BXvbX9CWs2TOBwosAAQIECBAgQIAAAQIECKyEwIIFC4oPfOADxaxZs2KatMJ/ZRA56d5vvvnmYpdddplyH/vuu29x3333TbiPuH1jHcoAryjDxqZl1e9f/OIXF3fffXdRhoLF0UcfPeE6cd199tmnWLx4cVN5V111VVGGo5NuUwaXxcc//vGmbaofGp3KQLa6uPL3d7/7XdM+y0CzKK8mbVpWrf+cOXOK73//+03bxw/33ntvEcuvrlcGoy3rTHfBg4+MFa/7+4VF2Py5Sf+9/UOLi+cW1Pf4kc8ublr3Ja9eUNz/0Fh9hYZ3p565pGndtV/+XHHHXaOVNa66flmxwV8taPq+sR4jWzxXfPwLSxr2tvztzf812rTNGectLbb4m4n38+JdFxR3/36sWLK0KI4+obnejWXtc+SiYnFrUcU1P13WVFbjNo3vN33tguKCf19ajE3MUMzasu57elnf8a+Z9MP4fUz1+bEnx4o3vW/RCtvy+bMnQCh3HM13+bupj5N937mouO/BVoBe9tdUBr7rj4ArIsv/U3sRIECAAAECBAgQIECAwPQExsbGwmtf+9rwk5/8ZHoblGtNdkVkfHr0iSeeGJYtW7bCfa211lrh3HPPDW9+85ub1v3lL3856ZWITSv++UN8gvVGG220wvrHKxKPOeaY2i5mz54dYttX9CqDwnDAAQc0rda4bbwyNHpUX7///e/DS1/60urHFf6dN29eiFd67rbbbrV1L7300rD//vvXPs+dOzc89dRTYfXVV68tm86bJ58uwnZvXBQefixmmlO/3vDXs8N/fH35JX/xyr1DjlkcLvqP8hK5P7/iFYjX/duqYa016pcVxqvv3vS+xSGuH18labj0a6uGN7x2+RWWjVcJLl9j4v9+/19XDQfsXb8q85flVZs7HrBo4pUnWLrJS0bCRi8eCT+5aer+POOkueGYty2/UrO6m2tvGA17Hb64+nGFf1+zy6xw5TfntVwd2djW08tyjm0oZ6b9sMLK/HmFp/5YhB32XRQeeHjF/fy5f1olfKS8ErXx9ZmvLg0nfnFped42Lp34/VprhHDu51Ztuoq2l/01ca0s7aeAILKf+somQIAAAQIECBAgQIBAYgJf+tKXQnk1ZK3W5VV6lduS99tvv0rA94tf/CL88Ic/DOecc05YuHBhZb2Jgsjx4Vlccfvttw+vec1rwjrrrBPKq/xCeRViePLJJ2tlrbnmmiHeFr355pvXlk0URL7yla8Mn/70pyu3Mcdbt9/3vveFa6+9trZN9c173/vecOihh1ZuA//Od74TTjrppFrYWF49GcqrMMMqqywPYaq3asdwb++99w577bVXePbZZ8P8+fNrt6XH/ZZXb4bYtsbXygaRMZg89dRTK7dwx5D2tNNOa7q1/cADDwzxtvLqa+nSpZVbxGNb4+vtb397iE/qXtnXP560JHzl/Hq6tNerZ4WP/+MqYbONZoV77x8LJ5Xh0/W/qId3l39j1fD6P4eIC8sccI/DFoWflbfqVl8xrPzBOauGOWVmGG/93f0ti8JzC6rfhjA+gBvZYvmXq68Wwt67zQ6x/GfLRfMvGw23lrdqV1/77jm7EmBWP08UbMVboz/9oVXCrq+YVQnc3nfiknDtDfV9VLd97+FzwqH7zy5vKZ4VvnPpskobq3nzi180Eu67brXKbdfV9ccHkfE29U03HAnPPBvKf0W48Zax8Nv7mwO+eNv5l06cW91F5e9UQWQ7/dBUyCQf3vvPS8JZ3673cwyE337wnPDqHWeF8nSu3BL/vy8ZDQ89WoTxQeSl146G/d/VHMRuv/VIiLfXr/O8UB4nRbjq+tHw5NP1wtcsw8hbLl0tbL7x8lC6l/1Vr4V3AyPQnwsxlUqAAAECBAgQIECAAAECqQk89NBDxRprrBFTlsq/1VZbrfjpT386YTMab48ef2v2I488Uqy33nq1/ZRX8BVf+MIXivK3Ipv29eijjxZvectbauvFcsurMZvWG39rdvk7ikW8dbzx9dhjjxVloNi0n/POO69xlcr7WM9q2+Lfu+66q7ZO/Lz11lsXd955Z21ZfFMGhcULX/jC2nblFZdN38cPK3Nrdrwte6Lb0MtwtVbG2muv3VLGM888U5x99tnFZZdd1uTTsuIkC27/zWgxe6v67cJ/++5FLWuWTS12/tv67bjxfeProUfHik1e03xL9Ls/vrh45PHW5f/wieZb3+N+4q3NW++9oLjz7ubjIJb7wl3qdYtlNL7G3+p78HsXFQuaq1bEW5FX+Yv6PmJZ53239ZboY09uvl37rt8131o8/tbs63/RXNdYr7jfRst4S/nVPykb0fCa7NbsTvRDQzEtb39+22jTbeHR9cc/a23DwrL74y3jl/2wXu/Yj+u9sm44t/T8wjlLyuOtuZhHnxgr3nJs823fr33rwtp6veyv5pr5NAgC5SXRXgQIECBAgAABAgQIECBAYMUCF110US0Mi8FceQXhpBtNFUTG30lsDPw++clPTrqf8nboorz6sGn9H/3oR7X1xweR119/fe27xjd77LFHbR8x7JvoVT7YprZOrF/5EJvaakceeWRRPlim9rnxTfmwmdp2MZQc/1qZIPKb3/zm+M0rn8uH8NTKiHVbtKg1KJxww2ku/NI3ltZ+LzAGZw883BzAVXfzvSvrv5EYw7RF4/LE2349WjzvZfWwKgZ+4z/vfcTCYmk936ruujjyI4uLp5+ZuNwYaFZ/gzGGZ42v8cHWROFgXH+Pw+oh6pblb0hO9Lpp3O9NXnldc0WnE0TG/c6/rO4U6/2esv6Nr8mCyE71Q2NZje9PPr35NzonCmMb1298H4PJah/Ev58sf+9zslf8bcy9Dq97x/V/9J/LLXvZX5PVz/L+Cbg1u/w/uBcBAgQIECBAgAABAgQIrFjglFNOqdy+XF3zj3/8Y3je88r7MSd4lWFfuOeeeyrfjL81Oz5F+oILLqh8F3+vMd6GXb0FeoJdVb5vfNp1vD38/e9/f2XV8bdml0Fk0+8nVvd32GGHVZ7wHT/HupVXO1a/qv2Nv6v4ghe8oPY5/iZlGUDWPk/05mc/+1k4+eSTa7djl1d6hvKKz6ZVV+bW7G9961uVp3s37aD8EJe/7W1vqy0ur04N8fbxTr3irctfvaB+u+7430aslvPI40XlVunq5zsunxe22bL5CdmX/3g07HfU4spTlavrVf9uvdlIuOGieeH5a9d/O7L63WR/4+3eJ5++NMTbguNrvXVDeOTG+u9fjr/V9/r588JuOzXXKW532HGLw4U/WL6PLTcdCXddU94DPu4Vfz/xBTst/0mB+NW5n5sbjnxz/Xcix9+aPVlZcdvN91xYu017953jb2bOi4srr8luze5kP1TLavzbaLB5+YTve65tNWhcv/H9ER9cHC749+V+8Tc27/1R823rjevG9/E27S1Kg+or3p4eb1PvZX9Vy/Z3gAT6l4EqmQABAgQIECBAgAABAgRSEnjrW99auypvww03nLLqU10RGa9ILKfFlX8HHXTQlPupfvmSl7ykts073/nO6uJiuldElr8HWdt+sisi423W1XrFv2eddVatnMY3v/nNb4oTTjhhwqdzl79v2bhq5f3KXBFZBo4t28cFl1xySVPd4tO2O/kaf/Va45VvU73//lXNVwxW6/SV85uvnov7iFdG/vrecffxVjcY9/c3vx0rTvj8kgmffr3OK2Z2ReR7/7l+VeVkV0TG28Ab23vWt5tv357uFZGxOfHp4tV9xaeDN74muyKy0/3QWGZ8//L96lcpHvielbuqNppV23PQP0xv2/gE9eo27/yn5VeFTveKyE701/j2+9x/AVdEDlAorCoECBAgQIAAAQIECBAYZIHGKxl32GGHpoe0jK934xWR8erFeBVj9bX++uuH8vcfKx/f9a53hfK3DatfTfr35S9/ea28+KCY+OTo+JruFZHxqswzzzyzss1kV0SWv1FZPqyjfvVbGUSG97znPZVt4n/iw2Di1Y/xSsm4bnyVv5kZ4hO9H3744crn+KCdeGVl46sTV0SOf7hPGUSGTTfdtLGYtt7vdsii8NM/P0U6PizmkH3qDlPtOF45ucsOrVcffu/K0XDQPzQ/1OQF64Rw8yWrhfjU6sleDzxSVK5+PHf+stoVlWuUFz/Gp29Xn+YdH4ry1M0rf0XksScvCWd+c/lVn5NdERm7dc7W9SfqnHXq3PCew+oWK3NF5D//r6Xh1DOXVpoaHwiz6M7VKw/uiQsmuyKy0/0w3vmlf70w/P6BmGmXV4geMDt8+4vLn3w+fr2JPq//qgXh0SeWf/Out84JZ3+6+QE8E23z8v0W1R40FB8+dPX586Z9RWQn+muiOlnWZ4H+Z6FqQIAAAQIECBAgQIAAAQIpCMTfciynsJV/5S3ZU1Z5qisi99xzz9p+dt999yn3E7+MVyrOmzevts073vGO2jbTvSLymGOOqW0/kysif/7znxexzdX2l7eUF2W4WsSHxMS/1eXduiLyBz/4Qa2MWFanr4h80/vqDxfZaLeJfz+xhr6CN7+8Y7RYY/vm34msXhW33RsWTPo7kPFBKo2/JxnrEX8z8Zlnxyp/q/uY6RWRx/xL/QrFXlwR+db3103jQ3gaX5NdEdnJfmgsr/r+v72tfkXkjgeMe6JPdaVJ/u753+vb7n7IireNV5fO26Z+HLzjwyt3RWQn+muSpljcRwEPq+kjvqIJECBAgAABAgQIECCQksD8+fObwrDJHgwT2zRVEPmBD3ygtp/4NOtbbrllSoavf/3rtfVjCHfOOefU1u9FEBmf5r3ddtvV6vCqV72qKH8fs1aHHILIj55WD+li4HftDWWKNIPXRE/Ijg+/qYaI8W98WM2S5jueK09UjiFldb1XHbSw+OOf6g+uaXyISwpB5BNPjRXr7lxvd3ySd+NrsiCyU/3QWFbj+w98st7P8cneN94yvVvl4z4at41PIL/lzqm3/fr/ab49/5zvLO/06d6aLYhs7Ll83gsi8+lLLSFAgAABAgQIECBAgEBXBe6///5i1VVXrQVyu+66a7Fw4cRXRk0VRH73u9+t7SMGi694xSuKJ554YsK633HHHUW8yrB6xWH8Wz5oprZuL4LIWIfG8s8///xa+fHNoASR5a3jRXzK+Exe8SrGaggY/2762gXFw49Nvq8bbh4t/vbdi5qublxcPkQ5XinXuJ9937mo+N0fxooNy6sbG5fH309sfN1xV3P553+vOalMLYg86qP1wC+2+7R/bX7C9GRBZCf6IbrGp5lPdCh887vN4WAMfx8vQ9PpvL57efOTwF+x/8IiBq4TvWJ/xsC4sc/v+t3ydQWRE4kNzzJB5PD0tZYSIECAAAECBAgQIECgbYETTzyxKZTbdtttiyuvvLIofxexcgt1tYCpgsi4zv7779+0n/Jp08XXvva14u67766Em7fddlsRbwVvvCU7hoHHHXdctYjK314EkVdddVVTXU877bSmOjTe9l29NXvx4nrQ1omH1Ux1a3b5BO1i5513rtRxq622Km666aam+k33wxuPrN9KHAOk5+/4XHHGeUuLGCo9/cxY8YvbR4sYEMaHnFQDpngFZPUVb72tLo9/t3n9gtpVjTFgW2uH5mDqX75UD+euur455Bof3DVeHVe9IjIGn/HVy2Br/MNqTvrikuLu39cNHnp0rMknOsTbwBc2XxBZTBZExva00w/xStP4IJm55RWL8XbwWN/G19LyY7wlu7GfXrjLc8VXL1ha3Hn3aOVK1QcfGSt+cM2y4vDjFxXjr+Tc/131vo/7WO+VzxVf+7elFYPYxtt+PVp88swlTbdkx/WOO6V+PvSyvxrb7v1gCHhYTTmSeREgQIAAAQIECBAgQIDA9AQWLVoU4oNqysBwwg3ig1lGRkZC+buOte/jg2JOP/302uf45pFHHqns57HHHmtaPtWHHXfcMdxwww1h7tz6QzJ68bCa+JCa8jcha1WLD6Q5+uijwzbbbBMuvvjiUD7RuvZdfBMfcBOXXXHFFaG8pTt0+2E1n/rUp8InPvGJWh0OO+yw8O1vf7v2ebpv/lTmhH996OLKw0Smu80jN64W1lt3JHzhnKXhQ59Z/mCWuG18MM2NF68Wttik/mCaK348GvZ71+Ly2Kjv/bzPzw1vO2hOiA+p2Wi3hbUv4gNpjj50Tthmi1nh4itGwyVXL384UHWF+ACZS64ZDVect2pYWha74wGLql+F6+fPC7vt1PoAnU48/GT8w2qqhW6w3khYpXymzX0Pxjy4+XX1+auGvV5dPq2m4TXZw2riKu30w/zLRsNbjq0/JGj3nWeF6/5tXkPJIdz0X2PhVQctqj0MqOnLcR/ig4h+9r369o88XoQd9lkYHnty3IpTfNxxu1nhhovmhbmrLF/pl3eM9ay/pqiWr/olMBh5qFoQIECAAAECBAgQIECAQCoCjz/+eHHIIYc0XSVYzmkn/VwGkRM27c477yziw2qm2rb63eGHH16U4WXLfnpxRWQs9OCDD55WPav1jX9vvfXWSn27fUXkxz72saa67bfffi1O010Qr4aLt2U3XjE32fv4O45laFZceu2ypiv85mz9XHH1T5qvxKuWf+785luD428NVteNV99NVtZky2/91Whfr4icrF5xebzScP5lEztMdUVktJpJP8Ttzvp2s+9WezU/JCeuE1/fv2pZy+3yE7Vll79r/emFeOXk+FvwJ9o2LotXVTZeNRvLdkVkVBjel1uzh7fvtZwAAQIECBAgQIAAAQJtCcTfejzqqKOK+PCWNdZYoykMawzkPvjBD05aTvxNwy9/+ctFebVjy23Yz3/+84s99tijiLdGT/a6/fbbm8q98cYbJ1z1+OOPr61XXsk44TrxoTRz5syprRdvFa++nnzyyeLQQw+tfRfbF2/D/tCHPlTcc889xSabbFL7bs011yxOOeWUorx6tLJ54+9qfvWrX63usvL3D3/4Q227uM8LL7yw6fvqh8svv7xpvbhd9fXb3/622HDDDSvfxzpdc8011a9m9Pe+B8cqt9I2PsG6GjTF26Jf9/cLiyt+vDxge+qPY01Puo7rfeX85t93HF+JeDtzdX/xb9xnvPX7yafHikMbnjRd/e5Dn1lc3HPfWLHJa+oB6Zrlbd6nnLGk8luIt/+m+fclJ3sAy/Gn1m8dj7eNT/QqD4EiBqnV+sXbjhtf42/N3myPBS3tj7+HGQO4qX5jc9W/rJcRb4ue6LUy/VDdPj7gJ94KHusfn1gdg9/JXnHdY09eXGxRrt8YjMZt4+ddD15YuTV/ou3j709++VtLK7d5Nz4ZO24bb+nf47CFRbzdfqJXL/trovIt66+AW7PL/9N7ESBAgAABAgQIECBAgED/BcogMJQPogmPPvpoKH/rMGywwQb9r9S4Gjz99NOhDAHD2muvHTbeeOPat2WgGsqrM0P8u/3224fVVlut9l0v3kS7MoQN5YN/OlZ2UUabjz5RhMefKsp2hbDJS0bC2mvVb7XuVruefqYIf3i4qJS18Qb18mIdbi5v641/t996Vlitfsdwt6rSst/xt2bH28BfveOsUD6IJTzyeAjbbjUS1l2nXueWHcxgwcr2Q1z/Z7eOha03GwnrPG96dVlY3tn+63vHwjPPFmH9F46EDV88K6y5+vQqWx56lfbHY2Wrl84K8TZ1LwKTCQgiJ5OxnAABAgQIECBAgAABAgQIECDQIDBREDnR71E2bOItAQINAoLIBgxvCRAgQIAAAQIECBAgQIDAsAmMbLFg2JqsvUMiUNwzzcs6h8RjEJopiByEXlAHAgQIECBAgAABAgQIECDQJwFBZJ/gFdt1AUFk14lXugBB5EqT2YAAAQIECBAgQIAAAQIECOQjIIjMpy+1pFlAENnsMQifBJGD0AvqQIAAAQIECBAgQIAAAQIECAy8gN+IHPguUsEBFxBEDngHqR4BAgQIECBAgAABAgQIECAwGAKCyMHoB7VIV0AQmW7fqTkBAgQIECBAgAABAgQIECDQQ4FbfzUWjj5hSa3E8/7H3PCXW8yqffaGAIGpBQSRU/v4lgABAgQIECBAgAABAgQIECBAgACBDggIIjuAaBcECBAgQIAAAQIECBAgQIAAAQIECEwtIIic2se3BAgQIECAAAECBAgQIECAAAECBAh0QEAQ2QFEuyBAgAABAgQIECBAgAABAgQIECBAYGoBQeTUPr4lQIAAAQIECBAgQIAAAQIECBAgQKADAoLIDiDaBQECBAgQIECAAAECBAgQIECAAAECUwsIIqf28S0BAgQIECBAgAABAgQIECBAgAABAh0QEER2ANEuCBAgQIAAAQIECBAgQIAAAQIECBCYWkAQObWPbwkQIECAAAECBAgQIECAAAECBAgQ6ICAILIDiHZBgAABAgQIECBAgAABAgQIECBAgMDUAoLIqX18S4AAAQIECBAgQIAAAQIECBAgQIBABwQEkR1AtAsCBAgQIECAAAECBAgQIECAAAECBKYWEERO7eNbAgQIECBAgAABAgQIECBAgAABAgQ6ICCI7ACiXRAgQIAAAQIECBAgQIAAAQIECBAgMLWAIHJqH98SIECAAAECBAgQIECAAAECBAgQINABAUFkBxDtggABAgQIECBAgAABAgQIECBAgACBqQUEkVP7+JYAAQIECBAgQIAAAQIECBAgQIAA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kAAJFJiA6+8dCpEFfiBYHAmQAAmQAAmQAAmQAAmQQMMh4PqAsOHcKbaUBEiABMqDgOvvHQqR5fEcshUkQAIkQAIkQAIkQAIkQAL1QMD1AWE9IOMlSYAESIAE8iDg+nuHQmQeN59ZSYAESIAESIAESIAESIAEGjYB1weEDfvusfUkQAIk4B4B1987FCLde+ZYYxIgARIgARIgARIgARIggRIh4PqAsEQwshokQAIkQAIJCbj+3qEQmfBGMxkJkAAJkAAJkAAJkAAJkAAJhAm4PiAMt4fHJEACJEACpU3A9fcOhcjSfr5YOxIgARIgARIgARIgARIggRIm4PqAsITRsmokQAIkQAIRBFx/71CIjLipjCIBEiABEiABEiABEiABEiCBJARcHxAmaSPTkAAJkAAJlA4B1987FCJL51liTUigwRGYO3euPP7445Ht3n777aVbt26R5xhJAiRAAiRAAiRAAqVCwPUBYalwZD1IgARIgASSEXD9vUMhMtl9ZioSKCqBJUuWyKOPPip9+vSRNm3aFPVapVT4a6+9Jn379o2s0g033CAnnHBC5DlGkgAJkAAJkAAJkECpEHB9QFgqHFkPEiABEiCBZARcf+9QiEx2n5mKBIpGACLkoYceKvfcc4+8+OKLstNOOxXtWqVWMIXIUrsjrA8JkAAJkAAJkEC2BFwfEGbbXqYnARIgARKoXwKuv3coRNbv88OrN3ACnufJEUccISNGjNAkKETWPhC0iKxlwT0SIAESIAESIIHSJeD6gLB0ybJmJEACJEACUQRcf+9QiIy6q4wjgTogABHy6KOPlttvv92/GoVIH4VQiKxlwT0SIAESIAESIIHSJeD6gLB0ybJmJEACJEACUQRcf+9QiIy6q4wjgTogcPzxx8vNN98cuBKFyFocFCJrWXCPBEiABEiABEigdAm4PiAsXbKsGQmQAAmQQBQB1987FCKj7mqJx8GS7r333pNPPvlE5syZIz/99JM0adJElltuOVlllVVkm222ke7du2dsxXfffSdffPGFTJkyRaZOnSrNmjXTXoqRF96KW7VqFVvGL7/8Iu+++25KmkaNGsmOO+4olZWVgvUPcY3x48fLhAkTBH8wnTp1kgEDBshaa62Vkhdte+ONN2TcuHEye/ZsXUbHjh2ld+/estFGG6WkR8S8efNkzJgxKedwfay3+Ndff2lW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RA77CVE+AQIECBAgQIAAAQJjK1D3F8KxbRgVI0CAwJgK1P13RyByTB9M1SJAgAABAgQIECBAYPgCvV4Ih39lVyBAgAABAg8JNBqNhw5G+JNA5Ag3jlsjQIAAAQIECBAgQGC0BQQiR7t93B0BAgQmRUAgclJaWj0JECBAgAABAgQIEJhYAYHIiW16FSdAgMBICQhEjlRzuBkCBAgQIECAAAECBAjMvoBA5OybKpEAAQIEpi4gEDl1M2cQIECAAAECBAgQIECgVgICkbVqLjdLgACBsRUQiBzbplUxAgQIECBAgAABAgQI/L+AQKQngQABAgRGQUAgchRawT0QIECAAAECBAgQIECAAAECBAgQIDASAlbNHolmcBMECBAgQIAAAQIECBAgQIAAAQIExltAIHK821ftCBAgQIAAAQIECBAgQIAAAQIECIyEgEDkSDSDmyBAgAABAgQIECBAgAABAgQIECAw3gICkePdvmpHgAABAgQIECBAgAABAgQIECBAYCQEBCJHohncBAECBAgQIECAAAECBAgQIECAAIHxFhCIHO/2VTsCBAgQIECAAAECBAgQIECAAAECIyEgEDkSzeAmCBAgQIAAAQIECBAgQIAAAQIECIy3gEDkeLev2hEgQIAAAQIECBAgQIAAAQIECBAYCQGByJFoBjdBgAABAgQIECBAgAABAgQIECBAYLwFBCLHu33VjgABAgQIECBAgAABAgQIECBAgMBICAhEjkQzuAkCBAgQIECAAAECBAgQIECAAAEC4y0gEDne7at2BAgQIECAAAECBAgQIECAAAECBEZCQCByJJrBTRAgQIAAAQIECBAgQIAAAQIECBAYbwGByPFuX7UjQIAAAQIECBAgQIAAAQIECBAgMBICApEj0QxuggABAgQIECBAgAABAgQIECBAgMB4CwhEjnf7qh0BAgQIECBAgAABAgQIECBAgACBkRAQiByJZnATBAgQIECAAAECBAgQIECAAAECBMZbQCByvNtX7QgQIECAAAECBAgQIECAAAECBAiMhIBA5Eg0g5sgQIAAAQIECBAgQIAAAQIECBAgMN4CApHj3b5qR4AAAQIECBAgQIAAAQIECBAgQGAkBAQiR6IZ3AQBAgQIECBAgAABAgQIECBAgACB8RYQiBzv9lU7AgQIECBAgAABAgQIECBAYMIFli1bls4///x02WWXpRtvvDHdeuutaa211krz589PixYtSgsXLkwPf/jDJ1xJ9f8XAgKR/wtl1yBAgAABAgQIECBAgAABAgRGQuDBBx9MZ511Vtpll13SuuuuOxL3NKybiIDjBz7wgXTKKaekCEb22jbbbLP03e9+Nz3+8Y/vlUU6gVkREIicFUaFECBAgAABAgQIECBAgAABAqMuEEHI/fffP51++unp3HPPTc95znNG/ZandX+NRiOdfPLJafHixemuu+4aqIwIyp5zzjlpu+22Gyi/TASmIyAQOR015xAgQIAAAQIECBAgQIAAAQK1Eojg3AEHHJBOPfXU4r7HORD5j3/8I6255ppTbp+5c+cWQ7if9rSnTflcJxAYREAgchAleQgQIECAAAECBAgQIECAAIHaCkQQ8uCDDy6GKJeVEIgsJdr3z33uc4ueke2pjgjMjoBA5Ow4KoUAAQIECBAgQIAAAQIECBAYUYE3vvGN6aSTTmq7u0kMRK622mrpvvvuSw888ECbRevBwx72sLR06dK03nrrtSb7TGBWBAQiZ4VRIQQIECBAgAABAgQIECAwjgLRk+7iiy9OV1xxRRGcue2229Iqq6yS1lhjjbTxxhunnXbaKT3hCU9YbtX/+te/pt/97nfpmmuuSX/4wx/SqquumrbYYovi3NjHCsb9tjvvvDNddNFFXVlipePddtstrbTSSinmP4xrLFmyJP3yl79MEVDaaKON0h577FG5CEnU7cILLyxWUr7pppuKMjbccMNiBeVtttmm61qRcPvtt6dLLrmk67u4fsy3+O9//7uwuvLKK9PVV19d1POxj31scQ9xL1XbddddV7h0fhcmO+64Y2dyuuGGG1KU37mtvvrqaeedd+5MTm9605vSiSee2JV+7LHHpqc+9alt6XPmzClWkW5L7Dj4xS9+UVz/lltuSfH3iEc8onCOuRV32GGHwr3jlOJweXbRXtEm3/ve99Kll16a/v73vxfPR7TvpptuWlVkz7TWodnz5s1LRx11VNp1113TtttuWwQi3/nOd6aPfOQjPc//2c9+lgzP7snji5kI5IfcRoAAAQIECBAgQIAAAQIECLQI5IBa493vfndjgw02aOR37r5/m2++eSMHjlrOfujjmWee2cgBuL7nR/k5iNXIAb6HTuz4lFc07llGXhm5ccEFF/S91xe/+MWNHMxslvqTn/yksckmm/QsMw/Pbdx7773N/OWHb3zjGz3P+cIXvtBYf/31K7/PAdPGC17wgsaNN95YFtXcv/Wtb608J6/g3MzT+uGDH/xgZf682EprtuLzkUceWZm3V5vGfVZt5fOQA4J9y5s/f37j05/+dFURjX52//znPwubhQsXdpW/8sorNw4//PDKMnsl5gVqinIWLFjQyIHeymx77bVX17VKl29+85uV50gkMFOBiLbbCBAgQIAAAQIECBAgQIAAgf8K5F6LjQgulkGZQfadgZvcM7GRe6BNqYzcI66RF1Np5J5zXW3RLxB52GGHNXKPxOVeK4KdeUhu4zOf+Uwj9/xbbv5999236z76BdMGcVpnnXUaP/3pT9vKHVYg8phjjlluHTvvuSoQmXuXNrbccssplRWB3Ahetm797P7yl780cs/antd4ylOe0lrUcj/HtXNP0MayZct65o1ntrP+5XG/oHjPAn1BYAABQ7PzvzIbAQIECBAgQIAAAQIECBAIgdxjrxiuG0Opp7LloE560YteVJySe6OlrbbaqihrKmWUeRctWpTOO++88rDYn3POOcXw5rbEaRw86UlPSlddddXAZ55wwgnpiCOOaOaPeubelc3j6Xx41KMelS6//PKUe5sWpx999NHpwx/+cFdRuUdkMdS884sPfehDKQcZO5NT7hGZ/va3vxXp733ve9O73vWurjzLS4ih7v/5z3+a2f785z8Xw5ljWPVUt1e+8pXp9NNPb57Wzy6Gz+dgczNv54eY3/KQQw7pTJ7R8fnnn18M668qJKYCmM6q21VlSSPQKiAQ2arhMwECBAgQIECAAAECBAhMtMCBBx6Yco/BKRu0BiJf+9rXplNPPXXKZbSeEPeQe0c2k2YrENkscMAPnUHRfsG0AYsssr3iFa9IX/7yl4vPwwhEPvnJTy7mqpzKPUXe1kBk7txVBKVjTsiqLebEfOITn5h++9vfFvM6VuX51re+lfIQ6OKr6drFvJU333wHvpSNAAAP60lEQVRzWnvttasuMe20T3ziE+nQQw/tOj8PLy/m4ez6QgKBWRAQiJwFREUQIECAAAECBAgQIECAQP0Fovfb4x73uHT//fdXViYWE3nGM56R8rDtdMcddxS99WJBltjKQGSeqzE9+9nPrjw/EqM34fOf//yUh8ymz33uc8XCMlWZozfatddeW/Tyi+8HCURGYCwWTInFdX74wx9WFduWFgGn6MUZC9zEAilVW/RejCBYufULpuW5DNN+++2Xtt9+++Kc0047LYVp1RYLvMQCOXmodhpGIDIWF4pefdGzNYKeVdvxxx/ftRhOLEQUC87E1q8tI4jaWm70WIyVuTu3WGimtO1n13le63G0UZw729s+++yTvv71r3cVGwvZvOc97+lKl0BgVgQGGL4tCwECBAgQIECAAAECBAgQGHuBN7/5zT3nzMsrPzcuu+yyLoMc6Gp88YtfbOSVnIvv3vKWt/QsI+bsa93uueeeRg5s9sz/7W9/u5m93xyROTjQOOWUU5p589DiRl7xuGe5kT8PXW5EvnKLhWQiveovD3cus/VdcCWvtNzMFx+uv/76vgvofP7zny/yD2uOyCg85l6sqlOknXvuucX1e/0nD62uPDesOre8YnnlPJIx72cO5BbZ+80RWd5jDoQ2tt5668Z6663XvPbZZ5/debkZH0fbVM0rmgPEzfud8UUUQKBCwGI1FSiSCBAgQIAAAQIECBAgQGDyBJ71rGc1gz9lYCj2EUyqCkJWCcUiJa3nlp8f+chHVi5Ck+fpq8wf5+Uee81L9AtExqIsndvixYt7lpt7LXZmb+QhxD3z//znP2/m7xdMi5WfO7ePf/zjPcvNczgW2Uc1EBkBwbL9WvfRxrlHZNdfHqZdmT9WKI+tn12UH4vV5B62Rd74Tywq9JjHPKZx3333NdNm68OrX/3qynvNPSFn6xLKIVApYGh2/tduI0CAAAECBAgQIECAAAECMQx56dKlXRCbbbZZMUy664uKhBjuHAvedG4xZ2FefbkzOd19991p7ty5XemR8LKXvSydccYZxXf9hmbfeuutKfegaysj5ibce++929LKg7wqeNpiiy3Kw2Ifi8dsu+22bWnlQe7pmHIPy+Kw3/DiHIjsqksME99xxx3Lotr2MZfmZz/72aEMzS4vFG0RbVK15R6RKYaz99rmzZtXDO/u9f2g6WeeeWZ66UtfWgyv7rXQz6qrrloM0485J4e95Z626YUvfGHXZWIho3gOYk5KG4FhCQhEDktWuQQIECBAgAABAgQIECBQK4GYH/CBBx7ouucFCxakX/3qV13pVQkxT2Lrqstlnp133rnnvI0x92TVtvvuuzdXUp5qIPKSSy5JT3/606uKTVWByN///vddwcny5JkEImOOxg033LAsqm3/ute9LuUh5T0DkTFfZ9xX5zbIqtnlOTMJRPZqy7LsQfcnnnhiOuyww/oGIg866KB08sknD1rktPPFnJ0xh2e5unhZUO6xmy699NJitfcyzZ7AMAQEIoehqkwCBAgQIECAAAECBAgQqJ1A9BKsCnzFSsoRuBlk1eKNNtqoWISls/K9gmrRm3H99dfvzF4cz6RH5KgEIiOAu80221TW79hjj015rsqegcgIjkUvyzyXYdv5b3/729P73//+trQ4WHfddbsCbP0Ckd/5znfSnnvu2VVOmbDxxhunPMdkedi27xU8bsv034NYnfqQQw7pG4j8zW9+k6JH4jC3f/3rX0Xv1F//+tddl4lV3vfff/+udAkEZl2gcsC2RAIECBAgQIAAAQIECBAgMGECeTXrynnz8ot4IwfNBtLot0hMDsp1lfGpT32q5zVj4Zty6zdHZA5mltma+1g4Ju676i/3iGzmKz/klbMr88b5rYvQ9JvnsGqOyJgHsuoeIi0W+Yntfe97X888V111VXmLxT732mvkYcyV+XMgsi1vHPRbrCavWt6VvzUhDymvvM4GG2wwrXkbp2rXei8z/RwLE/VakOhVr3rVTIt3PoGBBfSIzP/3sxEgQIAAAQIECBAgQIAAgRga+/rXv74nxMEHH5zywiopr6BdDL/+4x//mL7//e+n8847r5hD8eijj0458Fb08qsqJIZKRy+8ddZZp/g6esHFHIUxfLlqywvZpF133bX4qg5Ds3/84x+nnXbaqVmVK6+8sji+6667mmmtH/ICQMW8lHn17PSa17ym9avm57zSeProRz9aDJkPjwMOOKCnV1WPyGXLlhXzVuYoSbPM8sOWW25ZDH3fZJNNirkgY17NvLhOiiHj8RzkxYLSO97xjjJ72z4v9pKiF2G/npFXXHFF0d5lGVOdX7PtgjM8OOKII9LHPvaxylIOPPDAtPrqq3d9Fz2BwyCvpN31nQQC0xUQiJyunPMIECBAgAABAgQIECBAYKwE8urEKRamqVpsprWia621VrHIzP33399MjqG3J510UvrTn/6UNt1001QV+IrMMQy7XBTmwgsvTBEoq9oiOBaBzjLQVYdAZNRjt912K4KnYRgBxhhaXbXtsMMO6aKLLiq++sEPftAMuFblzStHF9633XZb1dfNtKpAZHwZc1T2CvbG9zH0u3Vezwh8RgA06hDXfvDBByNb1/bMZz6zCDxHXSJYd/PNN6frrrsuxZyaX/rSl1IEYmOL86MdV1QgMoaGH3rooV33P0jC7bffPtCUBIOUJQ+BEBCI9BwQIECAAAECBAgQIECAAIH/Cnzyk59Mb3jDG6bsUQYi48QjjzwynXDCCVMuo/WE6J231157NZPqEohs3vByPkTwcZdddily3XvvvSlWLL/zzjuXc1b/r3sFIhctWlT0XO1/9kPfloHISInejNErsN8WQcZegec4b0UGIs8+++wUK3X3Cqb2q1d8JxC5PCHfT1VAIHKqYvITIECAAAECBAgQIECAwNgKRM+4WCTmrLPOmlIdWwORsfJ2DKn+0Y9+NKUyysxve9vbuoJf4xSIfMlLXpK+9rWvldUt9jHkOs/Z2JY21YNegcjoebpw4cKBi2sNRMbzsMceexTD7wcuoCPjigpEXnDBBel5z3teuueeezruaPBDgcjBreQcUGDg2SRlJECAAAECBAgQIECAAAECEyCQh2g38px6jTxkt3Kxkvy63ZWeA5FtMrmXX+Ooo45q5N5yXXmrzo+0NdZYo3Haaae1lVMe1GGxml71KtPDIvcwbMTCKZ3bDTfc0MjDoJdrlXuJNo455pjKfDkQ2Vls8/iggw6qPKe8t9Z9DkQ2z4sPeQh+I6/U3chzJg5cRpQXz08OBDZyILIo73+5WM3FF1/cyPM+Tul+Ww3KzzkQ2WbhgMBMBfSIzP+6bAQIECBAgAABAgQIECBAoFMgr3KdYgGbGCadV6bu/Lo4jvkgd99992KBkwULFnTliTJycDF99atfLeYQ7MqQE7baaqu07777pv322y89+tGPrspSDC2OIcadWwwLjl5r8+bNa/tqyZIlabvttmtLKw9iHsO479bt+uuv70orvy8XlYnjfvMcHnfccSmvAp5uuumm8tRiH8Out99++8Ior0ze9l3rwbXXXpvySuEpFqW5++67m1/lVbJT2L785S9Phx9+eDHsPYa/d255Neu+c0HGMOXFixenvEJ411Dq8Iuh4vvss0/ac88902qrrdZZfIrFhaItzzjjjK46lplXWWWVtPXWW6e99947xYI2MT9lucVCRXnl6vKwuY9FYWIuzaprNjNN8UNe8TvlYOQUz2rPHs/WHXfckdZcc832LxwRmIGAQOQM8JxKgAABAgQIECBAgAABAuMvEMNzI7i2dOnSFAumRGBs7bXXTvPnzx94IY/ci6g4NxY0ueWWW1IErCJwFn91CvT0C0RGMC1WX77mmmuKoGss5hNB1tZg3CBPSwwlvvzyy4s5IyMwG2WsvPLKg5w6UJ4Icl599dVFe4Z/BGVjAaJBt2jLCP7GAjjRlrHl3qxFO26++eZpzpw5gxYlH4GJExCInLgmV2ECBAgQIECAAAECBAgQIDA9geUFIufOnTu9gp1FgMBECAhETkQzqyQBAgQIECBAgAABAgQIEJi5gEDkzA2VQGCSBQQiJ7n11Z0AAQIECBAgQIAAAQIECExBQCByCliyEiDQJSAQ2UUigQABAgQIECBAgAABAgQIEKgSEIisUpFGgMCgAgKRg0rJR4AAAQIECBAgQIAAAQIEJlxAIHLCHwDVJzBDAYHIGQI6nQABAgQIECBAgAABAgQITIqAQOSktLR6EhiOgEDkcFyVSoAAAQIECBAgQIAAAQIExk5gyZIl6bjjjuuq10orrZS+8pWvpDlz5nR9J4EAAQKlgEBkKWFPgAABAgQIECBAgAABAgQIECBAgMDQBAQih0arYAIECBAgQIAAAQIECBAgQIAAAQIESgGByFLCngABAgQIECBAgAABAgQIECBAgACBoQkIRA6NVsEECBAgQIAAAQIECBAgQIAAAQIECJQCApGlhD0BAgQIECBAgAABAgQIECBAgAABAkMTEIgcGq2CCRAgQIAAAQIECBAgQIAAAQIECBAoBQQiSwl7AgQIECBAgAABAgQIECBAgAABAgSGJiAQOTRaBRMgQIAAAQIECBAgQIAAAQIECBAgUAoIRJYS9gQIECBAgAABAgQIECBAgAABAgQIDE1AIHJotAomQIAAAQIECBAgQIAAAQIECBAgQKAUEIgsJewJECBAgAABAgQIECBAgAABAgQIEBiagEDk0GgVTIAAAQIECBAgQIAAAQIECBAgQIBAKSAQWUrYEyBAgAABAgQIECBAgAABAgQIECAwNAGByKHRKpgAAQIECBAgQIAAAQIECBAgQIAAgVJAILKUsCdAgAABAgQIECBAgAABAgQIECBAYGgCApFDo1UwAQIECBAgQIAAAQIECBAgQIAAAQKlgEBkKWFPgAABAgQIECBAgAABAgQIECBAgMDQBAQih0arYAIECBAgQIAAAQIECBAgQIAAAQIESgGByFLCngABAgQIECBAgAABAgQIECBAgACBoQkIRA6NVsEECBAgQIAAAQIECBAgQIAAAQIECJQCApGlhD0BAgQIECBAgAABAgQIECBAgAABAkMTEIgcGq2CCRAgQIAAAQIECBAgQIAAAQIECBAoBQQiSwl7AgQIECBAgAABAgQIECBAgAABAgSGJiAQOTRaBRMgQIAAAQIECBAgQIAAAQIECBAgUAoIRJYS9gQIECBAgAABAgQIECBAgAABAgQIDE1AIHJotAomQIAAAQIECBAgQIAAAQIECBAgQKAUEIgsJewJECBAgAABAgQIECBAgAABAgQIEBiagEDk0GgVTIAAAQIECBAgQIAAAQIECBAgQIBAKSAQWUrYEyBAgAABAgQIECBAgAABAgQIECAwNAGByKHRKpgAAQIECBAgQIAAAQIECBAgQIAAgVLg/wCh4qD1COXt5gAAAABJRU5ErkJggg==" - } - }, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Core Ideas:\n", - " - Network structure\n", - " - Client / server\n", - " - Request / response\n", - " \n", - " \n", - " \n", - " - HTTP protocol\n", - " - URL\n", - " - Headers\n", - " - Status Codes\n", - " - The requests module" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## HTTP Status Codes you need to know\n", - "- 200: success\n", - "- 404: not found\n", - "\n", - "Here is a list of all status codes, you do NOT need to memorize it: https://en.wikipedia.org/wiki/List_of_HTTP_status_codes" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## requests.get : Simple string example\n", - "- URL: https://www.msyamkumar.com/hello.txt" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "200\n", - "Hello CS220 / CS319 students! Welcome to my website. Hope you are staying safe and healthy!\n", - "\n" - ] - } - ], - "source": [ - "url = \"https://www.msyamkumar.com/hello.txt\"\n", - "r = requests.get(url) # r is the response\n", - "print(r.status_code)\n", - "print(r.text)" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "404\n", - "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n", - "<Error><Code>NoSuchKey</Code><Message>The specified key does not exist.</Message><Key>meena/hello.txttttt</Key><RequestId>9PAFR0FANW1CRPTP</RequestId><HostId>Y+VL63r3qTktX1ZLIpaUvaSXOhstWA4yhSSA6RKCRumeA5+WK+ht7TbROpUZtVjmpGT/QaJcYA0=</HostId></Error>\n" - ] - } - ], - "source": [ - "# Q: What if the web site does not exist?\n", - "typo_url = \"https://www.msyamkumar.com/hello.txttttt\"\n", - "r = requests.get(typo_url)\n", - "print(r.status_code)\n", - "print(r.text)\n", - "\n", - "# A: We get a 404 (client error)" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "metadata": {}, - "outputs": [ - { - "ename": "AssertionError", - "evalue": "", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mAssertionError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m/var/folders/k6/kcy8b4f57hx9f1wh4sbs8mn40000gn/T/ipykernel_11873/2682133174.py\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0mtypo_url\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m\"https://www.msyamkumar.com/hello.txttttt\"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[0mr\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mrequests\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtypo_url\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 4\u001b[0;31m \u001b[0;32massert\u001b[0m \u001b[0mr\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mstatus_code\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;36m200\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 5\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mr\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mstatus_code\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 6\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mr\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtext\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;31mAssertionError\u001b[0m: " - ] - } - ], - "source": [ - "# We can check for a status_code error by using an assert\n", - "typo_url = \"https://www.msyamkumar.com/hello.txttttt\"\n", - "r = requests.get(typo_url)\n", - "assert r.status_code == 200\n", - "print(r.status_code)\n", - "print(r.text)" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "metadata": {}, - "outputs": [ - { - "ename": "HTTPError", - "evalue": "404 Client Error: Not Found for url: https://www.msyamkumar.com/hello.txttttt", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mHTTPError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m/var/folders/k6/kcy8b4f57hx9f1wh4sbs8mn40000gn/T/ipykernel_11873/4051826470.py\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;31m# Instead of using an assert, we often use raise_for_status()\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0mr\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mrequests\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtypo_url\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 3\u001b[0;31m \u001b[0mr\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mraise_for_status\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;31m#similar to asserting r.status_code == 200\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 4\u001b[0m \u001b[0mr\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtext\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/opt/anaconda3/lib/python3.9/site-packages/requests/models.py\u001b[0m in \u001b[0;36mraise_for_status\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 951\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 952\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mhttp_error_msg\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 953\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mHTTPError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mhttp_error_msg\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mresponse\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 954\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 955\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mclose\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;31mHTTPError\u001b[0m: 404 Client Error: Not Found for url: https://www.msyamkumar.com/hello.txttttt" - ] - } - ], - "source": [ - "# Instead of using an assert, we often use raise_for_status()\n", - "r = requests.get(typo_url)\n", - "r.raise_for_status() #similar to asserting r.status_code == 200\n", - "r.text\n", - "\n", - "# Note the error you get.... We will use this in the next cell" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "metadata": {}, - "outputs": [ - { - "ename": "NameError", - "evalue": "name 'HTTPError' is not defined", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mHTTPError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m/var/folders/k6/kcy8b4f57hx9f1wh4sbs8mn40000gn/T/ipykernel_11873/2028031330.py\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0mr\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mrequests\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtypo_url\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 5\u001b[0;31m \u001b[0mr\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mraise_for_status\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;31m#similar to asserting r.status_code == 200\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 6\u001b[0m \u001b[0mr\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtext\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/opt/anaconda3/lib/python3.9/site-packages/requests/models.py\u001b[0m in \u001b[0;36mraise_for_status\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 952\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mhttp_error_msg\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 953\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mHTTPError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mhttp_error_msg\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mresponse\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 954\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;31mHTTPError\u001b[0m: 404 Client Error: Not Found for url: https://www.msyamkumar.com/hello.txttttt", - "\nDuring handling of the above exception, another exception occurred:\n", - "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m/var/folders/k6/kcy8b4f57hx9f1wh4sbs8mn40000gn/T/ipykernel_11873/2028031330.py\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0mr\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mraise_for_status\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;31m#similar to asserting r.status_code == 200\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 6\u001b[0m \u001b[0mr\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtext\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 7\u001b[0;31m \u001b[0;32mexcept\u001b[0m \u001b[0mHTTPError\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0me\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;31m# What's still wrong here?\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 8\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"oops!!\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0me\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;31mNameError\u001b[0m: name 'HTTPError' is not defined" - ] - } - ], - "source": [ - "# Let's try to catch that error\n", - "\n", - "try:\n", - " r = requests.get(typo_url)\n", - " r.raise_for_status() #similar to asserting r.status_code == 200\n", - " r.text\n", - "except HTTPError as e: # What's still wrong here?\n", - " print(\"oops!!\", e)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# we often need to prepend the names of exceptions with the name of the module\n", - "# fix the error from above\n", - "\n", - "try:\n", - " r = requests.get(typo_url)\n", - " r.raise_for_status() #similar to asserting r.status_code == 200\n", - " r.text\n", - "except requests.HTTPError as e: #correct way to catch the error.\n", - " print(\"oops!!\", e)\n", - " \n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## requests.get : JSON file example\n", - "- URL: https://www.msyamkumar.com/scores.json\n", - "- `json.load` (FILE_OBJECT)\n", - "- `json.loads` (STRING)" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "{\n", - " \"alice\": 100,\n", - " \"bob\": 200,\n", - " \"cindy\": 300\n", - "}\n", - "\n", - "<class 'dict'> {'alice': 100, 'bob': 200, 'cindy': 300}\n" - ] - } - ], - "source": [ - "# GETting a JSON file, the long way\n", - "url = \"https://www.msyamkumar.com/scores.json\"\n", - "r = requests.get(url)\n", - "r.raise_for_status()\n", - "urltext = r.text\n", - "print(urltext)\n", - "d = json.loads(urltext)\n", - "print(type(d), d)" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "<class 'dict'> {'alice': 100, 'bob': 200, 'cindy': 300}\n" - ] - } - ], - "source": [ - "# GETting a JSON file, the shortcut way\n", - "url = \"https://www.msyamkumar.com/scores.json\"\n", - "#Shortcut to bypass using json.loads()\n", - "r = requests.get(url)\n", - "r.raise_for_status()\n", - "d2 = r.json()\n", - "print(type(d2), d2)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Good GET Etiquette\n", - "\n", - "Don't make a lot of requests to the same server all at once.\n", - " - Requests use up the server's time\n", - " - Major websites will often ban users who make too many requests\n", - " - You can break a server....similar to DDoS attacks (DON'T DO THIS)\n", - " \n", - "In CS220 we will usually give you a link to a copied file to avoid overloading the site.\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## DEMO: Course Enrollment" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Explore the API!\n", - "\n", - "https://coletnelson.us/cs220-api/classes\n", - "\n", - "https://coletnelson.us/cs220-api/classes_as_txt\n", - "\n", - "https://coletnelson.us/cs220-api/classes/MATH_221\n", - "\n", - "https://coletnelson.us/cs220-api/classes/COMPSCI_200\n", - "\n", - "... etc\n", - "\n", - "https://coletnelson.us/cs220-api/all_data" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Get the list of classes." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### When the data is `json`" - ] - }, - { - "cell_type": "code", - "execution_count": 19, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "<class 'list'>\n", - "['PSYCH_202', 'COMPSCI_537', 'COMPSCI_300', 'CHEM_104', 'COMPSCI_200', 'MATH_114', 'PSYCH_456', 'COMPSCI_252', 'COMPSCI_400', 'MATH_221', 'BIOLOGY_101', 'COMPSCI_354', 'CHEM_103', 'COMPSCI_639', 'PSYCH_401', 'COMPSCI_240', 'STATS_302']\n" - ] - } - ], - "source": [ - "url = \"https://coletnelson.us/cs220-api/classes\"\n", - "r = requests.get(url)\n", - "r.raise_for_status()\n", - "classes_list = r.json()\n", - "print(type(classes_list))\n", - "print(classes_list)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### When the data is `text`" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "<class 'str'>\n", - "PSYCH_202\n", - "COMPSCI_537\n", - "COMPSCI_300\n", - "CHEM_104\n", - "COMPSCI_200\n", - "MATH_114\n", - "PSYCH_456\n", - "COMPSCI_252\n", - "COMPSCI_400\n", - "MATH_221\n", - "BIOLOGY_101\n", - "COMPSCI_354\n", - "CHEM_103\n", - "COMPSCI_639\n", - "PSYCH_401\n", - "COMPSCI_240\n", - "STATS_302\n" - ] - } - ], - "source": [ - "url = \"https://coletnelson.us/cs220-api/classes_as_txt\"\n", - "r = requests.get(url)\n", - "r.raise_for_status()\n", - "classes_txt = r.text\n", - "print(type(classes_txt))\n", - "print(classes_txt)" - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "['PSYCH_202',\n", - " 'COMPSCI_537',\n", - " 'COMPSCI_300',\n", - " 'CHEM_104',\n", - " 'COMPSCI_200',\n", - " 'MATH_114',\n", - " 'PSYCH_456',\n", - " 'COMPSCI_252',\n", - " 'COMPSCI_400',\n", - " 'MATH_221',\n", - " 'BIOLOGY_101',\n", - " 'COMPSCI_354',\n", - " 'CHEM_103',\n", - " 'COMPSCI_639',\n", - " 'PSYCH_401',\n", - " 'COMPSCI_240',\n", - " 'STATS_302']" - ] - }, - "execution_count": 21, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "classes_txt_as_list = classes_txt.split('\\n')\n", - "classes_txt_as_list" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Get data for a specific class" - ] - }, - { - "cell_type": "code", - "execution_count": 22, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "<class 'dict'>\n", - "{'credits': 3, 'description': 'Learn the process of incrementally developing small (200-500 lines) programs along with the fundamental Computer Science topics. These topics include: problem abstraction and decomposition, the edit-compile-run cycle, using variables of primitive and more complex data types, conditional and loop-based flow control, basic testing and debugging techniques, how to define and call functions (methods), and IO processing techniques. Also teaches and reinforces good programming practices including the use of a consistent style, and meaningful documentation. Intended for students who have no prior programming experience.', 'keywords': ['computer', 'science', 'programming', 'java'], 'name': 'Programming 1', 'number': 'COMPSCI_200', 'requisites': [], 'sections': [{'instructor': 'Jim Williams', 'location': '132 Noland Hall', 'subsections': [{'location': '1350 Computer Sciences and Statistics', 'time': {'wednesday': '9:30am - 10:45am'}, 'number': 'LAB_311'}, {'location': '1350 Computer Sciences and Statistics', 'time': {'wednesday': '11:00am - 12:15pm'}, 'number': 'LAB_312'}, {'location': '1350 Computer Sciences and Statistics', 'time': {'wednesday': '2:30pm - 3:45pm'}, 'number': 'LAB_314'}, {'location': '1350 Computer Sciences and Statistics', 'time': {'wednesday': '4:00pm - 5:15pm'}, 'number': 'LAB_315'}], 'time': {'thursday': '8:00am - 9:15am', 'tuesday': '8:00am - 9:15am'}, 'number': 'LEC_001'}, {'instructor': 'Jim Williams', 'location': '132 Noland Hall', 'subsections': [{'location': '1370 Computer Sciences and Statistics', 'time': {'wednesday': '9:30am - 10:45am'}, 'number': 'LAB_321'}, {'location': '1370 Computer Sciences and Statistics', 'time': {'wednesday': '1:00pm - 2:15pm'}, 'number': 'LAB_323'}, {'location': '1370 Computer Sciences and Statistics', 'time': {'wednesday': '2:30pm - 3:45pm'}, 'number': 'LAB_324'}, {'location': '1370 Computer Sciences and Statistics', 'time': {'wednesday': '4:00pm - 5:15pm'}, 'number': 'LAB_325'}], 'time': {'thursday': '11:00am - 12:15pm', 'tuesday': '11:00am - 12:15pm'}, 'number': 'LEC_002'}, {'instructor': 'Marc Renault', 'location': '113 Brogden Psychology Building', 'subsections': [{'location': '1350 Computer Sciences and Statistics', 'time': {'tuesday': '9:30am - 10:45am'}, 'number': 'LAB_331'}, {'location': '1350 Computer Sciences and Statistics', 'time': {'tuesday': '11:00am - 12:15pm'}, 'number': 'LAB_332'}, {'location': '1350 Computer Sciences and Statistics', 'time': {'tuesday': '1:00pm - 2:15pm'}, 'number': 'LAB_333'}, {'location': '1350 Computer Sciences and Statistics', 'time': {'tuesday': '2:30pm - 3:45pm'}, 'number': 'LAB_334'}], 'time': {'friday': '1:20pm - 2:10pm', 'monday': '1:20pm - 2:10pm', 'wednesday': '1:20pm - 2:10pm'}, 'number': 'LEC_003'}, {'instructor': 'Marc Renault', 'location': '113 Brogden Psychology Building', 'subsections': [{'location': '1370 Computer Sciences and Statistics', 'time': {'tuesday': '9:30am - 10:45am'}, 'number': 'LAB_341'}, {'location': '1370 Computer Sciences and Statistics', 'time': {'tuesday': '11:00am - 12:15pm'}, 'number': 'LAB_342'}, {'location': '1370 Computer Sciences and Statistics', 'time': {'tuesday': '1:00pm - 2:15pm'}, 'number': 'LAB_343'}, {'location': '1370 Computer Sciences and Statistics', 'time': {'tuesday': '2:30pm - 3:45pm'}, 'number': 'LAB_344'}, {'location': '1370 Computer Sciences and Statistics', 'time': {'tuesday': '4:00pm - 5:15pm'}, 'number': 'LAB_345'}], 'time': {'friday': '3:30pm - 4:20pm', 'monday': '3:30pm - 4:20pm', 'wednesday': '3:30pm - 4:20pm'}, 'number': 'LEC_004'}], 'subject': 'Computer Science'}\n" - ] - } - ], - "source": [ - "url = \"https://coletnelson.us/cs220-api/classes/COMPSCI_200\"\n", - "r = requests.get(url)\n", - "r.raise_for_status()\n", - "cs200_data = r.json()\n", - "print(type(cs200_data))\n", - "print(cs200_data) # Too much data? Try print(cs220_data.keys())" - ] - }, - { - "cell_type": "code", - "execution_count": 23, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "dict_keys(['credits', 'description', 'keywords', 'name', 'number', 'requisites', 'sections', 'subject'])" - ] - }, - "execution_count": 23, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "cs200_data.keys()" - ] - }, - { - "cell_type": "code", - "execution_count": 24, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "3" - ] - }, - "execution_count": 24, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Get the number of credits the course is worth\n", - "cs200_data['credits']" - ] - }, - { - "cell_type": "code", - "execution_count": 25, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "['computer', 'science', 'programming', 'java']" - ] - }, - "execution_count": 25, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Get the list of keywords for the course\n", - "cs200_data['keywords']" - ] - }, - { - "cell_type": "code", - "execution_count": 26, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'Programming 1'" - ] - }, - "execution_count": 26, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Get the official course name\n", - "cs200_data['name']" - ] - }, - { - "cell_type": "code", - "execution_count": 27, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "4" - ] - }, - "execution_count": 27, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Get the number of sections offered.\n", - "len(cs200_data['sections'])" - ] - }, - { - "cell_type": "code", - "execution_count": 28, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[{'credits': 3, 'description': 'Behavior, including its development, motivation, frustrations, emotion, intelligence, learning, forgetting, personality, language, thinking, and social behavior.', 'keywords': ['psychology', 'behavior', 'emotion', 'intelligence', 'brain'], 'name': 'Introduction to Psychology', 'number': 'PSYCH_202', 'requisites': [], 'sections': [{'instructor': 'Jeff Henriques', 'location': '105 Brogden Psychology Building', 'subsections': [], 'time': {'thursday': '9:30am - 10:45am', 'tuesday': '9:30am - 10:45am'}, 'number': 'LEC_001'}, {'instructor': 'Jeff Henriques', 'location': '105 Brogden Psychology Building', 'subsections': [], 'time': {'thursday': '11:00am - 12:15pm', 'tuesday': '11:00am - 12:15pm'}, 'number': 'LEC_002'}, {'instructor': 'C. Shawn Green', 'location': '105 Brogden Psychology Building', 'subsections': [], 'time': {'monday': '8:00am - 9:15am', 'wednesday': '8:00am - 9:15am'}, 'number': 'LEC_003'}, {'instructor': 'Patti Coffey', 'location': '105 Brogden Psychology Building', 'subsections': [], 'time': {'thursday': '1:00pm - 2:15pm', 'tuesday': '1:00pm - 2:15pm'}, 'number': 'LEC_004'}, {'instructor': 'Sarah Gavac', 'location': '105 Brogden Psychology Building', 'subsections': [], 'time': {'thursday': '2:30pm - 3:45pm', 'tuesday': '2:30pm - 3:45pm'}, 'number': 'LEC_005'}, {'instructor': 'Patti Coffey', 'location': '101 Brogden Psychology Building', 'subsections': [], 'time': {'thursday': '2:30pm - 3:45pm', 'tuesday': '2:30pm - 3:45pm'}, 'number': 'LEC_006'}, {'instructor': 'Baoyu Wang', 'location': '105 Brogden Psychology Building', 'subsections': [], 'time': {'monday': '4:30pm - 5:15pm', 'wednesday': '4:30pm - 5:15pm'}, 'number': 'LEC_009'}], 'subject': 'Psychology'}, {'credits': 4, 'description': 'Input-output hardware, interrupt handling, properties of magnetic tapes, discs and drums, associative memories and virtual address translation techniques. Batch processing, time sharing and real-time systems, scheduling resource allocation, modular software systems, performance measurement and system evaluation.', 'keywords': ['computer', 'science', 'operating', 'system', 'systems'], 'name': 'Introduction to Operating Systems', 'number': 'COMPSCI_537', 'requisites': [['COMPSCI_354', 'COMPSCI_400']], 'sections': [{'instructor': 'Andrea Arpaci-Dusseau', 'location': '1125 DeLuca Biochemistry Building', 'subsections': [{'location': '2317 Engineering Hall', 'time': {'wednesday': '11:00am - 11:50am'}, 'number': 'DIS_301'}, {'location': '1325 Computer Sciences and Statistics', 'time': {'wednesday': '12:05pm - 12:55pm'}, 'number': 'DIS_302'}, {'location': '1325 Computer Sciences and Statistics', 'time': {'wednesday': '1:20pm - 2:10pm'}, 'number': 'DIS_303'}, {'location': '2255 Engineering Hall', 'time': {'wednesday': '3:30pm - 4:20pm'}, 'number': 'DIS_304'}, {'location': '1325 Computer Sciences and Statistics', 'time': {'wednesday': '4:15pm - 5:25pm'}, 'number': 'DIS_305'}], 'time': {'thursday': '11:00am - 12:15pm', 'tuesday': '11:00am - 12:15pm'}, 'number': 'LEC_001'}], 'subject': 'Computer Science'}, {'credits': 3, 'description': 'Introduces students to Object-Oriented Programming using classes and objects to solve more complex problems. Introduces array-based and linked data structures: including lists, stacks, and queues. Programming assignments require writing and developing multi-class (file) programs using interfaces, generics, and exception handling to solve challenging real world problems. Topics reviewed include reading/writing data and objects from/to files and exception handling, and command line arguments. Topics introduced: object-oriented design; class vs. object; create and define interfaces and iterators; searching and sorting; abstract data types (List,Stack,Queue,PriorityQueue(Heap),Binary Search Tree); generic interfaces (parametric polymorphism); how to design and write test methods and classes; array based vs. linked node implementations; introduction to complexity analysis; recursion.', 'keywords': ['computer', 'science', 'programming', 'java'], 'name': 'Programming 2', 'number': 'COMPSCI_300', 'requisites': [['COMPSCI_200']], 'sections': [{'instructor': 'Gary Dahl', 'location': 'AB20 Weeks Hall for Geological Sciences', 'subsections': [], 'time': {'thursday': '2:30pm - 3:45pm', 'tuesday': '2:30pm - 3:45pm'}, 'number': 'LEC_001'}, {'instructor': 'Gary Dahl', 'location': '132 Noland Hall', 'subsections': [], 'time': {'thursday': '1:00pm - 2:15pm', 'tuesday': '1:00pm - 2:15pm'}, 'number': 'LEC_002'}, {'instructor': 'Mouna Ayari Ben Hadj Kacem', 'location': 'AB20 Weeks Hall for Geological Sciences', 'subsections': [], 'time': {'friday': '11:00am - 11:50pm', 'monday': '11:00am - 11:50pm', 'wednesday': '11:00am - 11:50pm'}, 'number': 'LEC_003'}, {'instructor': 'Mouna Ayari Ben Hadj Kacem', 'location': '1310 Sterling Hall', 'subsections': [], 'time': {'friday': '2:25pm - 3:15pm', 'monday': '2:25pm - 3:15pm', 'wednesday': '2:25pm - 3:15pm'}, 'number': 'LEC_004'}], 'subject': 'Computer Science'}, {'credits': 5, 'description': 'Principles and application of chemical equilibrium, coordination chemistry, oxidation-reduction and electrochemistry, kinetics, nuclear chemistry, introduction to organic chemistry. Lecture, lab, and discussion.', 'keywords': ['chemistry'], 'name': 'General Chemistry II', 'number': 'CHEM_104', 'requisites': [['MATH_114'], ['CHEM_103']], 'sections': [{'instructor': 'Linda Zelewski', 'location': 'B10 Ingraham Hall', 'subsections': [{'location': '123 Van Hise Hall', 'time': {'monday': '2:25pm - 5:25pm', 'thursday': '11:00am - 11:50am', 'tuesday': '11:00am - 11:50am'}, 'number': 'DIS_401'}, {'location': '123 Van Hise Hall', 'time': {'monday': '2:25pm - 5:25pm', 'thursday': '12:05pm - 12:55pm', 'tuesday': '12:05pm - 12:55pm'}, 'number': 'DIS_402'}, {'location': 'B387 Chemistry Building', 'time': {'monday': '2:25pm - 5:25pm', 'thursday': '11:00am - 11:50am', 'tuesday': '11:00am - 11:50am'}, 'number': 'DIS_403'}, {'location': 'B387 Chemistry Building', 'time': {'monday': '2:25pm - 5:25pm', 'thursday': '12:05pm - 12:55pm', 'tuesday': '12:05pm - 12:55pm'}, 'number': 'DIS_404'}], 'time': {'thursday': '9:30am - 10:45am', 'tuesday': '9:30am - 10:45am'}, 'number': 'LEC_001'}, {'instructor': 'Lea Gustin', 'location': '204 Educational Sciences', 'subsections': [{'location': '2377 Chemistry Building', 'time': {'monday': '9:55am - 10:45am', 'tuesday': '5:40pm - 8:40pm', 'wednesday': '9:55am - 10:45am'}, 'number': 'DIS_421'}, {'location': '2377 Chemistry Building', 'time': {'monday': '11:00am - 11:50am', 'tuesday': '5:40pm - 8:40pm', 'wednesday': '11:00am - 11:50am'}, 'number': 'DIS_422'}, {'location': '2381 Chemistry Building', 'time': {'monday': '11:00am - 11:50am', 'tuesday': '5:40pm - 8:40pm', 'wednesday': '11:00am - 11:50am'}, 'number': 'DIS_423'}, {'location': '2377 Chemistry Building', 'time': {'monday': '12:05pm - 12:55pm', 'tuesday': '5:40pm - 8:40pm', 'wednesday': '12:05pm - 12:55pm'}, 'number': 'DIS_424'}], 'time': {'thursday': '1:00pm - 2:15pm', 'tuesday': '1:00pm - 2:15pm'}, 'number': 'LEC_002'}], 'subject': 'Chemistry'}, {'credits': 3, 'description': 'Learn the process of incrementally developing small (200-500 lines) programs along with the fundamental Computer Science topics. These topics include: problem abstraction and decomposition, the edit-compile-run cycle, using variables of primitive and more complex data types, conditional and loop-based flow control, basic testing and debugging techniques, how to define and call functions (methods), and IO processing techniques. Also teaches and reinforces good programming practices including the use of a consistent style, and meaningful documentation. Intended for students who have no prior programming experience.', 'keywords': ['computer', 'science', 'programming', 'java'], 'name': 'Programming 1', 'number': 'COMPSCI_200', 'requisites': [], 'sections': [{'instructor': 'Jim Williams', 'location': '132 Noland Hall', 'subsections': [{'location': '1350 Computer Sciences and Statistics', 'time': {'wednesday': '9:30am - 10:45am'}, 'number': 'LAB_311'}, {'location': '1350 Computer Sciences and Statistics', 'time': {'wednesday': '11:00am - 12:15pm'}, 'number': 'LAB_312'}, {'location': '1350 Computer Sciences and Statistics', 'time': {'wednesday': '2:30pm - 3:45pm'}, 'number': 'LAB_314'}, {'location': '1350 Computer Sciences and Statistics', 'time': {'wednesday': '4:00pm - 5:15pm'}, 'number': 'LAB_315'}], 'time': {'thursday': '8:00am - 9:15am', 'tuesday': '8:00am - 9:15am'}, 'number': 'LEC_001'}, {'instructor': 'Jim Williams', 'location': '132 Noland Hall', 'subsections': [{'location': '1370 Computer Sciences and Statistics', 'time': {'wednesday': '9:30am - 10:45am'}, 'number': 'LAB_321'}, {'location': '1370 Computer Sciences and Statistics', 'time': {'wednesday': '1:00pm - 2:15pm'}, 'number': 'LAB_323'}, {'location': '1370 Computer Sciences and Statistics', 'time': {'wednesday': '2:30pm - 3:45pm'}, 'number': 'LAB_324'}, {'location': '1370 Computer Sciences and Statistics', 'time': {'wednesday': '4:00pm - 5:15pm'}, 'number': 'LAB_325'}], 'time': {'thursday': '11:00am - 12:15pm', 'tuesday': '11:00am - 12:15pm'}, 'number': 'LEC_002'}, {'instructor': 'Marc Renault', 'location': '113 Brogden Psychology Building', 'subsections': [{'location': '1350 Computer Sciences and Statistics', 'time': {'tuesday': '9:30am - 10:45am'}, 'number': 'LAB_331'}, {'location': '1350 Computer Sciences and Statistics', 'time': {'tuesday': '11:00am - 12:15pm'}, 'number': 'LAB_332'}, {'location': '1350 Computer Sciences and Statistics', 'time': {'tuesday': '1:00pm - 2:15pm'}, 'number': 'LAB_333'}, {'location': '1350 Computer Sciences and Statistics', 'time': {'tuesday': '2:30pm - 3:45pm'}, 'number': 'LAB_334'}], 'time': {'friday': '1:20pm - 2:10pm', 'monday': '1:20pm - 2:10pm', 'wednesday': '1:20pm - 2:10pm'}, 'number': 'LEC_003'}, {'instructor': 'Marc Renault', 'location': '113 Brogden Psychology Building', 'subsections': [{'location': '1370 Computer Sciences and Statistics', 'time': {'tuesday': '9:30am - 10:45am'}, 'number': 'LAB_341'}, {'location': '1370 Computer Sciences and Statistics', 'time': {'tuesday': '11:00am - 12:15pm'}, 'number': 'LAB_342'}, {'location': '1370 Computer Sciences and Statistics', 'time': {'tuesday': '1:00pm - 2:15pm'}, 'number': 'LAB_343'}, {'location': '1370 Computer Sciences and Statistics', 'time': {'tuesday': '2:30pm - 3:45pm'}, 'number': 'LAB_344'}, {'location': '1370 Computer Sciences and Statistics', 'time': {'tuesday': '4:00pm - 5:15pm'}, 'number': 'LAB_345'}], 'time': {'friday': '3:30pm - 4:20pm', 'monday': '3:30pm - 4:20pm', 'wednesday': '3:30pm - 4:20pm'}, 'number': 'LEC_004'}], 'subject': 'Computer Science'}, {'credits': 5, 'description': 'The two semester sequence MATH_112-MATH_113 covers similar material as MATH_114, but in a slower pace.', 'keywords': ['math', 'mathematics', 'algebra', 'trigonometry'], 'name': 'Algebra and Trigonometry', 'number': 'MATH_114', 'requisites': [], 'sections': [{'instructor': 'Sharad Chandarana', 'location': 'B130 Van Vleck Hall', 'subsections': [{'location': 'B113 Van Vleck Hall', 'time': {'monday': '7:45am - 8:35am', 'wednesday': '7:45am - 8:35am'}, 'number': 'DIS_301'}, {'location': 'B113 Van Vleck Hall', 'time': {'monday': '8:50am - 9:40am', 'wednesday': '8:50am - 9:40am'}, 'number': 'DIS_303'}, {'location': 'B219 Van Vleck Hall', 'time': {'monday': '8:50am - 9:40am', 'wednesday': '8:50am - 9:40am'}, 'number': 'DIS_304'}, {'location': 'B113 Van Vleck Hall', 'time': {'monday': '9:55am - 10:45am', 'wednesday': '9:55am - 10:45am'}, 'number': 'DIS_305'}, {'location': 'B219 Van Vleck Hall', 'time': {'monday': '9:55am - 10:45am', 'wednesday': '9:55am - 10:45am'}, 'number': 'DIS_306'}, {'location': 'B341 Van Vleck Hall', 'time': {'monday': '1:20pm - 2:10pm', 'wednesday': '1:20pm - 2:10pm'}, 'number': 'DIS_307'}, {'location': 'B317 Van Vleck Hall', 'time': {'monday': '1:20pm - 2:10pm', 'wednesday': '1:20pm - 2:10pm'}, 'number': 'DIS_308'}, {'location': 'B341 Van Vleck Hall', 'time': {'monday': '2:25pm - 3:15pm', 'wednesday': '2:25pm - 3:15pm'}, 'number': 'DIS_309'}, {'location': 'B329 Van Vleck Hall', 'time': {'monday': '2:25pm - 3:15pm', 'wednesday': '2:25pm - 3:15pm'}, 'number': 'DIS_310'}, {'location': 'B317 Van Vleck Hall', 'time': {'monday': '7:45am - 8:35am', 'wednesday': '7:45am - 8:35am'}, 'number': 'DIS_311'}], 'time': {'thursday': '2:30pm - 3:45pm', 'tuesday': '2:30pm - 3:45pm'}, 'number': 'LEC_001'}, {'instructor': 'Sharad Chandarana', 'location': '19 Ingraham Hall', 'subsections': [{'location': '591 Van Hise Hall', 'time': {'thursday': '8:50am - 9:40am', 'tuesday': '8:50am - 9:40am'}, 'number': 'DIS_321'}, {'location': 'B219 Van Vleck Hall', 'time': {'thursday': '9:55am - 10:45am', 'tuesday': '9:55am - 10:45am'}, 'number': 'DIS_322'}, {'location': '4020 Vilas Hall', 'time': {'thursday': '11:00am - 11:50am', 'tuesday': '11:00am - 11:50am'}, 'number': 'DIS_323'}, {'location': '599 Van Hise Hall', 'time': {'thursday': '11:00am - 11:50am', 'tuesday': '11:00am - 11:50am'}, 'number': 'DIS_324'}, {'location': 'B341 Van Vleck Hall', 'time': {'thursday': '1:20pm - 2:10pm', 'tuesday': '1:20pm - 2:10pm'}, 'number': 'DIS_325'}, {'location': '223 Van Hise Hall', 'time': {'thursday': '1:20pm - 2:10pm', 'tuesday': '1:20pm - 2:10pm'}, 'number': 'DIS_326'}, {'location': '223 Van Hise Hall', 'time': {'thursday': '2:25pm - 3:15pm', 'tuesday': '2:25pm - 3:15pm'}, 'number': 'DIS_328'}, {'location': 'B219 Van Vleck Hall', 'time': {'thursday': '3:30pm - 4:20pm', 'tuesday': '3:30pm - 4:20pm'}, 'number': 'DIS_329'}, {'location': 'B341 Van Vleck Hall', 'time': {'thursday': '3:30pm - 4:20pm', 'tuesday': '3:30pm - 4:20pm'}, 'number': 'DIS_330'}], 'time': {'friday': '8:50am - 9:40am', 'monday': '8:50am - 9:40am', 'wednesday': '8:50am - 9:40am'}, 'number': 'LEC_002'}], 'subject': 'Mathematics'}, {'credits': 4, 'description': 'The systematic study of the individual in a social context, including social interaction, motivation, attitudes, conformity, communication, leadership, personal relationships, and behavior in small groups.', 'keywords': ['psychology', 'science', 'social', 'interaction', 'behavior'], 'name': 'Introductory Social Psychology', 'number': 'PSYCH_456', 'requisites': [['PSYCH_202']], 'sections': [{'instructor': 'Abigail Letak', 'location': '6104 Sewell Social Sciences', 'subsections': [{'location': '6121 Sewell Social Sciences', 'time': {'tuesday': '8:50am - 9:40am'}, 'number': 'DIS_301'}, {'location': '6121 Sewell Social Sciences', 'time': {'tuesday': '9:55am - 10:45am'}, 'number': 'DIS_302'}, {'location': '6121 Sewell Social Sciences', 'time': {'tuesday': '11:00am - 11:50am'}, 'number': 'DIS_303'}, {'location': '6121 Sewell Social Sciences', 'time': {'tuesday': '1:20pm - 2:10pm'}, 'number': 'DIS_304'}, {'location': '6121 Sewell Social Sciences', 'time': {'tuesday': '2:25pm - 3:15pm'}, 'number': 'DIS_305'}], 'time': {'friday': '11:00am - 11:50am', 'monday': '11:00am - 11:50am', 'wednesday': '11:00am - 11:50am'}, 'number': 'LEC_001'}], 'subject': 'Psychology'}, {'credits': 2, 'description': 'Logic components built with transistors, rudimentary Boolean algebra, basic combinational logic design, basic synchronous sequential logic design, basic computer organization and design, introductory machine- and assembly-language programming.', 'keywords': ['computer', 'science', 'engineering', 'programming'], 'name': 'Introduction to Computer Engineering', 'number': 'COMPSCI_252', 'requisites': [], 'sections': [{'instructor': 'Joseph Krachey', 'location': '1610 Engineering Hall', 'subsections': [], 'time': {'friday': '2:25pm - 3:15pm', 'monday': '2:25pm - 3:15pm', 'wednesday': '2:25pm - 3:15pm'}, 'number': 'LEC_001'}, {'instructor': 'Adil Ibrahim', 'location': '113 Brogden Psychology Building', 'subsections': [], 'time': {'friday': '8:50am - 9:40am', 'monday': '8:50am - 9:40am', 'wednesday': '8:50am - 9:40am'}, 'number': 'LEC_002'}, {'instructor': 'Adil Ibrahim', 'location': '113 Brogden Psychology Building', 'subsections': [], 'time': {'friday': '12:05pm - 12:55pm', 'monday': '12:05pm - 12:55pm', 'wednesday': '12:05pm - 12:55pm'}, 'number': 'LEC_005'}], 'subject': 'Computer Science'}, {'credits': 3, 'description': 'The third course in our programming fundamentals sequence. It presumes that students understand and use functional and object-oriented design and abstract data types as needed. This course introduces balanced search trees, graphs, graph traversal algorithms, hash tables and sets, and complexity analysis and about classes of problems that require each data type. Students are required to design and implement using high quality professional code, a medium sized program, that demonstrates knowledge and use of latest language features, tools, and conventions. Additional topics introduced will include as needed for projects: inheritance and polymorphism; anonymous inner classes, lambda functions, performance analysis to discover and optimize critical code blocks. Students learn about industry standards for code development. Students will design and implement a medium size project with a more advanced user-interface design, such as a web or mobile application with a GUI and event- driven implementation; use of version-control software.', 'keywords': ['computer', 'science', 'programming', 'java'], 'name': 'Programming 3', 'number': 'COMPSCI_400', 'requisites': [['COMPSCI_300']], 'sections': [{'instructor': 'Gary Dahl', 'location': 'AB20 Weeks Hall for Geological Sciences', 'subsections': [], 'time': {'thursday': '2:30pm - 3:45pm', 'tuesday': '2:30pm - 3:45pm'}, 'number': 'LEC_001'}, {'instructor': 'Gary Dahl', 'location': '132 Noland Hall', 'subsections': [], 'time': {'thursday': '1:00pm - 2:15pm', 'tuesday': '1:00pm - 2:15pm'}, 'number': 'LEC_002'}, {'instructor': 'Mouna Ayari Ben Hadj Kacem', 'location': 'AB20 Weeks Hall for Geological Sciences', 'subsections': [], 'time': {'friday': '11:00am - 11:50pm', 'monday': '11:00am - 11:50pm', 'wednesday': '11:00am - 11:50pm'}, 'number': 'LEC_003'}, {'instructor': 'Mouna Ayari Ben Hadj Kacem', 'location': '1310 Sterling Hall', 'subsections': [], 'time': {'friday': '2:25pm - 3:15pm', 'monday': '2:25pm - 3:15pm', 'wednesday': '2:25pm - 3:15pm'}, 'number': 'LEC_004'}], 'subject': 'Computer Science'}, {'credits': 5, 'description': 'Introduction to differential and integral calculus and plane analytic geometry; applications; transcendental functions.', 'keywords': ['math', 'mathematics', 'calculus', 'analytical', 'geometry', 'differential', 'integral'], 'name': 'Calculus and Analytical Geometry 1', 'number': 'MATH_221', 'requisites': [['MATH_114']], 'sections': [{'instructor': 'Laurentiu Maxim', 'location': '6210 Sewell Social Sciences', 'subsections': [{'location': 'B231 Van Vleck Hall', 'time': {'monday': '7:45am - 8:35am', 'wednesday': '7:45am - 8:35am'}, 'number': 'DIS_301'}, {'location': 'B215 Van Vleck Hall', 'time': {'monday': '7:45am - 8:35am', 'wednesday': '7:45am - 8:35am'}, 'number': 'DIS_302'}, {'location': 'B309 Van Vleck Hall', 'time': {'monday': '3:30pm - 4:20pm', 'wednesday': '3:30pm - 4:20pm'}, 'number': 'DIS_303'}, {'location': 'B211 Van Vleck Hall', 'time': {'monday': '3:30pm - 4:20pm', 'wednesday': '3:30pm - 4:20pm'}, 'number': 'DIS_304'}, {'location': 'B129 Van Vleck Hall', 'time': {'monday': '11:00am - 11:50am', 'wednesday': '11:00am - 11:50am'}, 'number': 'DIS_305'}, {'location': 'B131 Van Vleck Hall', 'time': {'monday': '11:00am - 11:50am', 'wednesday': '11:00am - 11:50am'}, 'number': 'DIS_306'}, {'location': 'B231 Van Vleck Hall', 'time': {'monday': '12:05pm - 12:55pm', 'wednesday': '12:05pm - 12:55pm'}, 'number': 'DIS_307'}, {'location': 'B215 Van Vleck Hall', 'time': {'monday': '12:05pm - 12:55pm', 'wednesday': '12:05pm - 12:55pm'}, 'number': 'DIS_308'}, {'location': 'B313 Van Vleck Hall', 'time': {'monday': '1:20pm - 2:10pm', 'wednesday': '1:20pm - 2:10pm'}, 'number': 'DIS_309'}, {'location': 'B309 Van Vleck Hall', 'time': {'monday': '1:20pm - 2:10pm', 'wednesday': '1:20pm - 2:10pm'}, 'number': 'DIS_310'}, {'location': 'B305 Van Vleck Hall', 'time': {'monday': '2:25pm - 3:15pm', 'wednesday': '2:25pm - 3:15pm'}, 'number': 'DIS_311'}, {'location': 'B105 Van Vleck Hall', 'time': {'monday': '2:25pm - 3:15pm', 'wednesday': '2:25pm - 3:15pm'}, 'number': 'DIS_312'}, {'location': 'B321 Van Vleck Hall', 'time': {'friday': '9:55am - 10:45am', 'monday': '9:55am - 10:45am', 'wednesday': '9:55am - 10:45am'}, 'number': 'DIS_313'}], 'time': {'thursday': '1:00pm - 2:15pm', 'tuesday': '1:00pm - 2:15pm'}, 'number': 'LEC_001'}], 'subject': 'Mathematics'}, {'credits': 3, 'description': 'General biological principles. Topics include: evolution, ecology, animal behavior, cell structure and function, genetics and molecular genetics and the physiology of a variety of organ systems emphasizing function in humans.', 'keywords': ['biology', 'science', 'animal', 'evolution', 'genetics', 'ecology'], 'name': 'Animal Biology', 'number': 'BIOLOGY_101', 'requisites': [], 'sections': [{'instructor': 'Sharon Thoma', 'location': '272 Bascom Hall', 'subsections': [], 'time': {'friday': '11:00am - 11:50am', 'monday': '11:00am - 11:50am', 'wednesday': '11:00am - 11:50am'}, 'number': 'LEC_001'}, {'instructor': 'Sharon Thoma', 'location': '272 Bascom Hall', 'subsections': [], 'time': {'friday': '12:05pm - 12:55pm', 'monday': '12:05pm - 12:55pm', 'wednesday': '12:05pm - 12:55pm'}, 'number': 'LEC_002'}], 'subject': 'Biology'}, {'credits': 3, 'description': 'An introduction to fundamental structures of computer systems and the C programming language with a focus on the low-level interrelationships and impacts on performance. Topics include the virtual address space and virtual memory, the heap and dynamic memory management, the memory hierarchy and caching, assembly language and the stack, communication and interrupts/signals, compiling and assemblers/linkers.', 'keywords': ['computer', 'science', 'engineering', 'electrical', 'machine', 'programming'], 'name': 'Machine Organization and Programming', 'number': 'COMPSCI_354', 'requisites': [['COMPSCI_252'], ['COMPSCI_300']], 'sections': [{'instructor': 'James Skrentny', 'location': '132 Noland Hall', 'subsections': [], 'time': {'thursday': '2:30pm - 3:45pm', 'tuesday': '2:30pm - 3:45pm'}, 'number': 'LEC_001'}, {'instructor': 'James Skrentny', 'location': '132 Noland Hall', 'subsections': [], 'time': {'thursday': '4:00pm - 5:15pm', 'tuesday': '4:00pm - 5:15pm'}, 'number': 'LEC_002'}], 'subject': 'Computer Science'}, {'credits': 4, 'description': 'Introduction. Stoichiometry and the mole concept, the behavior of gases, liquids and solids, thermochemistry, electronic structure of atoms and chemical bonding, descriptive chemistry of selected elements and compounds, intermolecular forces. For students taking one year or more of college chemistry; serves as a prereq for CHEM_104; lecture, lab and discussion.', 'keywords': ['chemistry'], 'name': 'General Chemistry I', 'number': 'CHEM_103', 'requisites': [], 'sections': [{'instructor': 'Unknown', 'location': 'B10 Ingraham Hall', 'subsections': [{'location': '49 Sellery Residence Hall', 'time': {'monday': '3:30pm - 4:20pm', 'wednesday': '3:30pm - 4:20pm'}, 'number': 'DIS_301'}, {'location': '2307 Chemistry Building', 'time': {'monday': '4:35pm - 5:25pm', 'wednesday': '4:35pm - 5:25pm'}, 'number': 'DIS_302'}, {'location': '123 Van Hise Hall', 'time': {'monday': '1:20pm - 2:10pm', 'wednesday': '1:20pm - 2:10pm'}, 'number': 'DIS_303'}, {'location': '123 Van Hise Hall', 'time': {'monday': '2:25pm - 3:15pm', 'wednesday': '2:25pm - 3:15pm'}, 'number': 'DIS_304'}], 'time': {'friday': '11:00am - 11:50am', 'monday': '11:00am - 11:50am', 'wednesday': '11:00am - 11:50am'}, 'number': 'LEC_001'}], 'subject': 'Chemistry'}, {'credits': 3, 'description': 'This course introduces students to the software development of user interfaces (UIs). Topics covered include state-of-the-art (1) UI paradigms, such as event-driven interfaces, direct-manipulation interfaces, and dialogue-based interaction; (2) methods for capturing, interpreting, and responding to different forms of user input and states, including pointing, text entry, speech, touch, gestures, user activity, context, and physiological states; and (3) platform-specific UI development APIs, frameworks, and toolkits for platforms including web/mobile/desktop interfaces, natural user interfaces, and voice user interfaces. Through readings, lectures, and hands-on-activities, students will learn about the fundamental concepts, technologies, and methods in building user interfaces. Assignments will provide an opportunity to gain hands-on experience in the use of state-of-the-art UI development tools and build a UI development portfolio.', 'keywords': ['computer', 'science', 'building', 'user', 'interface', 'interfaces', 'design', 'ui'], 'name': 'Building User Interfaces', 'number': 'COMPSCI_639', 'requisites': [['COMPSCI_300']], 'sections': [{'instructor': 'Bilge Mutlu', 'location': '1221 Computer Sciences and Statistics', 'subsections': [], 'time': {'thursday': '1:00pm - 2:15pm', 'tuesday': '1:00pm - 2:15pm'}, 'number': 'LEC_002'}], 'subject': 'Computer Science'}, {'credits': 3, 'description': 'Focuses on the role that psychological principles, research evidence and social science play in the laws of U.S. society, especially in the policies and mechanisms of social control of human behavior. The course will address the ways that society defines membership, and the role of psychology in how it determines who should be excluded or restricted from open society, in order to maintain a more civil society. In addition to learning the factual information about how selected processes work in the legal and social context, students will be asked to consider the role they can play as citizens in supporting or changing these social processes. The course will take a particular interest in psycholegal issues \"in action\" and in learning about the clinical-legal processes used to determine the disposition of individuals considered marginal in society. Finally, the course will address the mechanisms that are used to exclude individuals from open society through criminal and civil court processes, the role of psychology as a science, and the role of psychologists as behavioral experts in criminal and civil courts, and in shaping social policies.', 'keywords': ['psychology', 'science', 'law', 'social', 'policy', 'behavior'], 'name': 'Psychology, Law, and Social Policy', 'number': 'PSYCH_401', 'requisites': [['PSYCH_202']], 'sections': [{'instructor': 'Gregory Van Rybroek', 'location': '121 Brogden Psychology Building', 'subsections': [], 'time': {'monday': '4:00pm - 5:15pm', 'wednesday': '4:00pm - 5:15pm'}, 'number': 'LEC_001'}], 'subject': 'Psychology'}, {'credits': 3, 'description': 'Basic concepts of logic, sets, partial order and other relations, and functions. Basic concepts of mathematics (definitions, proofs, sets, functions, and relations) with a focus on discrete structures: integers, bits, strings, trees, and graphs. Propositional logic, Boolean algebra, and predicate logic. Mathematical induction and recursion. Invariants and algorithmic correctness. Recurrences and asymptotic growth analysis. Fundamentals of counting.', 'keywords': ['computer', 'science', 'math', 'mathematics', 'discrete', 'logic', 'algorithm', 'algorithms'], 'name': 'Introduction To Discrete Mathematics', 'number': 'COMPSCI_240', 'requisites': [['MATH_221']], 'sections': [{'instructor': 'Beck Hasti', 'location': '105 Brogden Psychology Building', 'subsections': [{'location': '1257 Computer Sciences and Statistics', 'time': {'tuesday': '8:50am - 9:40am'}, 'number': 'DIS_310'}, {'location': '1257 Computer Sciences and Statistics', 'time': {'thursday': '8:50am - 9:40am'}, 'number': 'DIS_311'}, {'location': '3024 Engineering Hall', 'time': {'tuesday': '9:55am - 10:45am'}, 'number': 'DIS_312'}, {'location': '2345 Engineering Hall', 'time': {'thursday': '9:55am - 10:45am'}, 'number': 'DIS_313'}, {'location': '2535 Engineering Hall', 'time': {'tuesday': '11:00am - 11:50am'}, 'number': 'DIS_314'}, {'location': '2535 Engineering Hall', 'time': {'thursday': '11:00am - 11:50am'}, 'number': 'DIS_315'}, {'location': 'B309 Van Vleck Hall', 'time': {'tuesday': '9:55am - 10:45am'}, 'number': 'DIS_316'}], 'time': {'friday': '9:55am - 10:45am', 'monday': '9:55am - 10:45am', 'wednesday': '9:55am - 10:45am'}, 'number': 'LEC_001'}, {'instructor': 'Beck Hasti', 'location': '132 Noland Hall', 'subsections': [{'location': 'B211 Van Vleck Hall', 'time': {'thursday': '11:00am - 11:50am'}, 'number': 'DIS_320'}, {'location': 'B211 Van Vleck Hall', 'time': {'tuesday': '12:05pm - 12:55pm'}, 'number': 'DIS_321'}, {'location': '2255 Engineering Hall', 'time': {'thursday': '12:05pm - 12:55pm'}, 'number': 'DIS_322'}, {'location': '2349 Engineering Hall', 'time': {'tuesday': '1:20pm - 2:10pm'}, 'number': 'DIS_323'}, {'location': '1263 Computer Sciences and Statistics', 'time': {'thursday': '1:20pm - 2:10pm'}, 'number': 'DIS_324'}, {'location': '3418 Engineering Hall', 'time': {'tuesday': '2:25pm - 3:15pm'}, 'number': 'DIS_325'}, {'location': '3418 Engineering Hall', 'time': {'thursday': '2:25pm - 3:15pm'}, 'number': 'DIS_326'}], 'time': {'friday': '1:20pm - 2:10pm', 'monday': '1:20pm - 2:10pm', 'wednesday': '1:20pm - 2:10pm'}, 'number': 'LEC_002'}, {'instructor': 'Beck Hasti', 'location': '168 Noland Hall', 'subsections': [{'location': '1263 Computer Sciences and Statistics', 'time': {'tuesday': '8:50am - 9:40am'}, 'number': 'DIS_330'}, {'location': '1263 Computer Sciences and Statistics', 'time': {'tuesday': '1:20pm - 2:10pm'}, 'number': 'DIS_331'}, {'location': '3024 Engineering Hall', 'time': {'thursday': '9:55am - 10:45am'}, 'number': 'DIS_332'}, {'location': '2349 Engineering Hall', 'time': {'thursday': '12:05am - 12:55am'}, 'number': 'DIS_333'}], 'time': {'friday': '2:25pm - 3:15pm', 'monday': '2:25pm - 3:15pm', 'wednesday': '2:25pm - 3:15pm'}, 'number': 'LEC_003'}], 'subject': 'Computer Science'}, {'credits': 3, 'description': 'Graphical and numerical exploration of data; standard errors; distributions for statistical models including binomial, Poisson, normal; estimation; hypothesis testing; randomization tests; basic principles of experimental design; regression; ANOVA; categorical data analysis; goodness of fit; application. (intended for students wishing to take additional statistics courses).', 'keywords': ['statistics', 'statistical', 'math', 'mathematics', 'methods'], 'name': 'Accelerated Introduction to Statistical Methods', 'number': 'STATS_302', 'requisites': [['MATH_221']], 'sections': [{'instructor': 'Unknown', 'location': '331 Service Memorial Institute', 'subsections': [{'location': '212 Educational Sciences', 'time': {'tuesday': '1:20pm - 2:10pm'}, 'number': 'DIS_311'}, {'location': '1313 Sterling Hall', 'time': {'wednesday': '7:45am - 8:35am'}, 'number': 'DIS_312'}, {'location': '1313 Sterling Hall', 'time': {'wednesday': '11:00am - 11:50am'}, 'number': 'DIS_313'}], 'time': {'monday': '4:00pm - 5:15pm', 'wednesday': '4:00pm - 5:15pm'}, 'number': 'LEC_001'}], 'subject': 'Statistics'}]\n" - ] - } - ], - "source": [ - "# Collect all the class data in a list called 'all_class_data'\n", - "all_class_data = []\n", - "for class_num in classes_list:\n", - " url = \"https://coletnelson.us/cs220-api/classes/\" + class_num\n", - " r = requests.get(url)\n", - " r.raise_for_status()\n", - " class_data = r.json()\n", - " all_class_data.append(class_data)\n", - "\n", - "print(all_class_data) # Too much data? Try print(len(all_class_data))" - ] - }, - { - "cell_type": "code", - "execution_count": 29, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "17\n" - ] - } - ], - "source": [ - "print(len(all_class_data))" - ] - }, - { - "cell_type": "code", - "execution_count": 30, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "3 PSYCH_202 Introduction to Psychology\n", - "4 COMPSCI_537 Introduction to Operating Systems\n", - "3 COMPSCI_300 Programming 2\n", - "5 CHEM_104 General Chemistry II\n", - "3 COMPSCI_200 Programming 1\n", - "5 MATH_114 Algebra and Trigonometry\n", - "4 PSYCH_456 Introductory Social Psychology\n", - "2 COMPSCI_252 Introduction to Computer Engineering\n", - "3 COMPSCI_400 Programming 3\n", - "5 MATH_221 Calculus and Analytical Geometry 1\n", - "3 BIOLOGY_101 Animal Biology\n", - "3 COMPSCI_354 Machine Organization and Programming\n", - "4 CHEM_103 General Chemistry I\n", - "3 COMPSCI_639 Building User Interfaces\n", - "3 PSYCH_401 Psychology, Law, and Social Policy\n", - "3 COMPSCI_240 Introduction To Discrete Mathematics\n", - "3 STATS_302 Accelerated Introduction to Statistical Methods\n" - ] - } - ], - "source": [ - "# Print the number of credits, course number, and name for each class.\n", - "for spec_class in all_class_data:\n", - " print(spec_class['credits'], spec_class['number'], spec_class['name'])" - ] - }, - { - "cell_type": "code", - "execution_count": 31, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "3.4705882352941178" - ] - }, - "execution_count": 31, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# What is the average number of credits per course?\n", - "num_credits = 0 \n", - "for spec_class in all_class_data:\n", - " num_credits += spec_class['credits']\n", - "num_credits / len(all_class_data)" - ] - }, - { - "cell_type": "code", - "execution_count": 32, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "['Biology',\n", - " 'Chemistry',\n", - " 'Computer Science',\n", - " 'Mathematics',\n", - " 'Psychology',\n", - " 'Statistics']" - ] - }, - "execution_count": 32, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# What are the unique subjects?\n", - "subjects = []\n", - "for spec_class in all_class_data:\n", - " subjects.append(spec_class['subject'])\n", - "list(set(subjects))" - ] - }, - { - "cell_type": "code", - "execution_count": 33, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "['COMPSCI_300', 'COMPSCI_200', 'COMPSCI_400']" - ] - }, - "execution_count": 33, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Besides PYSCH 202, what are the course numbers of the courses\n", - "# with the most sections offered (not including subsections)?\n", - "high_courses = []\n", - "high_sections = 0\n", - "for spec_class in all_class_data:\n", - " current_course_num = spec_class['number']\n", - " current_num_sects = len(spec_class['sections'])\n", - " \n", - " if current_course_num == 'PSYCH_202':\n", - " continue\n", - " \n", - " if current_num_sects == high_sections:\n", - " high_courses.append(current_course_num)\n", - " elif current_num_sects > high_sections:\n", - " high_courses = []\n", - " high_courses.append(current_course_num)\n", - " high_sections = current_num_sects\n", - "high_courses" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Can we make a Pandas dataframe? Yes!" - ] - }, - { - "cell_type": "code", - "execution_count": 34, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "<div>\n", - "<style scoped>\n", - " .dataframe tbody tr th:only-of-type {\n", - " vertical-align: middle;\n", - " }\n", - "\n", - " .dataframe tbody tr th {\n", - " vertical-align: top;\n", - " }\n", - "\n", - " .dataframe thead th {\n", - " text-align: right;\n", - " }\n", - "</style>\n", - "<table border=\"1\" class=\"dataframe\">\n", - " <thead>\n", - " <tr style=\"text-align: right;\">\n", - " <th></th>\n", - " <th>credits</th>\n", - " <th>description</th>\n", - " <th>keywords</th>\n", - " <th>name</th>\n", - " <th>number</th>\n", - " <th>requisites</th>\n", - " <th>sections</th>\n", - " <th>subject</th>\n", - " </tr>\n", - " </thead>\n", - " <tbody>\n", - " <tr>\n", - " <th>0</th>\n", - " <td>3</td>\n", - " <td>Behavior, including its development, motivatio...</td>\n", - " <td>[psychology, behavior, emotion, intelligence, ...</td>\n", - " <td>Introduction to Psychology</td>\n", - " <td>PSYCH_202</td>\n", - " <td>[]</td>\n", - " <td>[{'instructor': 'Jeff Henriques', 'location': ...</td>\n", - " <td>Psychology</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1</th>\n", - " <td>4</td>\n", - " <td>Input-output hardware, interrupt handling, pro...</td>\n", - " <td>[computer, science, operating, system, systems]</td>\n", - " <td>Introduction to Operating Systems</td>\n", - " <td>COMPSCI_537</td>\n", - " <td>[[COMPSCI_354, COMPSCI_400]]</td>\n", - " <td>[{'instructor': 'Andrea Arpaci-Dusseau', 'loca...</td>\n", - " <td>Computer Science</td>\n", - " </tr>\n", - " <tr>\n", - " <th>2</th>\n", - " <td>3</td>\n", - " <td>Introduces students to Object-Oriented Program...</td>\n", - " <td>[computer, science, programming, java]</td>\n", - " <td>Programming 2</td>\n", - " <td>COMPSCI_300</td>\n", - " <td>[[COMPSCI_200]]</td>\n", - " <td>[{'instructor': 'Gary Dahl', 'location': 'AB20...</td>\n", - " <td>Computer Science</td>\n", - " </tr>\n", - " <tr>\n", - " <th>3</th>\n", - " <td>5</td>\n", - " <td>Principles and application of chemical equilib...</td>\n", - " <td>[chemistry]</td>\n", - " <td>General Chemistry II</td>\n", - " <td>CHEM_104</td>\n", - " <td>[[MATH_114], [CHEM_103]]</td>\n", - " <td>[{'instructor': 'Linda Zelewski', 'location': ...</td>\n", - " <td>Chemistry</td>\n", - " </tr>\n", - " <tr>\n", - " <th>4</th>\n", - " <td>3</td>\n", - " <td>Learn the process of incrementally developing ...</td>\n", - " <td>[computer, science, programming, java]</td>\n", - " <td>Programming 1</td>\n", - " <td>COMPSCI_200</td>\n", - " <td>[]</td>\n", - " <td>[{'instructor': 'Jim Williams', 'location': '1...</td>\n", - " <td>Computer Science</td>\n", - " </tr>\n", - " <tr>\n", - " <th>5</th>\n", - " <td>5</td>\n", - " <td>The two semester sequence MATH_112-MATH_113 co...</td>\n", - " <td>[math, mathematics, algebra, trigonometry]</td>\n", - " <td>Algebra and Trigonometry</td>\n", - " <td>MATH_114</td>\n", - " <td>[]</td>\n", - " <td>[{'instructor': 'Sharad Chandarana', 'location...</td>\n", - " <td>Mathematics</td>\n", - " </tr>\n", - " <tr>\n", - " <th>6</th>\n", - " <td>4</td>\n", - " <td>The systematic study of the individual in a so...</td>\n", - " <td>[psychology, science, social, interaction, beh...</td>\n", - " <td>Introductory Social Psychology</td>\n", - " <td>PSYCH_456</td>\n", - " <td>[[PSYCH_202]]</td>\n", - " <td>[{'instructor': 'Abigail Letak', 'location': '...</td>\n", - " <td>Psychology</td>\n", - " </tr>\n", - " <tr>\n", - " <th>7</th>\n", - " <td>2</td>\n", - " <td>Logic components built with transistors, rudim...</td>\n", - " <td>[computer, science, engineering, programming]</td>\n", - " <td>Introduction to Computer Engineering</td>\n", - " <td>COMPSCI_252</td>\n", - " <td>[]</td>\n", - " <td>[{'instructor': 'Joseph Krachey', 'location': ...</td>\n", - " <td>Computer Science</td>\n", - " </tr>\n", - " <tr>\n", - " <th>8</th>\n", - " <td>3</td>\n", - " <td>The third course in our programming fundamenta...</td>\n", - " <td>[computer, science, programming, java]</td>\n", - " <td>Programming 3</td>\n", - " <td>COMPSCI_400</td>\n", - " <td>[[COMPSCI_300]]</td>\n", - " <td>[{'instructor': 'Gary Dahl', 'location': 'AB20...</td>\n", - " <td>Computer Science</td>\n", - " </tr>\n", - " <tr>\n", - " <th>9</th>\n", - " <td>5</td>\n", - " <td>Introduction to differential and integral calc...</td>\n", - " <td>[math, mathematics, calculus, analytical, geom...</td>\n", - " <td>Calculus and Analytical Geometry 1</td>\n", - " <td>MATH_221</td>\n", - " <td>[[MATH_114]]</td>\n", - " <td>[{'instructor': 'Laurentiu Maxim', 'location':...</td>\n", - " <td>Mathematics</td>\n", - " </tr>\n", - " <tr>\n", - " <th>10</th>\n", - " <td>3</td>\n", - " <td>General biological principles. Topics include:...</td>\n", - " <td>[biology, science, animal, evolution, genetics...</td>\n", - " <td>Animal Biology</td>\n", - " <td>BIOLOGY_101</td>\n", - " <td>[]</td>\n", - " <td>[{'instructor': 'Sharon Thoma', 'location': '2...</td>\n", - " <td>Biology</td>\n", - " </tr>\n", - " <tr>\n", - " <th>11</th>\n", - " <td>3</td>\n", - " <td>An introduction to fundamental structures of c...</td>\n", - " <td>[computer, science, engineering, electrical, m...</td>\n", - " <td>Machine Organization and Programming</td>\n", - " <td>COMPSCI_354</td>\n", - " <td>[[COMPSCI_252], [COMPSCI_300]]</td>\n", - " <td>[{'instructor': 'James Skrentny', 'location': ...</td>\n", - " <td>Computer Science</td>\n", - " </tr>\n", - " <tr>\n", - " <th>12</th>\n", - " <td>4</td>\n", - " <td>Introduction. Stoichiometry and the mole conce...</td>\n", - " <td>[chemistry]</td>\n", - " <td>General Chemistry I</td>\n", - " <td>CHEM_103</td>\n", - " <td>[]</td>\n", - " <td>[{'instructor': 'Unknown', 'location': 'B10 In...</td>\n", - " <td>Chemistry</td>\n", - " </tr>\n", - " <tr>\n", - " <th>13</th>\n", - " <td>3</td>\n", - " <td>This course introduces students to the softwar...</td>\n", - " <td>[computer, science, building, user, interface,...</td>\n", - " <td>Building User Interfaces</td>\n", - " <td>COMPSCI_639</td>\n", - " <td>[[COMPSCI_300]]</td>\n", - " <td>[{'instructor': 'Bilge Mutlu', 'location': '12...</td>\n", - " <td>Computer Science</td>\n", - " </tr>\n", - " <tr>\n", - " <th>14</th>\n", - " <td>3</td>\n", - " <td>Focuses on the role that psychological princip...</td>\n", - " <td>[psychology, science, law, social, policy, beh...</td>\n", - " <td>Psychology, Law, and Social Policy</td>\n", - " <td>PSYCH_401</td>\n", - " <td>[[PSYCH_202]]</td>\n", - " <td>[{'instructor': 'Gregory Van Rybroek', 'locati...</td>\n", - " <td>Psychology</td>\n", - " </tr>\n", - " <tr>\n", - " <th>15</th>\n", - " <td>3</td>\n", - " <td>Basic concepts of logic, sets, partial order a...</td>\n", - " <td>[computer, science, math, mathematics, discret...</td>\n", - " <td>Introduction To Discrete Mathematics</td>\n", - " <td>COMPSCI_240</td>\n", - " <td>[[MATH_221]]</td>\n", - " <td>[{'instructor': 'Beck Hasti', 'location': '105...</td>\n", - " <td>Computer Science</td>\n", - " </tr>\n", - " <tr>\n", - " <th>16</th>\n", - " <td>3</td>\n", - " <td>Graphical and numerical exploration of data; s...</td>\n", - " <td>[statistics, statistical, math, mathematics, m...</td>\n", - " <td>Accelerated Introduction to Statistical Methods</td>\n", - " <td>STATS_302</td>\n", - " <td>[[MATH_221]]</td>\n", - " <td>[{'instructor': 'Unknown', 'location': '331 Se...</td>\n", - " <td>Statistics</td>\n", - " </tr>\n", - " </tbody>\n", - "</table>\n", - "</div>" - ], - "text/plain": [ - " credits description \\\n", - "0 3 Behavior, including its development, motivatio... \n", - "1 4 Input-output hardware, interrupt handling, pro... \n", - "2 3 Introduces students to Object-Oriented Program... \n", - "3 5 Principles and application of chemical equilib... \n", - "4 3 Learn the process of incrementally developing ... \n", - "5 5 The two semester sequence MATH_112-MATH_113 co... \n", - "6 4 The systematic study of the individual in a so... \n", - "7 2 Logic components built with transistors, rudim... \n", - "8 3 The third course in our programming fundamenta... \n", - "9 5 Introduction to differential and integral calc... \n", - "10 3 General biological principles. Topics include:... \n", - "11 3 An introduction to fundamental structures of c... \n", - "12 4 Introduction. Stoichiometry and the mole conce... \n", - "13 3 This course introduces students to the softwar... \n", - "14 3 Focuses on the role that psychological princip... \n", - "15 3 Basic concepts of logic, sets, partial order a... \n", - "16 3 Graphical and numerical exploration of data; s... \n", - "\n", - " keywords \\\n", - "0 [psychology, behavior, emotion, intelligence, ... \n", - "1 [computer, science, operating, system, systems] \n", - "2 [computer, science, programming, java] \n", - "3 [chemistry] \n", - "4 [computer, science, programming, java] \n", - "5 [math, mathematics, algebra, trigonometry] \n", - "6 [psychology, science, social, interaction, beh... \n", - "7 [computer, science, engineering, programming] \n", - "8 [computer, science, programming, java] \n", - "9 [math, mathematics, calculus, analytical, geom... \n", - "10 [biology, science, animal, evolution, genetics... \n", - "11 [computer, science, engineering, electrical, m... \n", - "12 [chemistry] \n", - "13 [computer, science, building, user, interface,... \n", - "14 [psychology, science, law, social, policy, beh... \n", - "15 [computer, science, math, mathematics, discret... \n", - "16 [statistics, statistical, math, mathematics, m... \n", - "\n", - " name number \\\n", - "0 Introduction to Psychology PSYCH_202 \n", - "1 Introduction to Operating Systems COMPSCI_537 \n", - "2 Programming 2 COMPSCI_300 \n", - "3 General Chemistry II CHEM_104 \n", - "4 Programming 1 COMPSCI_200 \n", - "5 Algebra and Trigonometry MATH_114 \n", - "6 Introductory Social Psychology PSYCH_456 \n", - "7 Introduction to Computer Engineering COMPSCI_252 \n", - "8 Programming 3 COMPSCI_400 \n", - "9 Calculus and Analytical Geometry 1 MATH_221 \n", - "10 Animal Biology BIOLOGY_101 \n", - "11 Machine Organization and Programming COMPSCI_354 \n", - "12 General Chemistry I CHEM_103 \n", - "13 Building User Interfaces COMPSCI_639 \n", - "14 Psychology, Law, and Social Policy PSYCH_401 \n", - "15 Introduction To Discrete Mathematics COMPSCI_240 \n", - "16 Accelerated Introduction to Statistical Methods STATS_302 \n", - "\n", - " requisites \\\n", - "0 [] \n", - "1 [[COMPSCI_354, COMPSCI_400]] \n", - "2 [[COMPSCI_200]] \n", - "3 [[MATH_114], [CHEM_103]] \n", - "4 [] \n", - "5 [] \n", - "6 [[PSYCH_202]] \n", - "7 [] \n", - "8 [[COMPSCI_300]] \n", - "9 [[MATH_114]] \n", - "10 [] \n", - "11 [[COMPSCI_252], [COMPSCI_300]] \n", - "12 [] \n", - "13 [[COMPSCI_300]] \n", - "14 [[PSYCH_202]] \n", - "15 [[MATH_221]] \n", - "16 [[MATH_221]] \n", - "\n", - " sections subject \n", - "0 [{'instructor': 'Jeff Henriques', 'location': ... Psychology \n", - "1 [{'instructor': 'Andrea Arpaci-Dusseau', 'loca... Computer Science \n", - "2 [{'instructor': 'Gary Dahl', 'location': 'AB20... Computer Science \n", - "3 [{'instructor': 'Linda Zelewski', 'location': ... Chemistry \n", - "4 [{'instructor': 'Jim Williams', 'location': '1... Computer Science \n", - "5 [{'instructor': 'Sharad Chandarana', 'location... Mathematics \n", - "6 [{'instructor': 'Abigail Letak', 'location': '... Psychology \n", - "7 [{'instructor': 'Joseph Krachey', 'location': ... Computer Science \n", - "8 [{'instructor': 'Gary Dahl', 'location': 'AB20... Computer Science \n", - "9 [{'instructor': 'Laurentiu Maxim', 'location':... Mathematics \n", - "10 [{'instructor': 'Sharon Thoma', 'location': '2... Biology \n", - "11 [{'instructor': 'James Skrentny', 'location': ... Computer Science \n", - "12 [{'instructor': 'Unknown', 'location': 'B10 In... Chemistry \n", - "13 [{'instructor': 'Bilge Mutlu', 'location': '12... Computer Science \n", - "14 [{'instructor': 'Gregory Van Rybroek', 'locati... Psychology \n", - "15 [{'instructor': 'Beck Hasti', 'location': '105... Computer Science \n", - "16 [{'instructor': 'Unknown', 'location': '331 Se... Statistics " - ] - }, - "execution_count": 34, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "all_course_frame = DataFrame(all_class_data)\n", - "all_course_frame" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### We may want to do some \"plumbing\" with our data." - ] - }, - { - "cell_type": "code", - "execution_count": 35, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "<div>\n", - "<style scoped>\n", - " .dataframe tbody tr th:only-of-type {\n", - " vertical-align: middle;\n", - " }\n", - "\n", - " .dataframe tbody tr th {\n", - " vertical-align: top;\n", - " }\n", - "\n", - " .dataframe thead th {\n", - " text-align: right;\n", - " }\n", - "</style>\n", - "<table border=\"1\" class=\"dataframe\">\n", - " <thead>\n", - " <tr style=\"text-align: right;\">\n", - " <th></th>\n", - " <th>credits</th>\n", - " <th>description</th>\n", - " <th>keywords</th>\n", - " <th>name</th>\n", - " <th>number</th>\n", - " <th>subject</th>\n", - " </tr>\n", - " </thead>\n", - " <tbody>\n", - " <tr>\n", - " <th>0</th>\n", - " <td>3</td>\n", - " <td>Behavior, including its development, motivatio...</td>\n", - " <td>[psychology, behavior, emotion, intelligence, ...</td>\n", - " <td>Introduction to Psychology</td>\n", - " <td>PSYCH_202</td>\n", - " <td>Psychology</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1</th>\n", - " <td>4</td>\n", - " <td>Input-output hardware, interrupt handling, pro...</td>\n", - " <td>[computer, science, operating, system, systems]</td>\n", - " <td>Introduction to Operating Systems</td>\n", - " <td>COMPSCI_537</td>\n", - " <td>Computer Science</td>\n", - " </tr>\n", - " <tr>\n", - " <th>2</th>\n", - " <td>3</td>\n", - " <td>Introduces students to Object-Oriented Program...</td>\n", - " <td>[computer, science, programming, java]</td>\n", - " <td>Programming 2</td>\n", - " <td>COMPSCI_300</td>\n", - " <td>Computer Science</td>\n", - " </tr>\n", - " <tr>\n", - " <th>3</th>\n", - " <td>5</td>\n", - " <td>Principles and application of chemical equilib...</td>\n", - " <td>[chemistry]</td>\n", - " <td>General Chemistry II</td>\n", - " <td>CHEM_104</td>\n", - " <td>Chemistry</td>\n", - " </tr>\n", - " <tr>\n", - " <th>4</th>\n", - " <td>3</td>\n", - " <td>Learn the process of incrementally developing ...</td>\n", - " <td>[computer, science, programming, java]</td>\n", - " <td>Programming 1</td>\n", - " <td>COMPSCI_200</td>\n", - " <td>Computer Science</td>\n", - " </tr>\n", - " <tr>\n", - " <th>5</th>\n", - " <td>5</td>\n", - " <td>The two semester sequence MATH_112-MATH_113 co...</td>\n", - " <td>[math, mathematics, algebra, trigonometry]</td>\n", - " <td>Algebra and Trigonometry</td>\n", - " <td>MATH_114</td>\n", - " <td>Mathematics</td>\n", - " </tr>\n", - " <tr>\n", - " <th>6</th>\n", - " <td>4</td>\n", - " <td>The systematic study of the individual in a so...</td>\n", - " <td>[psychology, science, social, interaction, beh...</td>\n", - " <td>Introductory Social Psychology</td>\n", - " <td>PSYCH_456</td>\n", - " <td>Psychology</td>\n", - " </tr>\n", - " <tr>\n", - " <th>7</th>\n", - " <td>2</td>\n", - " <td>Logic components built with transistors, rudim...</td>\n", - " <td>[computer, science, engineering, programming]</td>\n", - " <td>Introduction to Computer Engineering</td>\n", - " <td>COMPSCI_252</td>\n", - " <td>Computer Science</td>\n", - " </tr>\n", - " <tr>\n", - " <th>8</th>\n", - " <td>3</td>\n", - " <td>The third course in our programming fundamenta...</td>\n", - " <td>[computer, science, programming, java]</td>\n", - " <td>Programming 3</td>\n", - " <td>COMPSCI_400</td>\n", - " <td>Computer Science</td>\n", - " </tr>\n", - " <tr>\n", - " <th>9</th>\n", - " <td>5</td>\n", - " <td>Introduction to differential and integral calc...</td>\n", - " <td>[math, mathematics, calculus, analytical, geom...</td>\n", - " <td>Calculus and Analytical Geometry 1</td>\n", - " <td>MATH_221</td>\n", - " <td>Mathematics</td>\n", - " </tr>\n", - " <tr>\n", - " <th>10</th>\n", - " <td>3</td>\n", - " <td>General biological principles. Topics include:...</td>\n", - " <td>[biology, science, animal, evolution, genetics...</td>\n", - " <td>Animal Biology</td>\n", - " <td>BIOLOGY_101</td>\n", - " <td>Biology</td>\n", - " </tr>\n", - " <tr>\n", - " <th>11</th>\n", - " <td>3</td>\n", - " <td>An introduction to fundamental structures of c...</td>\n", - " <td>[computer, science, engineering, electrical, m...</td>\n", - " <td>Machine Organization and Programming</td>\n", - " <td>COMPSCI_354</td>\n", - " <td>Computer Science</td>\n", - " </tr>\n", - " <tr>\n", - " <th>12</th>\n", - " <td>4</td>\n", - " <td>Introduction. Stoichiometry and the mole conce...</td>\n", - " <td>[chemistry]</td>\n", - " <td>General Chemistry I</td>\n", - " <td>CHEM_103</td>\n", - " <td>Chemistry</td>\n", - " </tr>\n", - " <tr>\n", - " <th>13</th>\n", - " <td>3</td>\n", - " <td>This course introduces students to the softwar...</td>\n", - " <td>[computer, science, building, user, interface,...</td>\n", - " <td>Building User Interfaces</td>\n", - " <td>COMPSCI_639</td>\n", - " <td>Computer Science</td>\n", - " </tr>\n", - " <tr>\n", - " <th>14</th>\n", - " <td>3</td>\n", - " <td>Focuses on the role that psychological princip...</td>\n", - " <td>[psychology, science, law, social, policy, beh...</td>\n", - " <td>Psychology, Law, and Social Policy</td>\n", - " <td>PSYCH_401</td>\n", - " <td>Psychology</td>\n", - " </tr>\n", - " <tr>\n", - " <th>15</th>\n", - " <td>3</td>\n", - " <td>Basic concepts of logic, sets, partial order a...</td>\n", - " <td>[computer, science, math, mathematics, discret...</td>\n", - " <td>Introduction To Discrete Mathematics</td>\n", - " <td>COMPSCI_240</td>\n", - " <td>Computer Science</td>\n", - " </tr>\n", - " <tr>\n", - " <th>16</th>\n", - " <td>3</td>\n", - " <td>Graphical and numerical exploration of data; s...</td>\n", - " <td>[statistics, statistical, math, mathematics, m...</td>\n", - " <td>Accelerated Introduction to Statistical Methods</td>\n", - " <td>STATS_302</td>\n", - " <td>Statistics</td>\n", - " </tr>\n", - " </tbody>\n", - "</table>\n", - "</div>" - ], - "text/plain": [ - " credits description \\\n", - "0 3 Behavior, including its development, motivatio... \n", - "1 4 Input-output hardware, interrupt handling, pro... \n", - "2 3 Introduces students to Object-Oriented Program... \n", - "3 5 Principles and application of chemical equilib... \n", - "4 3 Learn the process of incrementally developing ... \n", - "5 5 The two semester sequence MATH_112-MATH_113 co... \n", - "6 4 The systematic study of the individual in a so... \n", - "7 2 Logic components built with transistors, rudim... \n", - "8 3 The third course in our programming fundamenta... \n", - "9 5 Introduction to differential and integral calc... \n", - "10 3 General biological principles. Topics include:... \n", - "11 3 An introduction to fundamental structures of c... \n", - "12 4 Introduction. Stoichiometry and the mole conce... \n", - "13 3 This course introduces students to the softwar... \n", - "14 3 Focuses on the role that psychological princip... \n", - "15 3 Basic concepts of logic, sets, partial order a... \n", - "16 3 Graphical and numerical exploration of data; s... \n", - "\n", - " keywords \\\n", - "0 [psychology, behavior, emotion, intelligence, ... \n", - "1 [computer, science, operating, system, systems] \n", - "2 [computer, science, programming, java] \n", - "3 [chemistry] \n", - "4 [computer, science, programming, java] \n", - "5 [math, mathematics, algebra, trigonometry] \n", - "6 [psychology, science, social, interaction, beh... \n", - "7 [computer, science, engineering, programming] \n", - "8 [computer, science, programming, java] \n", - "9 [math, mathematics, calculus, analytical, geom... \n", - "10 [biology, science, animal, evolution, genetics... \n", - "11 [computer, science, engineering, electrical, m... \n", - "12 [chemistry] \n", - "13 [computer, science, building, user, interface,... \n", - "14 [psychology, science, law, social, policy, beh... \n", - "15 [computer, science, math, mathematics, discret... \n", - "16 [statistics, statistical, math, mathematics, m... \n", - "\n", - " name number \\\n", - "0 Introduction to Psychology PSYCH_202 \n", - "1 Introduction to Operating Systems COMPSCI_537 \n", - "2 Programming 2 COMPSCI_300 \n", - "3 General Chemistry II CHEM_104 \n", - "4 Programming 1 COMPSCI_200 \n", - "5 Algebra and Trigonometry MATH_114 \n", - "6 Introductory Social Psychology PSYCH_456 \n", - "7 Introduction to Computer Engineering COMPSCI_252 \n", - "8 Programming 3 COMPSCI_400 \n", - "9 Calculus and Analytical Geometry 1 MATH_221 \n", - "10 Animal Biology BIOLOGY_101 \n", - "11 Machine Organization and Programming COMPSCI_354 \n", - "12 General Chemistry I CHEM_103 \n", - "13 Building User Interfaces COMPSCI_639 \n", - "14 Psychology, Law, and Social Policy PSYCH_401 \n", - "15 Introduction To Discrete Mathematics COMPSCI_240 \n", - "16 Accelerated Introduction to Statistical Methods STATS_302 \n", - "\n", - " subject \n", - "0 Psychology \n", - "1 Computer Science \n", - "2 Computer Science \n", - "3 Chemistry \n", - "4 Computer Science \n", - "5 Mathematics \n", - "6 Psychology \n", - "7 Computer Science \n", - "8 Computer Science \n", - "9 Mathematics \n", - "10 Biology \n", - "11 Computer Science \n", - "12 Chemistry \n", - "13 Computer Science \n", - "14 Psychology \n", - "15 Computer Science \n", - "16 Statistics " - ] - }, - "execution_count": 35, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Remove the 'sections' and 'requisites' column.\n", - "new_course_frame = all_course_frame.loc[:, \"credits\":\"number\"]\n", - "new_course_frame[\"subject\"] = all_course_frame.loc[:, \"subject\"]\n", - "new_course_frame" - ] - }, - { - "cell_type": "code", - "execution_count": 36, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "<div>\n", - "<style scoped>\n", - " .dataframe tbody tr th:only-of-type {\n", - " vertical-align: middle;\n", - " }\n", - "\n", - " .dataframe tbody tr th {\n", - " vertical-align: top;\n", - " }\n", - "\n", - " .dataframe thead th {\n", - " text-align: right;\n", - " }\n", - "</style>\n", - "<table border=\"1\" class=\"dataframe\">\n", - " <thead>\n", - " <tr style=\"text-align: right;\">\n", - " <th></th>\n", - " <th>credits</th>\n", - " <th>description</th>\n", - " <th>keywords</th>\n", - " <th>name</th>\n", - " <th>number</th>\n", - " <th>subject</th>\n", - " </tr>\n", - " </thead>\n", - " <tbody>\n", - " <tr>\n", - " <th>0</th>\n", - " <td>3</td>\n", - " <td>Behavior, including its development, motivatio...</td>\n", - " <td>psychology, behavior, emotion, intelligence, b...</td>\n", - " <td>Introduction to Psychology</td>\n", - " <td>PSYCH_202</td>\n", - " <td>Psychology</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1</th>\n", - " <td>4</td>\n", - " <td>Input-output hardware, interrupt handling, pro...</td>\n", - " <td>computer, science, operating, system, systems</td>\n", - " <td>Introduction to Operating Systems</td>\n", - " <td>COMPSCI_537</td>\n", - " <td>Computer Science</td>\n", - " </tr>\n", - " <tr>\n", - " <th>2</th>\n", - " <td>3</td>\n", - " <td>Introduces students to Object-Oriented Program...</td>\n", - " <td>computer, science, programming, java</td>\n", - " <td>Programming 2</td>\n", - " <td>COMPSCI_300</td>\n", - " <td>Computer Science</td>\n", - " </tr>\n", - " <tr>\n", - " <th>3</th>\n", - " <td>5</td>\n", - " <td>Principles and application of chemical equilib...</td>\n", - " <td>chemistry</td>\n", - " <td>General Chemistry II</td>\n", - " <td>CHEM_104</td>\n", - " <td>Chemistry</td>\n", - " </tr>\n", - " <tr>\n", - " <th>4</th>\n", - " <td>3</td>\n", - " <td>Learn the process of incrementally developing ...</td>\n", - " <td>computer, science, programming, java</td>\n", - " <td>Programming 1</td>\n", - " <td>COMPSCI_200</td>\n", - " <td>Computer Science</td>\n", - " </tr>\n", - " <tr>\n", - " <th>5</th>\n", - " <td>5</td>\n", - " <td>The two semester sequence MATH_112-MATH_113 co...</td>\n", - " <td>math, mathematics, algebra, trigonometry</td>\n", - " <td>Algebra and Trigonometry</td>\n", - " <td>MATH_114</td>\n", - " <td>Mathematics</td>\n", - " </tr>\n", - " <tr>\n", - " <th>6</th>\n", - " <td>4</td>\n", - " <td>The systematic study of the individual in a so...</td>\n", - " <td>psychology, science, social, interaction, beha...</td>\n", - " <td>Introductory Social Psychology</td>\n", - " <td>PSYCH_456</td>\n", - " <td>Psychology</td>\n", - " </tr>\n", - " <tr>\n", - " <th>7</th>\n", - " <td>2</td>\n", - " <td>Logic components built with transistors, rudim...</td>\n", - " <td>computer, science, engineering, programming</td>\n", - " <td>Introduction to Computer Engineering</td>\n", - " <td>COMPSCI_252</td>\n", - " <td>Computer Science</td>\n", - " </tr>\n", - " <tr>\n", - " <th>8</th>\n", - " <td>3</td>\n", - " <td>The third course in our programming fundamenta...</td>\n", - " <td>computer, science, programming, java</td>\n", - " <td>Programming 3</td>\n", - " <td>COMPSCI_400</td>\n", - " <td>Computer Science</td>\n", - " </tr>\n", - " <tr>\n", - " <th>9</th>\n", - " <td>5</td>\n", - " <td>Introduction to differential and integral calc...</td>\n", - " <td>math, mathematics, calculus, analytical, geome...</td>\n", - " <td>Calculus and Analytical Geometry 1</td>\n", - " <td>MATH_221</td>\n", - " <td>Mathematics</td>\n", - " </tr>\n", - " <tr>\n", - " <th>10</th>\n", - " <td>3</td>\n", - " <td>General biological principles. Topics include:...</td>\n", - " <td>biology, science, animal, evolution, genetics,...</td>\n", - " <td>Animal Biology</td>\n", - " <td>BIOLOGY_101</td>\n", - " <td>Biology</td>\n", - " </tr>\n", - " <tr>\n", - " <th>11</th>\n", - " <td>3</td>\n", - " <td>An introduction to fundamental structures of c...</td>\n", - " <td>computer, science, engineering, electrical, ma...</td>\n", - " <td>Machine Organization and Programming</td>\n", - " <td>COMPSCI_354</td>\n", - " <td>Computer Science</td>\n", - " </tr>\n", - " <tr>\n", - " <th>12</th>\n", - " <td>4</td>\n", - " <td>Introduction. Stoichiometry and the mole conce...</td>\n", - " <td>chemistry</td>\n", - " <td>General Chemistry I</td>\n", - " <td>CHEM_103</td>\n", - " <td>Chemistry</td>\n", - " </tr>\n", - " <tr>\n", - " <th>13</th>\n", - " <td>3</td>\n", - " <td>This course introduces students to the softwar...</td>\n", - " <td>computer, science, building, user, interface, ...</td>\n", - " <td>Building User Interfaces</td>\n", - " <td>COMPSCI_639</td>\n", - " <td>Computer Science</td>\n", - " </tr>\n", - " <tr>\n", - " <th>14</th>\n", - " <td>3</td>\n", - " <td>Focuses on the role that psychological princip...</td>\n", - " <td>psychology, science, law, social, policy, beha...</td>\n", - " <td>Psychology, Law, and Social Policy</td>\n", - " <td>PSYCH_401</td>\n", - " <td>Psychology</td>\n", - " </tr>\n", - " <tr>\n", - " <th>15</th>\n", - " <td>3</td>\n", - " <td>Basic concepts of logic, sets, partial order a...</td>\n", - " <td>computer, science, math, mathematics, discrete...</td>\n", - " <td>Introduction To Discrete Mathematics</td>\n", - " <td>COMPSCI_240</td>\n", - " <td>Computer Science</td>\n", - " </tr>\n", - " <tr>\n", - " <th>16</th>\n", - " <td>3</td>\n", - " <td>Graphical and numerical exploration of data; s...</td>\n", - " <td>statistics, statistical, math, mathematics, me...</td>\n", - " <td>Accelerated Introduction to Statistical Methods</td>\n", - " <td>STATS_302</td>\n", - " <td>Statistics</td>\n", - " </tr>\n", - " </tbody>\n", - "</table>\n", - "</div>" - ], - "text/plain": [ - " credits description \\\n", - "0 3 Behavior, including its development, motivatio... \n", - "1 4 Input-output hardware, interrupt handling, pro... \n", - "2 3 Introduces students to Object-Oriented Program... \n", - "3 5 Principles and application of chemical equilib... \n", - "4 3 Learn the process of incrementally developing ... \n", - "5 5 The two semester sequence MATH_112-MATH_113 co... \n", - "6 4 The systematic study of the individual in a so... \n", - "7 2 Logic components built with transistors, rudim... \n", - "8 3 The third course in our programming fundamenta... \n", - "9 5 Introduction to differential and integral calc... \n", - "10 3 General biological principles. Topics include:... \n", - "11 3 An introduction to fundamental structures of c... \n", - "12 4 Introduction. Stoichiometry and the mole conce... \n", - "13 3 This course introduces students to the softwar... \n", - "14 3 Focuses on the role that psychological princip... \n", - "15 3 Basic concepts of logic, sets, partial order a... \n", - "16 3 Graphical and numerical exploration of data; s... \n", - "\n", - " keywords \\\n", - "0 psychology, behavior, emotion, intelligence, b... \n", - "1 computer, science, operating, system, systems \n", - "2 computer, science, programming, java \n", - "3 chemistry \n", - "4 computer, science, programming, java \n", - "5 math, mathematics, algebra, trigonometry \n", - "6 psychology, science, social, interaction, beha... \n", - "7 computer, science, engineering, programming \n", - "8 computer, science, programming, java \n", - "9 math, mathematics, calculus, analytical, geome... \n", - "10 biology, science, animal, evolution, genetics,... \n", - "11 computer, science, engineering, electrical, ma... \n", - "12 chemistry \n", - "13 computer, science, building, user, interface, ... \n", - "14 psychology, science, law, social, policy, beha... \n", - "15 computer, science, math, mathematics, discrete... \n", - "16 statistics, statistical, math, mathematics, me... \n", - "\n", - " name number \\\n", - "0 Introduction to Psychology PSYCH_202 \n", - "1 Introduction to Operating Systems COMPSCI_537 \n", - "2 Programming 2 COMPSCI_300 \n", - "3 General Chemistry II CHEM_104 \n", - "4 Programming 1 COMPSCI_200 \n", - "5 Algebra and Trigonometry MATH_114 \n", - "6 Introductory Social Psychology PSYCH_456 \n", - "7 Introduction to Computer Engineering COMPSCI_252 \n", - "8 Programming 3 COMPSCI_400 \n", - "9 Calculus and Analytical Geometry 1 MATH_221 \n", - "10 Animal Biology BIOLOGY_101 \n", - "11 Machine Organization and Programming COMPSCI_354 \n", - "12 General Chemistry I CHEM_103 \n", - "13 Building User Interfaces COMPSCI_639 \n", - "14 Psychology, Law, and Social Policy PSYCH_401 \n", - "15 Introduction To Discrete Mathematics COMPSCI_240 \n", - "16 Accelerated Introduction to Statistical Methods STATS_302 \n", - "\n", - " subject \n", - "0 Psychology \n", - "1 Computer Science \n", - "2 Computer Science \n", - "3 Chemistry \n", - "4 Computer Science \n", - "5 Mathematics \n", - "6 Psychology \n", - "7 Computer Science \n", - "8 Computer Science \n", - "9 Mathematics \n", - "10 Biology \n", - "11 Computer Science \n", - "12 Chemistry \n", - "13 Computer Science \n", - "14 Psychology \n", - "15 Computer Science \n", - "16 Statistics " - ] - }, - "execution_count": 36, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Turn 'keywords' into a series of Strings and remove the '[', ']', '''\n", - "new_course_frame[\"keywords\"] = new_course_frame[\"keywords\"].astype('string')\n", - "new_course_frame[\"keywords\"] = new_course_frame[\"keywords\"].str.replace(\"[\", \"\", regex=False)\n", - "new_course_frame[\"keywords\"] = new_course_frame[\"keywords\"].str.replace(\"]\", \"\", regex=False)\n", - "new_course_frame[\"keywords\"] = new_course_frame[\"keywords\"].str.replace(\"'\", \"\", regex=False)\n", - "new_course_frame" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Pandas Operations" - ] - }, - { - "cell_type": "code", - "execution_count": 37, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "5" - ] - }, - "execution_count": 37, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# What is the most number of credits a course offers?\n", - "new_course_frame[\"credits\"].max()" - ] - }, - { - "cell_type": "code", - "execution_count": 38, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "2" - ] - }, - "execution_count": 38, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# What is the least number of credits a course offers?\n", - "new_course_frame[\"credits\"].min()" - ] - }, - { - "cell_type": "code", - "execution_count": 39, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "credits 2\n", - "description Logic components built with transistors, rudim...\n", - "keywords computer, science, engineering, programming\n", - "name Introduction to Computer Engineering\n", - "number COMPSCI_252\n", - "subject Computer Science\n", - "Name: 7, dtype: object" - ] - }, - "execution_count": 39, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# What is the info for that course?\n", - "new_course_frame.iloc[new_course_frame[\"credits\"].idxmin()]" - ] - }, - { - "cell_type": "code", - "execution_count": 40, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "<div>\n", - "<style scoped>\n", - " .dataframe tbody tr th:only-of-type {\n", - " vertical-align: middle;\n", - " }\n", - "\n", - " .dataframe tbody tr th {\n", - " vertical-align: top;\n", - " }\n", - "\n", - " .dataframe thead th {\n", - " text-align: right;\n", - " }\n", - "</style>\n", - "<table border=\"1\" class=\"dataframe\">\n", - " <thead>\n", - " <tr style=\"text-align: right;\">\n", - " <th></th>\n", - " <th>credits</th>\n", - " <th>description</th>\n", - " <th>keywords</th>\n", - " <th>name</th>\n", - " <th>number</th>\n", - " <th>subject</th>\n", - " </tr>\n", - " </thead>\n", - " <tbody>\n", - " <tr>\n", - " <th>2</th>\n", - " <td>3</td>\n", - " <td>Introduces students to Object-Oriented Program...</td>\n", - " <td>computer, science, programming, java</td>\n", - " <td>Programming 2</td>\n", - " <td>COMPSCI_300</td>\n", - " <td>Computer Science</td>\n", - " </tr>\n", - " <tr>\n", - " <th>4</th>\n", - " <td>3</td>\n", - " <td>Learn the process of incrementally developing ...</td>\n", - " <td>computer, science, programming, java</td>\n", - " <td>Programming 1</td>\n", - " <td>COMPSCI_200</td>\n", - " <td>Computer Science</td>\n", - " </tr>\n", - " <tr>\n", - " <th>7</th>\n", - " <td>2</td>\n", - " <td>Logic components built with transistors, rudim...</td>\n", - " <td>computer, science, engineering, programming</td>\n", - " <td>Introduction to Computer Engineering</td>\n", - " <td>COMPSCI_252</td>\n", - " <td>Computer Science</td>\n", - " </tr>\n", - " <tr>\n", - " <th>8</th>\n", - " <td>3</td>\n", - " <td>The third course in our programming fundamenta...</td>\n", - " <td>computer, science, programming, java</td>\n", - " <td>Programming 3</td>\n", - " <td>COMPSCI_400</td>\n", - " <td>Computer Science</td>\n", - " </tr>\n", - " <tr>\n", - " <th>11</th>\n", - " <td>3</td>\n", - " <td>An introduction to fundamental structures of c...</td>\n", - " <td>computer, science, engineering, electrical, ma...</td>\n", - " <td>Machine Organization and Programming</td>\n", - " <td>COMPSCI_354</td>\n", - " <td>Computer Science</td>\n", - " </tr>\n", - " </tbody>\n", - "</table>\n", - "</div>" - ], - "text/plain": [ - " credits description \\\n", - "2 3 Introduces students to Object-Oriented Program... \n", - "4 3 Learn the process of incrementally developing ... \n", - "7 2 Logic components built with transistors, rudim... \n", - "8 3 The third course in our programming fundamenta... \n", - "11 3 An introduction to fundamental structures of c... \n", - "\n", - " keywords \\\n", - "2 computer, science, programming, java \n", - "4 computer, science, programming, java \n", - "7 computer, science, engineering, programming \n", - "8 computer, science, programming, java \n", - "11 computer, science, engineering, electrical, ma... \n", - "\n", - " name number subject \n", - "2 Programming 2 COMPSCI_300 Computer Science \n", - "4 Programming 1 COMPSCI_200 Computer Science \n", - "7 Introduction to Computer Engineering COMPSCI_252 Computer Science \n", - "8 Programming 3 COMPSCI_400 Computer Science \n", - "11 Machine Organization and Programming COMPSCI_354 Computer Science " - ] - }, - "execution_count": 40, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# What courses contain the keyword \"programming\"?\n", - "mask = new_course_frame[\"keywords\"].str.contains(\"programming\")\n", - "new_course_frame[mask]" - ] - }, - { - "cell_type": "code", - "execution_count": 41, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'Psychology, Law, and Social Policy'" - ] - }, - "execution_count": 41, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# What course has the most lengthy description?\n", - "idx_max_desc = new_course_frame[\"description\"].str.len().idxmax()\n", - "new_course_frame.iloc[idx_max_desc]['name']" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Write it out to a CSV file on your drive\n", - "You now have your own copy!" - ] - }, - { - "cell_type": "code", - "execution_count": 42, - "metadata": {}, - "outputs": [], - "source": [ - "# Write it all out to a single CSV file\n", - "new_course_frame.to_csv(\"my_course_data.csv\", index=False)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Other Cool APIs" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "- City of Madison Transit: http://transitdata.cityofmadison.com/\n", - "- Reddit: https://reddit.com/r/UWMadison.json\n", - "- Lord of the Rings: https://the-one-api.dev/\n", - "- Pokemon: https://pokeapi.co/\n", - "\n", - "Remember: Be judicious when making requests; don't overwhelm the server! :)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Next Time\n", - "What other documents can we get via the Web? HTML is very popular! We'll explore this." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "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.9.7" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/f22/meena_lec_notes/lec-29/.ipynb_checkpoints/lec_29_web1_template-checkpoint.ipynb b/f22/meena_lec_notes/lec-29/.ipynb_checkpoints/lec_29_web1_template-checkpoint.ipynb deleted file mode 100644 index b51ca54..0000000 --- a/f22/meena_lec_notes/lec-29/.ipynb_checkpoints/lec_29_web1_template-checkpoint.ipynb +++ /dev/null @@ -1,767 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Web 1 - How to get data from the Internet" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# New module\n", - "import requests\n", - "\n", - "# Known modules\n", - "import json\n", - "import pandas as pd\n", - "from pandas import Series, DataFrame" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### P10 check-in" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# It is very important to check auto-grader test results on p10 in a timely manner.\n", - "# Take a few minutes to verify if you hardcoded the slashes in P10 rather than using os.path.join? \n", - " # Your code won't clear auto-grader if you hardcode either \"/\" or \"\\\" \n", - " # for *ANY* relative path in the entire project\n", - "# Check your code and check the autograder as soon as possible." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Warmup 1: Read the data from \"IMDB-Movie-Data.csv\" into a pandas DataFrame called \"movies\"" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Warmup 2: fixing duplicate index columns\n", - "\n", - "Notice that there are two index columns\n", - "- That happened because when you write a csv from pandas to a file, it writes a new index column\n", - "- So if the DataFrame already contains an index, you are going to get two index columns\n", - "- Let's fix that problem" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "#use slicing to retain all the rows and columns excepting for column with integer position 0\n", - "movies = movies.iloc[:, 1:] \n", - "movies" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "movies.to_csv(\"better_movies.csv\", index = False)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Warmup 3: Which movie has highest rating?" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Warmup 4: Which movies were released in 2020?" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Warmup 5a: What does this function do?" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "def format_revenue(revenue):\n", - " if type(revenue) == float: # need this in here if we run code multiple times\n", - " return revenue\n", - " elif revenue[-1] == 'M': # some have an \"M\" at the end\n", - " return float(revenue[:-1]) * 1e6\n", - " else: # otherwise, assume millions.\n", - " return float(revenue) * 1e6" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Warmup 5b: Using the above function, create a new column called \"Revenue in dollars\" by applying appropriate conversion to Revenue column." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Warmup 6: What are the top 10 highest-revenue movies?" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Warmup 7: Which shortest movies (below average runtime) have highest rating?" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Learning Objectives\n", - "\n", - "- Make a request for data using requests.get(URL)\n", - "- Check the status of a request/response\n", - "- Extract the text of a response\n", - "- Create a json file from a response\n", - "- State and practice good etiquette when getting data" - ] - }, - { - "attachments": { - "Client_server.png": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAABSIAAAJQCAYAAACaZRpjAAAMa2lDQ1BJQ0MgUHJvZmlsZQAASImVVwdYU8kWnluSkJDQAhGQEnoTRHqREkKLICBVsBGSQEKJMSGI2NFFBXtBFCu6KqLoWgBZVMReFsXeF2VRWVkXdVEUlTcpoOu+8r3zfXPnv2fO/KfcmXvvAKDdx5VIclEdAPLE+dL4iBDm+NQ0JukZQAEOKMAZ6HB5MgkrLi4aQBns/y7vbgNE0d9wVnD9c/y/ih5fIOMBgEyEOIMv4+VB3AwAvoknkeYDQFTorabnSxR4HsT6UhggxGsVOEuF9yhwhgo3KW0S49kQXwNAg8rlSrMA0HoI9cwCXhbk0foEsauYLxIDoD0C4kCekMuHWBH7iLy8qQpcAbE9tJdADOMBPhnfcGb9jT9jiJ/LzRrCqryUohEqkklyuTP+z9L8b8nLlQ/6sIWNKpRGxivyhzW8mzM1SoGpEHeLM2JiFbWGuE/EV9UdAJQilEcmqexRE56MDesHGBC78rmhURCbQBwuzo2JVuszMkXhHIjhakELRfmcRIgNIV4skIUlqG22SafGq32hdZlSNkutv8CVKv0qfD2W5ySx1PxvhAKOmh/TKhImpkBMgdi6QJQcA7EWxC6ynIQotc3oIiE7ZtBGKo9XxG8NcbxAHBGi4scKMqXh8Wr70jzZYL7YNqGIE6PGh/KFiZGq+mBneFxl/DAX7JpAzEoa5BHIxkcP5sIXhIapcsdeCMRJCWqePkl+SLxqLk6R5Map7XFLQW6EQm8JsYesIEE9F0/Oh4tTxY9nSvLjElVx4kXZ3DFxqnjwlSAasEEoYAI5bBlgKsgGotbu+m54pxoJB1wgBVlAAHeoSjM4I0U5IobXBFAE/oBIAGRD80KUowJQAPWfh7SqqzPIVI4WKGfkgGcQ54EokAvv5cpZ4iFvyeA3qBH9wzsXNh6MNxc2xfi/1w9qv2pYUBOt1sgHPTK1By2JYcRQYiQxnOiAG+OBuD8eDa/BsLnhPrjvYB5f7QnPCG2Ep4RbhHbCvSmiYul3UY4F7ZA/XF2LjG9rgdtCTk88BA+A7JAZZ+DGwBn3gH5YeBD07Am1bHXciqowv+P+WwbfPA21HdmVjJKHkYPJ9t/P1HLU8hxiUdT62/qoYs0Yqjd7aOR7/+xvqs+HfdT3lthi7DB2HjuFXcSasHrAxE5iDdgV7LgCD62u35Sra9BbvDKeHMgj+oc/rtqnopIy1xrXLtdPqrF8QWG+YuOxp0pmSEVZwnwmC34dBEyOmOcygunm6uYGgOJbo3p9vWUovyEI49JXXfEyAAI8BgYGmr7qorUBOAL3DKXjq87eD74mCgG4sJwnlxaodLjiQoBvCW2404yAGbAC9jAfN+AF/EEwCANjQCxIBKlgMqyyEK5zKZgOZoH5oASUgZVgHdgItoIdYA/YDw6BetAEToFz4DK4Bm6BB3D1dIKXoAe8A/0IgpAQGkJHjBBzxAZxQtwQHyQQCUOikXgkFUlHshAxIkdmIQuQMmQ1shHZjlQjPyHHkFPIRaQNuYc8QbqQN8hHFEOpqD5qitqiI1EflIVGoYnoJDQLnYYWoQvR5WgFWoXuQ+vQU+hl9Bbajr5EezGAaWIMzAJzxnwwNhaLpWGZmBSbg5Vi5VgVVos1wud8A2vHurEPOBGn40zcGa7gSDwJ5+HT8Dn4Unwjvgevw8/gN/AneA/+hUAjmBCcCH4EDmE8IYswnVBCKCfsIhwlnIV7qZPwjkgkMoh2RG+4F1OJ2cSZxKXEzcQDxGZiG7GD2EsikYxITqQAUiyJS8onlZA2kPaRTpKukzpJfRqaGuYabhrhGmkaYo1ijXKNvRonNK5rPNfoJ+uQbch+5FgynzyDvIK8k9xIvkruJPdTdCl2lABKIiWbMp9SQamlnKU8pLzV1NS01PTVHKcp0pynWaF5UPOC5hPND1Q9qiOVTZ1IlVOXU3dTm6n3qG9pNJotLZiWRsunLadV007THtP6tOhaLlocLb7WXK1KrTqt61qvtMnaNtos7cnaRdrl2oe1r2p365B1bHXYOlydOTqVOsd07uj06tJ1R+nG6ubpLtXdq3tR94UeSc9WL0yPr7dQb4feab0OOka3orPpPPoC+k76WXqnPlHfTp+jn61fpr9fv1W/x0DPwMMg2aDQoNLguEE7A2PYMjiMXMYKxiHGbcbHYabDWMMEw5YMqx12fdh7w+GGwYYCw1LDA4a3DD8aMY3CjHKMVhnVGz0yxo0djccZTzfeYnzWuHu4/nD/4bzhpcMPDb9vgpo4msSbzDTZYXLFpNfUzDTCVGK6wfS0abcZwyzYLNtsrdkJsy5zunmguch8rflJ89+ZBkwWM5dZwTzD7LEwsYi0kFtst2i16Le0s0yyLLY8YPnIimLlY5VptdaqxarH2tx6rPUs6xrr+zZkGx8boc16m/M2723tbFNsF9nW276wM7Tj2BXZ1dg9tKfZB9lPs6+yv+lAdPBxyHHY7HDNEXX0dBQ6VjpedUKdvJxETpud2kYQRviOEI+oGnHHmerMci5wrnF+4sJwiXYpdql3eTXSemTayFUjz4/84urpmuu60/XBKL1RY0YVj2oc9cbN0Y3nVul2053mHu4+173B/bWHk4fAY4vHXU+651jPRZ4tnp+9vL2kXrVeXd7W3unem7zv+Oj7xPks9bngS/AN8Z3r2+T7wc/LL9/vkN+f/s7+Of57/V+MthstGL1zdEeAZQA3YHtAeyAzMD1wW2B7kEUQN6gq6GmwVTA/eFfwc5YDK5u1j/UqxDVEGnI05D3bjz2b3RyKhUaEloa2humFJYVtDHscbhmeFV4T3hPhGTEzojmSEBkVuSryDseUw+NUc3rGeI+ZPeZMFDUqIWpj1NNox2hpdONYdOyYsWvGPoyxiRHH1MeCWE7smthHcXZx0+J+HkccFzeuctyz+FHxs+LPJ9ATpiTsTXiXGJK4IvFBkn2SPKklWTt5YnJ18vuU0JTVKe3jR46fPf5yqnGqKLUhjZSWnLYrrXdC2IR1Ezonek4smXh7kt2kwkkXJxtPzp18fIr2FO6Uw+mE9JT0vemfuLHcKm5vBidjU0YPj81bz3vJD+av5XcJAgSrBc8zAzJXZ77ICshak9UlDBKWC7tFbNFG0evsyOyt2e9zYnN25wzkpuQeyNPIS887JtYT54jPTDWbWji1TeIkKZG0T/Obtm5ajzRKukuGyCbJGvL14U/9Fbm9/Af5k4LAgsqCvunJ0w8X6haKC6/McJyxZMbzovCiH2fiM3kzW2ZZzJo/68ls1uztc5A5GXNa5lrNXTi3c17EvD3zKfNz5v9S7Fq8uvivBSkLGheaLpy3sOOHiB9qSrRKpCV3Fvkv2roYXyxa3LrEfcmGJV9K+aWXylzLyss+LeUtvbRs1LKKZQPLM5e3rvBasWUlcaV45e1VQav2rNZdXbS6Y83YNXVrmWtL1/61bsq6i+Ue5VvXU9bL17dXRFc0bLDesHLDp43CjbcqQyoPbDLZtGTT+838zde3BG+p3Wq6tWzrx22ibXe3R2yvq7KtKt9B3FGw49nO5J3nf/T5sXqX8a6yXZ93i3e374nfc6bau7p6r8neFTVojbyma9/Efdf2h+5vqHWu3X6AcaDsIDgoP/j7T+k/3T4UdajlsM/h2iM2RzYdpR8trUPqZtT11Avr2xtSG9qOjTnW0ujfePRnl593N1k0VR43OL7iBOXEwhMDJ4tO9jZLmrtPZZ3qaJnS8uD0+NM3z4w703o26uyFc+HnTp9nnT95IeBC00W/i8cu+Vyqv+x1ue6K55Wjv3j+crTVq7XuqvfVhmu+1xrbRreduB50/dSN0BvnbnJuXr4Vc6vtdtLtu3cm3mm/y7/74l7uvdf3C+73P5j3kPCw9JHOo/LHJo+rfnX49UC7V/vxJ6FPrjxNePqgg9fx8jfZb586Fz6jPSt/bv68+oXbi6au8K5rv0/4vfOl5GV/d8kfun9semX/6sifwX9e6Rnf0/la+nrgzdK3Rm93/+XxV0tvXO/jd3nv+t+X9hn17fng8+H8x5SPz/unfyJ9qvjs8LnxS9SXhwN5AwMSrpSr/BXAYEMzMwF4sxsAWioAdHhuo0xQnQWVgqjOr0oE/hNWnReV4gVALewUv/HsZgAOwmYLG20eAIpf+MRggLq7DzW1yDLd3VRcVHgSIvQNDLw1BYDUCMBn6cBA/+aBgc87YbD3AGiepjqDKoQIzwzblBzXGYXzwHeiOp9+k+P3PVBE4AG+7/8FlTiO10mPo7EAAACKZVhJZk1NACoAAAAIAAQBGgAFAAAAAQAAAD4BGwAFAAAAAQAAAEYBKAADAAAAAQACAACHaQAEAAAAAQAAAE4AAAAAAAAAkAAAAAEAAACQAAAAAQADkoYABwAAABIAAAB4oAIABAAAAAEAAAUioAMABAAAAAEAAAJQAAAAAEFTQ0lJAAAAU2NyZWVuc2hvdHZ0poQAAAAJcEhZcwAAFiUAABYlAUlSJPAAAAHXaVRYdFhNTDpjb20uYWRvYmUueG1wAAAAAAA8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJYTVAgQ29yZSA2LjAuMCI+CiAgIDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+CiAgICAgIDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiCiAgICAgICAgICAgIHhtbG5zOmV4aWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vZXhpZi8xLjAvIj4KICAgICAgICAgPGV4aWY6UGl4ZWxZRGltZW5zaW9uPjU5MjwvZXhpZjpQaXhlbFlEaW1lbnNpb24+CiAgICAgICAgIDxleGlmOlBpeGVsWERpbWVuc2lvbj4xMzE0PC9leGlmOlBpeGVsWERpbWVuc2lvbj4KICAgICAgICAgPGV4aWY6VXNlckNvbW1lbnQ+U2NyZWVuc2hvdDwvZXhpZjpVc2VyQ29tbWVudD4KICAgICAgPC9yZGY6RGVzY3JpcHRpb24+CiAgIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+CtqejFIAAAAcaURPVAAAAAIAAAAAAAABKAAAACgAAAEoAAABKAAAQx+mtpFGAABAAElEQVR4AezdCZgkRYEv8OiZYRguQVEQueTc5VI5lBV0YcGncu0CisKDVRHR1QURP3UVXVgQL56+p4DKtyCKgg93HuKK8JZbn6AsKsixoHKoIPcpwtzd+TJqrKuru6en64yoX33f0FVZmRkRv8gkvvh/mZUjRfkKXgQIECBAgAABAgQIECBAgAABAgQIEOiiwIggsou6dk2AAAECBAgQIECAAAECBAgQIECAQEVAEOlAIECAAAECBAgQIECAAAECBAgQIECg6wKCyK4TK4AAAQIECBAgQIAAAQIECBAgQIAAAUGkY4AAAQIECBAgQIAAAQIECBAgQIAAga4LCCK7TqwAAgQIECBAgAABAgQIECBAgAABAgQEkY4BAgQIECBAgAABAgQIECBAgAABAgS6LiCI7DqxAggQIECAAAECBAgQIECAAAECBAgQEEQ6BggQIECAAAECBAgQIECAAAECBAgQ6LqAILLrxAogQIAAAQIECBAgQIAAAQIECBAgQEAQ6RggQIAAAQIECBAgQIAAAQIECBAgQKDrAoLIrhMrgAABAgQIECBAgAABAgQIECBAgAABQaRjgAABAgQIECBAgAABAgQIECBAgACBrgsIIrtOrAACBAgQIECAAAECBAgQIECAAAECBASRjgECBAgQIECAAAECBAgQIECAAAECBLouIIjsOrECCBAgQIAAAQIECBAgQIAAAQIECBAQRDoGCBAgQIAAAQIECBAgQIAAAQIECBDouoAgsuvECiBAgAABAgQIECBAgAABAgQIECBAQBDpGCBAgAABAgQIECBAgAABAgQIECBAoOsCgsiuEyuAAAECBAgQIECAAAECBAgQIECAAAFBpGOAAAECBAgQIECAAAECBAgQIECAAIGuCwgiu06sAAIECBAgQIAAAQIECBAgQIAAAQIEBJGOAQIECBAgQIAAAQIECBAgQIAAAQIEui4giOw6sQIIECBAgAABAgQIECBAgAABAgQIEBBEOgYIECBAgAABAgQIECBAgAABAgQIEOi6gCCy68QKIECAAAECBAgQIECAAAECBAgQIEBAEOkYIECAAAECBAgQIECAAAECBAgQIECg6wKCyK4TK4AAAQIECBAgQIAAAQIECBAgQIAAAUGkY4AAAQIECBAgQIAAAQIECBAgQIAAga4LCCK7TqwAAgQIECBAgAABAgQIECBAgAABAgQEkY4BAgQIECBAgAABAgQIECBAgAABAgS6LiCI7DqxAggQIECAAAECBAgQIECAAAECBAgQEEQ6BggQIECAAAECBAgQIECAAAECBAgQ6LqAILLrxAogQIAAAQIECBAgQIAAAQIECBAgQEAQ6RggQIAAAQIECBAgQIAAAQIECBAgQKDrAoLIrhMrgAABAgQIECBAgAABAgQIECBAgAABQaRjgAABAgQIECBAgAABAgQIECBAgACBrgsIIrtOrAACBAgQIECAAAECBAgQIECAAAECBASRjgECBAgQIECAAAECBAgQ6LjAqaeeGh588MHKfl//+teHAw88sONl2CGBVAWOP3VJWLxkee0P/7s5YfedZ6XaFPUmsFICgsiV4rIyAQIECBAgQIAAAQIECExHYMsttwz33HNPZdVjjz02nH766dPZLNt1FixYEFZfffVs26dhKycwe6sFYWxs+TannzQ3HPu2OSu3A2sTSFRAEJlox6k2AQIECBAgQIAAAQIEBllAEFnvnWOOOSacffbZYbPNNgvz588PO+ywQ/1L74ZSQBA5lN2u0aWAINJhQIAAAQIECBAgQIAAAQIdFxBELif91a9+FbbZZpua71FHHRXOOeec2mdvhlNAEDmc/a7VgkjHAAECBAgQIECAAAECBAh0QUAQuRz14YcfDptssklYunRpZcFHP/rR8JnPfKYL4naZkoAgMqXeUtdOCrgispOa9kWAAAECBAgQIECAAAECFQFBZP1A+MY3vhG++MUv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Ksp2hbDJS0bC2mvVb7XuVruefqYIf3i4qJS18Qb18mIdbi5v641/t996Vlitfsdwt6rSst/xt2bH28BfveOsUD6IJTzyeAjbbjUS1l2nXueWHcxgwcr2Q1z/Z7eOha03GwnrPG96dVlY3tn+63vHwjPPFmH9F46EDV88K6y5+vQqWx56lfbHY2Wrl84K8TZ1LwKTCQgiJ5OxnAABAgQIECBAgAABAgQIECDQIDBREDnR71E2bOItAQINAoLIBgxvCRAgQIAAAQIECBAgQIDAsAmMbLFg2JqsvUMiUNwzzcs6h8RjEJopiByEXlAHAgQIECBAgAABAgQIECDQJwFBZJ/gFdt1AUFk14lXugBB5EqT2YAAAQIECBAgQIAAAQIECOQjIIjMpy+1pFlAENnsMQifBJGD0AvqQIAAAQIECBAgQIAAAQIECAy8gN+IHPguUsEBFxBEDngHqR4BAgQIECBAgAABAgQIECAwGAKCyMHoB7VIV0AQmW7fqTkBAgQIECBAgAABAgQIECDQQ4FbfzUWjj5hSa3E8/7H3PCXW8yqffaGAIGpBQSRU/v4lgABAgQIECBAgAABAgQIECBAgACBDggIIjuAaBcECBAgQIAAAQIECBAgQIAAAQIECEwtIIic2se3BAgQIECAAAECBAgQIECAAAECBAh0QEAQ2QFEuyBAgAABAgQIECBAgAABAgQIECBAYGoBQeTUPr4lQIAAAQIECBAgQIAAAQIECBAgQKADAoLIDiDaBQECBAgQIECAAAECBAgQIECAAAECUwsIIqf28S0BAgQIECBAgAABAgQIECBAgAABAh0QEER2ANEuCBAgQIAAAQIECBAgQIAAAQIECBCYWkAQObWPbwkQIECAAAECBAgQIECAAAECBAgQ6ICAILIDiHZBgAABAgQIECBAgAABAgQIECBAgMDUAoLIqX18S4AAAQIECBAgQIAAAQIECBAgQIBABwQEkR1AtAsCBAgQIECAAAECBAgQIECAAAECBKYWEERO7eNbAgQIECBAgAABAgQIECBAgAABAgQ6ICCI7ACiXRAgQIAAAQIECBAgQIAAAQIECBAgMLWAIHJqH98SIECAAAECBAgQIECAAAECBAgQINABAUFkBxDtggABAgQIECBAgAABAgQIECBAgACBqQUEkVP7+JYAAQIECBAgQIAAAQIECBAgQIAA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kAAJFJiA6+8dCpEFfiBYHAmQAAmQAAmQAAmQAAmQQMMh4PqAsOHcKbaUBEiABMqDgOvvHQqR5fEcshUkQAIkQAIkQAIkQAIkQAL1QMD1AWE9IOMlSYAESIAE8iDg+nuHQmQeN59ZSYAESIAESIAESIAESIAEGjYB1weEDfvusfUkQAIk4B4B1987FCLde+ZYYxIgARIgARIgARIgARIggRIh4PqAsEQwshokQAIkQAIJCbj+3qEQmfBGMxkJkAAJkAAJkAAJkAAJkAAJhAm4PiAMt4fHJEACJEACpU3A9fcOhcjSfr5YOxIgARIgARIgARIgARIggRIm4PqAsITRsmokQAIkQAIRBFx/71CIjLipjCIBEiABEiABEiABEiABEiCBJARcHxAmaSPTkAAJkAAJlA4B1987FCJL51liTUigwRGYO3euPP7445Ht3n777aVbt26R5xhJAiRAAiRAAiRAAqVCwPUBYalwZD1IgARIgASSEXD9vUMhMtl9ZioSKCqBJUuWyKOPPip9+vSRNm3aFPVapVT4a6+9Jn379o2s0g033CAnnHBC5DlGkgAJkAAJkAAJkECpEHB9QFgqHFkPEiABEiCBZARcf+9QiEx2n5mKBIpGACLkoYceKvfcc4+8+OKLstNOOxXtWqVWMIXIUrsjrA8JkAAJkAAJkEC2BFwfEGbbXqYnARIgARKoXwKuv3coRNbv88OrN3ACnufJEUccISNGjNAkKETWPhC0iKxlwT0SIAESIAESIIHSJeD6gLB0ybJmJEACJEACUQRcf+9QiIy6q4wjgTogABHy6KOPlttvv92/GoVIH4VQiKxlwT0SIAESIAESIIHSJeD6gLB0ybJmJEACJEACUQRcf+9QiIy6q4wjgTogcPzxx8vNN98cuBKFyFocFCJrWXCPBEiABEiABEigdAm4PiAsXbKsGQmQAAmQQBQB1987FCKj7mqJx8GS7r333pNPPvlE5syZIz/99JM0adJElltuOVlllVVkm222ke7du2dsxXfffSdffPGFTJkyRaZOnSrNmjXTXoqRF96KW7VqFVvGL7/8Iu+++25KmkaNGsmOO+4olZWVgvUPcY3x48fLhAkTBH8wnTp1kgEDBshaa62Vkhdte+ONN2TcuHEye/ZsXUbHjh2ld+/estFGG6WkR8S8efNkzJgxKedwfay3+Ndff2lW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RA77CVE+AQIECBAgQIAAAQJjK1D3F8KxbRgVI0CAwJgK1P13RyByTB9M1SJAgAABAgQIECBAYPgCvV4Ih39lVyBAgAABAg8JNBqNhw5G+JNA5Ag3jlsjQIAAAQIECBAgQGC0BQQiR7t93B0BAgQmRUAgclJaWj0JECBAgAABAgQIEJhYAYHIiW16FSdAgMBICQhEjlRzuBkCBAgQIECAAAECBAjMvoBA5OybKpEAAQIEpi4gEDl1M2cQIECAAAECBAgQIECgVgICkbVqLjdLgACBsRUQiBzbplUxAgQIECBAgAABAgQI/L+AQKQngQABAgRGQUAgchRawT0QIECAAAECBAgQIECAAAECBAgQIDASAlbNHolmcBMECBAgQIAAAQIECBAgQIAAAQIExltAIHK821ftCBAgQIAAAQIECBAgQIAAAQIECIyEgEDkSDSDmyBAgAABAgQIECBAgAABAgQIECAw3gICkePdvmpHgAABAgQIECBAgAABAgQIECBAYCQEBCJHohncBAECBAgQIECAAAECBAgQIECAAIHxFhCIHO/2VTsCBAgQIECAAAECBAgQIECAAAECIyEgEDkSzeAmCBAgQIAAAQIECBAgQIAAAQIECIy3gEDkeLev2hEgQIAAAQIECBAgQIAAAQIECBAYCQGByJFoBjdBgAABAgQIECBAgAABAgQIECBAYLwFBCLHu33VjgABAgQIECBAgAABAgQIECBAgMBICAhEjkQzuAkCBAgQIECAAAECBAgQIECAAAEC4y0gEDne7at2BAgQIECAAAECBAgQIECAAAECBEZCQCByJJrBTRAgQIAAAQIECBAgQIAAAQIECBAYbwGByPFuX7UjQIAAAQIECBAgQIAAAQIECBAgMBICApEj0QxuggABAgQIECBAgAABAgQIECBAgMB4CwhEjnf7qh0BAgQIECBAgAABAgQIECBAgACBkRAQiByJZnATBAgQIECAAAECBAgQIECAAAECBMZbQCByvNtX7QgQIECAAAECBAgQIECAAAECBAiMhIBA5Eg0g5sgQIAAAQIECBAgQIAAAQIECBAgMN4CApHj3b5qR4AAAQIECBAgQIAAAQIECBAgQGAkBAQiR6IZ3AQBAgQIECBAgAABAgQIECBAgACB8RYQiBzv9lU7AgQIECBAgAABAgQIECBAYMIFli1bls4///x02WWXpRtvvDHdeuutaa211krz589PixYtSgsXLkwPf/jDJ1xJ9f8XAgKR/wtl1yBAgAABAgQIECBAgAABAgRGQuDBBx9MZ511Vtpll13SuuuuOxL3NKybiIDjBz7wgXTKKaekCEb22jbbbLP03e9+Nz3+8Y/vlUU6gVkREIicFUaFECBAgAABAgQIECBAgAABAqMuEEHI/fffP51++unp3HPPTc95znNG/ZandX+NRiOdfPLJafHixemuu+4aqIwIyp5zzjlpu+22Gyi/TASmIyAQOR015xAgQIAAAQIECBAgQIAAAQK1Eojg3AEHHJBOPfXU4r7HORD5j3/8I6255ppTbp+5c+cWQ7if9rSnTflcJxAYREAgchAleQgQIECAAAECBAgQIECAAIHaCkQQ8uCDDy6GKJeVEIgsJdr3z33uc4ueke2pjgjMjoBA5Ow4KoUAAQIECBAgQIAAAQIECBAYUYE3vvGN6aSTTmq7u0kMRK622mrpvvvuSw888ECbRevBwx72sLR06dK03nrrtSb7TGBWBAQiZ4VRIQQIECBAgAABAgQIECAwjgLRk+7iiy9OV1xxRRGcue2229Iqq6yS1lhjjbTxxhunnXbaKT3hCU9YbtX/+te/pt/97nfpmmuuSX/4wx/SqquumrbYYovi3NjHCsb9tjvvvDNddNFFXVlipePddtstrbTSSinmP4xrLFmyJP3yl79MEVDaaKON0h577FG5CEnU7cILLyxWUr7pppuKMjbccMNiBeVtttmm61qRcPvtt6dLLrmk67u4fsy3+O9//7uwuvLKK9PVV19d1POxj31scQ9xL1XbddddV7h0fhcmO+64Y2dyuuGGG1KU37mtvvrqaeedd+5MTm9605vSiSee2JV+7LHHpqc+9alt6XPmzClWkW5L7Dj4xS9+UVz/lltuSfH3iEc8onCOuRV32GGHwr3jlOJweXbRXtEm3/ve99Kll16a/v73vxfPR7TvpptuWlVkz7TWodnz5s1LRx11VNp1113TtttuWwQi3/nOd6aPfOQjPc//2c9+lgzP7snji5kI5IfcRoAAAQIECBAgQIAAAQIECLQI5IBa493vfndjgw02aOR37r5/m2++eSMHjlrOfujjmWee2cgBuL7nR/k5iNXIAb6HTuz4lFc07llGXhm5ccEFF/S91xe/+MWNHMxslvqTn/yksckmm/QsMw/Pbdx7773N/OWHb3zjGz3P+cIXvtBYf/31K7/PAdPGC17wgsaNN95YFtXcv/Wtb608J6/g3MzT+uGDH/xgZf682EprtuLzkUceWZm3V5vGfVZt5fOQA4J9y5s/f37j05/+dFURjX52//znPwubhQsXdpW/8sorNw4//PDKMnsl5gVqinIWLFjQyIHeymx77bVX17VKl29+85uV50gkMFOBiLbbCBAgQIAAAQIECBAgQIAAgf8K5F6LjQgulkGZQfadgZvcM7GRe6BNqYzcI66RF1Np5J5zXW3RLxB52GGHNXKPxOVeK4KdeUhu4zOf+Uwj9/xbbv5999236z76BdMGcVpnnXUaP/3pT9vKHVYg8phjjlluHTvvuSoQmXuXNrbccssplRWB3Ahetm797P7yl780cs/antd4ylOe0lrUcj/HtXNP0MayZct65o1ntrP+5XG/oHjPAn1BYAABQ7PzvzIbAQIECBAgQIAAAQIECBAIgdxjrxiuG0Opp7LloE560YteVJySe6OlrbbaqihrKmWUeRctWpTOO++88rDYn3POOcXw5rbEaRw86UlPSlddddXAZ55wwgnpiCOOaOaPeubelc3j6Xx41KMelS6//PKUe5sWpx999NHpwx/+cFdRuUdkMdS884sPfehDKQcZO5NT7hGZ/va3vxXp733ve9O73vWurjzLS4ih7v/5z3+a2f785z8Xw5ljWPVUt1e+8pXp9NNPb57Wzy6Gz+dgczNv54eY3/KQQw7pTJ7R8fnnn18M668qJKYCmM6q21VlSSPQKiAQ2arhMwECBAgQIECAAAECBAhMtMCBBx6Yco/BKRu0BiJf+9rXplNPPXXKZbSeEPeQe0c2k2YrENkscMAPnUHRfsG0AYsssr3iFa9IX/7yl4vPwwhEPvnJTy7mqpzKPUXe1kBk7txVBKVjTsiqLebEfOITn5h++9vfFvM6VuX51re+lfIQ6OKr6drFvJU333wHvpSNAAAP60lEQVRzWnvttasuMe20T3ziE+nQQw/tOj8PLy/m4ez6QgKBWRAQiJwFREUQIECAAAECBAgQIECAQP0Fovfb4x73uHT//fdXViYWE3nGM56R8rDtdMcddxS99WJBltjKQGSeqzE9+9nPrjw/EqM34fOf//yUh8ymz33uc8XCMlWZozfatddeW/Tyi+8HCURGYCwWTInFdX74wx9WFduWFgGn6MUZC9zEAilVW/RejCBYufULpuW5DNN+++2Xtt9+++Kc0047LYVp1RYLvMQCOXmodhpGIDIWF4pefdGzNYKeVdvxxx/ftRhOLEQUC87E1q8tI4jaWm70WIyVuTu3WGimtO1n13le63G0UZw729s+++yTvv71r3cVGwvZvOc97+lKl0BgVgQGGL4tCwECBAgQIECAAAECBAgQGHuBN7/5zT3nzMsrPzcuu+yyLoMc6Gp88YtfbOSVnIvv3vKWt/QsI+bsa93uueeeRg5s9sz/7W9/u5m93xyROTjQOOWUU5p589DiRl7xuGe5kT8PXW5EvnKLhWQiveovD3cus/VdcCWvtNzMFx+uv/76vgvofP7zny/yD2uOyCg85l6sqlOknXvuucX1e/0nD62uPDesOre8YnnlPJIx72cO5BbZ+80RWd5jDoQ2tt5668Z6663XvPbZZ5/debkZH0fbVM0rmgPEzfud8UUUQKBCwGI1FSiSCBAgQIAAAQIECBAgQGDyBJ71rGc1gz9lYCj2EUyqCkJWCcUiJa3nlp8f+chHVi5Ck+fpq8wf5+Uee81L9AtExqIsndvixYt7lpt7LXZmb+QhxD3z//znP2/m7xdMi5WfO7ePf/zjPcvNczgW2Uc1EBkBwbL9WvfRxrlHZNdfHqZdmT9WKI+tn12UH4vV5B62Rd74Tywq9JjHPKZx3333NdNm68OrX/3qynvNPSFn6xLKIVApYGh2/tduI0CAAAECBAgQIECAAAECMQx56dKlXRCbbbZZMUy664uKhBjuHAvedG4xZ2FefbkzOd19991p7ty5XemR8LKXvSydccYZxXf9hmbfeuutKfegaysj5ibce++929LKg7wqeNpiiy3Kw2Ifi8dsu+22bWnlQe7pmHIPy+Kw3/DiHIjsqksME99xxx3Lotr2MZfmZz/72aEMzS4vFG0RbVK15R6RKYaz99rmzZtXDO/u9f2g6WeeeWZ66UtfWgyv7rXQz6qrrloM0485J4e95Z626YUvfGHXZWIho3gOYk5KG4FhCQhEDktWuQQIECBAgAABAgQIECBQK4GYH/CBBx7ouucFCxakX/3qV13pVQkxT2Lrqstlnp133rnnvI0x92TVtvvuuzdXUp5qIPKSSy5JT3/606uKTVWByN///vddwcny5JkEImOOxg033LAsqm3/ute9LuUh5T0DkTFfZ9xX5zbIqtnlOTMJRPZqy7LsQfcnnnhiOuyww/oGIg866KB08sknD1rktPPFnJ0xh2e5unhZUO6xmy699NJitfcyzZ7AMAQEIoehqkwCBAgQIECAAAECBAgQqJ1A9BKsCnzFSsoRuBlk1eKNNtqoWISls/K9gmrRm3H99dfvzF4cz6RH5KgEIiOAu80221TW79hjj015rsqegcgIjkUvyzyXYdv5b3/729P73//+trQ4WHfddbsCbP0Ckd/5znfSnnvu2VVOmbDxxhunPMdkedi27xU8bsv034NYnfqQQw7pG4j8zW9+k6JH4jC3f/3rX0Xv1F//+tddl4lV3vfff/+udAkEZl2gcsC2RAIECBAgQIAAAQIECBAgMGECeTXrynnz8ot4IwfNBtLot0hMDsp1lfGpT32q5zVj4Zty6zdHZA5mltma+1g4Ju676i/3iGzmKz/klbMr88b5rYvQ9JvnsGqOyJgHsuoeIi0W+Yntfe97X888V111VXmLxT732mvkYcyV+XMgsi1vHPRbrCavWt6VvzUhDymvvM4GG2wwrXkbp2rXei8z/RwLE/VakOhVr3rVTIt3PoGBBfSIzP/3sxEgQIAAAQIECBAgQIAAgRga+/rXv74nxMEHH5zywiopr6BdDL/+4x//mL7//e+n8847r5hD8eijj0458Fb08qsqJIZKRy+8ddZZp/g6esHFHIUxfLlqywvZpF133bX4qg5Ds3/84x+nnXbaqVmVK6+8sji+6667mmmtH/ICQMW8lHn17PSa17ym9avm57zSeProRz9aDJkPjwMOOKCnV1WPyGXLlhXzVuYoSbPM8sOWW25ZDH3fZJNNirkgY17NvLhOiiHj8RzkxYLSO97xjjJ72z4v9pKiF2G/npFXXHFF0d5lGVOdX7PtgjM8OOKII9LHPvaxylIOPPDAtPrqq3d9Fz2BwyCvpN31nQQC0xUQiJyunPMIECBAgAABAgQIECBAYKwE8urEKRamqVpsprWia621VrHIzP33399MjqG3J510UvrTn/6UNt1001QV+IrMMQy7XBTmwgsvTBEoq9oiOBaBzjLQVYdAZNRjt912K4KnYRgBxhhaXbXtsMMO6aKLLiq++sEPftAMuFblzStHF9633XZb1dfNtKpAZHwZc1T2CvbG9zH0u3Vezwh8RgA06hDXfvDBByNb1/bMZz6zCDxHXSJYd/PNN6frrrsuxZyaX/rSl1IEYmOL86MdV1QgMoaGH3rooV33P0jC7bffPtCUBIOUJQ+BEBCI9BwQIECAAAECBAgQIECAAIH/Cnzyk59Mb3jDG6bsUQYi48QjjzwynXDCCVMuo/WE6J231157NZPqEohs3vByPkTwcZdddily3XvvvSlWLL/zzjuXc1b/r3sFIhctWlT0XO1/9kPfloHISInejNErsN8WQcZegec4b0UGIs8+++wUK3X3Cqb2q1d8JxC5PCHfT1VAIHKqYvITIECAAAECBAgQIECAwNgKRM+4WCTmrLPOmlIdWwORsfJ2DKn+0Y9+NKUyysxve9vbuoJf4xSIfMlLXpK+9rWvldUt9jHkOs/Z2JY21YNegcjoebpw4cKBi2sNRMbzsMceexTD7wcuoCPjigpEXnDBBel5z3teuueeezruaPBDgcjBreQcUGDg2SRlJECAAAECBAgQIECAAAECEyCQh2g38px6jTxkt3Kxkvy63ZWeA5FtMrmXX+Ooo45q5N5yXXmrzo+0NdZYo3Haaae1lVMe1GGxml71KtPDIvcwbMTCKZ3bDTfc0MjDoJdrlXuJNo455pjKfDkQ2Vls8/iggw6qPKe8t9Z9DkQ2z4sPeQh+I6/U3chzJg5cRpQXz08OBDZyILIo73+5WM3FF1/cyPM+Tul+Ww3KzzkQ2WbhgMBMBfSIzP+6bAQIECBAgAABAgQIECBAoFMgr3KdYgGbGCadV6bu/Lo4jvkgd99992KBkwULFnTliTJycDF99atfLeYQ7MqQE7baaqu07777pv322y89+tGPrspSDC2OIcadWwwLjl5r8+bNa/tqyZIlabvttmtLKw9iHsO479bt+uuv70orvy8XlYnjfvMcHnfccSmvAp5uuumm8tRiH8Out99++8Ior0ze9l3rwbXXXpvySuEpFqW5++67m1/lVbJT2L785S9Phx9+eDHsPYa/d255Neu+c0HGMOXFixenvEJ411Dq8Iuh4vvss0/ac88902qrrdZZfIrFhaItzzjjjK46lplXWWWVtPXWW6e99947xYI2MT9lucVCRXnl6vKwuY9FYWIuzaprNjNN8UNe8TvlYOQUz2rPHs/WHXfckdZcc832LxwRmIGAQOQM8JxKgAABAgQIECBAgAABAuMvEMNzI7i2dOnSFAumRGBs7bXXTvPnzx94IY/ci6g4NxY0ueWWW1IErCJwFn91CvT0C0RGMC1WX77mmmuKoGss5hNB1tZg3CBPSwwlvvzyy4s5IyMwG2WsvPLKg5w6UJ4Icl599dVFe4Z/BGVjAaJBt2jLCP7GAjjRlrHl3qxFO26++eZpzpw5gxYlH4GJExCInLgmV2ECBAgQIECAAAECBAgQIDA9geUFIufOnTu9gp1FgMBECAhETkQzqyQBAgQIECBAgAABAgQIEJi5gEDkzA2VQGCSBQQiJ7n11Z0AAQIECBAgQIAAAQIECExBQCByCliyEiDQJSAQ2UUigQABAgQIECBAgAABAgQIEKgSEIisUpFGgMCgAgKRg0rJR4AAAQIECBAgQIAAAQIEJlxAIHLCHwDVJzBDAYHIGQI6nQABAgQIECBAgAABAgQITIqAQOSktLR6EhiOgEDkcFyVSoAAAQIECBAgQIAAAQIExk5gyZIl6bjjjuuq10orrZS+8pWvpDlz5nR9J4EAAQKlgEBkKWFPgAABAgQIECBAgAABAgQIECBAgMDQBAQih0arYAIECBAgQIAAAQIECBAgQIAAAQIESgGByFLCngABAgQIECBAgAABAgQIECBAgACBoQkIRA6NVsEECBAgQIAAAQIECBAgQIAAAQIECJQCApGlhD0BAgQIECBAgAABAgQIECBAgAABAkMTEIgcGq2CCRAgQIAAAQIECBAgQIAAAQIECBAoBQQiSwl7AgQIECBAgAABAgQIECBAgAABAgSGJiAQOTRaBRMgQIAAAQIECBAgQIAAAQIECBAgUAoIRJYS9gQIECBAgAABAgQIECBAgAABAgQIDE1AIHJotAomQIAAAQIECBAgQIAAAQIECBAgQKAUEIgsJewJECBAgAABAgQIECBAgAABAgQIEBiagEDk0GgVTIAAAQIECBAgQIAAAQIECBAgQIBAKSAQWUrYEyBAgAABAgQIECBAgAABAgQIECAwNAGByKHRKpgAAQIECBAgQIAAAQIECBAgQIAAgVJAILKUsCdAgAABAgQIECBAgAABAgQIECBAYGgCApFDo1UwAQIECBAgQIAAAQIECBAgQIAAAQKlgEBkKWFPgAABAgQIECBAgAABAgQIECBAgMDQBAQih0arYAIECBAgQIAAAQIECBAgQIAAAQIESgGByFLCngABAgQIECBAgAABAgQIECBAgACBoQkIRA6NVsEECBAgQIAAAQIECBAgQIAAAQIECJQCApGlhD0BAgQIECBAgAABAgQIECBAgAABAkMTEIgcGq2CCRAgQIAAAQIECBAgQIAAAQIECBAoBQQiSwl7AgQIECBAgAABAgQIECBAgAABAgSGJiAQOTRaBRMgQIAAAQIECBAgQIAAAQIECBAgUAoIRJYS9gQIECBAgAABAgQIECBAgAABAgQIDE1AIHJotAomQIAAAQIECBAgQIAAAQIECBAgQKAUEIgsJewJECBAgAABAgQIECBAgAABAgQIEBiagEDk0GgVTIAAAQIECBAgQIAAAQIECBAgQIBAKSAQWUrYEyBAgAABAgQIECBAgAABAgQIECAwNAGByKHRKpgAAQIECBAgQIAAAQIECBAgQIAAgVLg/wCh4qD1COXt5gAAAABJRU5ErkJggg==" - } - }, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Core Ideas:\n", - " - Network structure\n", - " - Client / server\n", - " - Request / response\n", - " \n", - " \n", - " \n", - " - HTTP protocol\n", - " - URL\n", - " - Headers\n", - " - Status Codes\n", - " - The requests module" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## HTTP Status Codes you need to know\n", - "- 200: success\n", - "- 404: not found\n", - "\n", - "Here is a list of all status codes, you do NOT need to memorize it: https://en.wikipedia.org/wiki/List_of_HTTP_status_codes" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## requests.get : Simple string example\n", - "- URL: https://www.msyamkumar.com/hello.txt" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "url = \"https://www.msyamkumar.com/hello.txt\"\n", - "r = requests.get(url) # r is the response\n", - "print(r.status_code)\n", - "print(r.text)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Q: What if the web site does not exist?\n", - "typo_url = \"https://www.msyamkumar.com/hello.txttttt\"\n", - "r = requests.get(typo_url)\n", - "print(r.status_code)\n", - "print(r.text)\n", - "\n", - "# A: " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# We can check for a status_code error by using an assert\n", - "typo_url = \"https://www.msyamkumar.com/hello.txttttt\"\n", - "r = requests.get(typo_url)\n", - "assert r.status_code == 200\n", - "print(r.status_code)\n", - "print(r.text)\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Instead of using an assert, we often use raise_for_status()\n", - "r = requests.get(typo_url)\n", - "r.raise_for_status() #similar to asserting r.status_code == 200\n", - "r.text\n", - "\n", - "# Note the error you get.... We will use this in the next cell" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Let's try to catch that error\n", - "\n", - "try:\n", - "\n", - "except:\n", - " print(\"oops!!\", e)\n", - " " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# we often need to prepend the names of exceptions with the name of the module\n", - "# fix the error from above\n", - "\n", - "try:\n", - "\n", - "except:\n", - " print(\"oops!!\", e)\n", - " \n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## requests.get : JSON file example\n", - "- URL: https://www.msyamkumar.com/scores.json\n", - "- `json.load` (FILE_OBJECT)\n", - "- `json.loads` (STRING)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# GETting a JSON file, the long way\n", - "url = \"https://www.msyamkumar.com/scores.json\"\n", - "r = requests.get(url)\n", - "r.raise_for_status()\n", - "urltext = r.text\n", - "print(urltext)\n", - "d = json.loads(urltext)\n", - "print(type(d), d)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# GETting a JSON file, the shortcut way\n", - "url = \"https://www.msyamkumar.com/scores.json\"\n", - "#Shortcut to bypass using json.loads()\n", - "r = requests.get(url)\n", - "r.raise_for_status()\n", - "d2 = r.json()\n", - "print(type(d2), d2)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Good GET Etiquette\n", - "\n", - "Don't make a lot of requests to the same server all at once.\n", - " - Requests use up the server's time\n", - " - Major websites will often ban users who make too many requests\n", - " - You can break a server....similar to DDoS attacks (DON'T DO THIS)\n", - " \n", - "In CS220 we will usually give you a link to a copied file to avoid overloading the site.\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## DEMO: Course Enrollment" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Explore the API!\n", - "\n", - "https://coletnelson.us/cs220-api/classes\n", - "\n", - "https://coletnelson.us/cs220-api/classes_as_txt\n", - "\n", - "https://coletnelson.us/cs220-api/classes/MATH_221\n", - "\n", - "https://coletnelson.us/cs220-api/classes/COMPSCI_200\n", - "\n", - "... etc\n", - "\n", - "https://coletnelson.us/cs220-api/all_data" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Get the list of classes." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### When the data is `json`" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "url = \"https://coletnelson.us/cs220-api/classes\"\n", - "r = requests.get(url)\n", - "r.raise_for_status()\n", - "classes_list = r.json()\n", - "print(type(classes_list))\n", - "print(classes_list)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### When the data is `text`" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "url = \"https://coletnelson.us/cs220-api/classes_as_txt\"\n", - "r = requests.get(url)\n", - "r.raise_for_status()\n", - "classes_txt = r.text\n", - "print(type(classes_txt))\n", - "print(classes_txt)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "classes_txt_as_list = ???" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Get data for a specific class" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "url = \"https://coletnelson.us/cs220-api/classes/COMPSCI_200\"\n", - "r = requests.get(url)\n", - "r.raise_for_status()\n", - "cs200_data = r.json()\n", - "print(type(cs200_data))\n", - "print(cs200_data) # Too much data? Try print(cs220_data.keys())" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "cs200_data.keys()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Get the number of credits the course is worth\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Get the list of keywords for the course\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Get the official course name\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Get the number of sections offered.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Collect all the class data in a list called 'all_class_data'\n", - "all_class_data = []\n", - "for class_num in classes_list:\n", - " url = \"https://coletnelson.us/cs220-api/classes/\" + class_num\n", - " r = requests.get(url)\n", - " r.raise_for_status()\n", - " class_data = r.json()\n", - " all_class_data.append(???)\n", - "\n", - "print(all_class_data) # Too much data? Try print(len(all_class_data))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "print(len(all_class_data))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Print the number of credits, course number, and name for each class.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# What is the average number of credits per course?\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# What are the unique subjects?\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Besides PYSCH 202, what are the course numbers of the courses\n", - "# with the most sections offered (not including subsections)?\n", - "high_courses = []\n", - "high_sections = 0\n", - "for spec_class in all_class_data:\n", - " pass\n", - "high_courses" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Can we make a Pandas dataframe? Yes!" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "all_course_frame = DataFrame(all_class_data)\n", - "all_course_frame" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### We may want to do some \"plumbing\" with our data." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Remove the 'sections' and 'requisites' column.\n", - "new_course_frame = all_course_frame.loc[:, \"credits\":\"number\"]\n", - "new_course_frame[\"subject\"] = all_course_frame.loc[:, \"subject\"]\n", - "new_course_frame" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Turn 'keywords' into a series of Strings and remove the '[', ']', '''\n", - "new_course_frame[\"keywords\"] = new_course_frame[\"keywords\"].astype('string')\n", - "new_course_frame[\"keywords\"] = new_course_frame[\"keywords\"].str.replace(\"[\", \"\", regex=False)\n", - "new_course_frame[\"keywords\"] = new_course_frame[\"keywords\"].str.replace(\"]\", \"\", regex=False)\n", - "new_course_frame[\"keywords\"] = new_course_frame[\"keywords\"].str.replace(\"'\", \"\", regex=False)\n", - "new_course_frame" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Pandas Operations" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# What is the most number of credits a course offers?\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# What is the least number of credits a course offers?\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# What is the info for that course?\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# What courses contain the keyword \"programming\"?\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# What course has the most lengthy description?\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Write it out to a CSV file on your drive\n", - "You now have your own copy!" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Write it all out to a single CSV file\n", - "new_course_frame.to_csv(\"my_course_data.csv\", index=False)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Other Cool APIs" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "- City of Madison Transit: http://transitdata.cityofmadison.com/\n", - "- Reddit: https://reddit.com/r/UWMadison.json\n", - "- Lord of the Rings: https://the-one-api.dev/\n", - "- Pokemon: https://pokeapi.co/\n", - "\n", - "Remember: Be judicious when making requests; don't overwhelm the server! :)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Next Time\n", - "What other documents can we get via the Web? HTML is very popular! We'll explore this." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "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.9.7" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/f22/meena_lec_notes/lec-29/.ipynb_checkpoints/pandas1-checkpoint.ipynb b/f22/meena_lec_notes/lec-29/.ipynb_checkpoints/pandas1-checkpoint.ipynb deleted file mode 100644 index 1e84430..0000000 --- a/f22/meena_lec_notes/lec-29/.ipynb_checkpoints/pandas1-checkpoint.ipynb +++ /dev/null @@ -1,1736 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Pandas 1" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "<style>.container { width:100% !important; }</style>" - ], - "text/plain": [ - "<IPython.core.display.HTML object>" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "from IPython.core.display import display, HTML\n", - "display(HTML(\"<style>.container { width:100% !important; }</style>\"))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Learning objectives" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " - Pandas:\n", - " - Python module: tools for doing Data Science\n", - " - helps deal with tabular (tables) data\n", - " - List of list is not adequate alternative to excel\n", - " - Series: new data structure\n", - " - hybrid of a dict and a list\n", - " - Python dict \"key\" equivalent to \"index\" in pandas\n", - " - Python list \"index\" quivalent to \"integer position\" in pandas\n", - " - supports complicated expressions within lookup [...]\n", - " - element-wise operation\n", - " - boolean indexing\n", - " - DataFrames aka tables (next lecture)\n", - " - built from series\n", - " - each series will be a column in the table" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# pandas comes with Anaconda installation\n", - "If for some reason, you don't have pandas installed, run the following command in terminal or powershell\n", - "<pre> pip install pandas </pre>" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [], - "source": [ - "# importing pandas module\n", - "import pandas" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Module naming abbreviation" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [], - "source": [ - "# Common abbrievation for pandas module\n", - "import pandas as pd" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Create a series from a dict" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'one': 7, 'two': 8, 'three': 9}" - ] - }, - "execution_count": 4, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# create a series from a dict\n", - "d = {\"one\": 7, \"two\": 8, \"three\": 9}\n", - "d" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "pandas.core.series.Series" - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "pd.Series" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "one 7\n", - "two 8\n", - "three 9\n", - "dtype: int64" - ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s = pd.Series(d)\n", - "s" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "one 7\n", - "two 8\n", - "three 9\n", - "dtype: int64" - ] - }, - "execution_count": 7, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s = pd.Series({\"one\": 7, \"two\": 8, \"three\": 9}) # equivalent to the above example\n", - "s" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [], - "source": [ - "# IP index value\n", - "# 0 one 7\n", - "# 1 two 8\n", - "# 2 three 9\n", - "\n", - "# dtype: int64" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Accessing values with index (.loc[...])" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'one': 7, 'two': 8, 'three': 9}" - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "d" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "7" - ] - }, - "execution_count": 10, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# dict access with key\n", - "d[\"one\"]" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "7" - ] - }, - "execution_count": 11, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s.loc[\"one\"]" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "8" - ] - }, - "execution_count": 12, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s.loc[\"two\"]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Accessing values with integer position (.iloc[...])" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "7" - ] - }, - "execution_count": 13, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s.iloc[0]" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "9" - ] - }, - "execution_count": 14, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s.iloc[-1]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Regular lookups with just [ ]" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "one 7\n", - "two 8\n", - "three 9\n", - "dtype: int64" - ] - }, - "execution_count": 15, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "7" - ] - }, - "execution_count": 16, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s[\"one\"]" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "7" - ] - }, - "execution_count": 17, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s[0]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Accessing multiple values with a list of integer positions" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "two 8\n", - "three 9\n", - "dtype: int64" - ] - }, - "execution_count": 18, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s[[1, 2]]" - ] - }, - { - "cell_type": "code", - "execution_count": 19, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "two 8\n", - "three 9\n", - "dtype: int64" - ] - }, - "execution_count": 19, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# series access with a list of indexes\n", - "s[[\"two\", \"three\"]]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Create a series from a list" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "0 100\n", - "1 200\n", - "2 300\n", - "dtype: int64" - ] - }, - "execution_count": 20, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Series created from a list\n", - "num_list = [100, 200, 300]\n", - "s = pd.Series(num_list)\n", - "s" - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "metadata": {}, - "outputs": [], - "source": [ - "# IP index value\n", - "# 0 0 100\n", - "# 1 1 200\n", - "# 2 2 300\n", - "# dtype: int64" - ] - }, - { - "cell_type": "code", - "execution_count": 22, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "200\n", - "200\n" - ] - } - ], - "source": [ - "print(s.loc[1])\n", - "print(s.iloc[1])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "pandas looks for an index when we do a [ ] lookup, by default" - ] - }, - { - "cell_type": "code", - "execution_count": 23, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'D'" - ] - }, - "execution_count": 23, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "letters_list = [\"A\", \"B\", \"C\", \"D\"]\n", - "letters = pd.Series(letters_list)\n", - "letters\n", - "# letters[-1] # Avoid negative indexes, unless we use .iloc\n", - "letters.iloc[-1]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Slicing series using integer positions" - ] - }, - { - "cell_type": "code", - "execution_count": 24, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "0 A\n", - "1 B\n", - "2 C\n", - "3 D\n", - "dtype: object" - ] - }, - "execution_count": 24, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "letters_list = [\"A\", \"B\", \"C\", \"D\"]\n", - "letters = pd.Series(letters_list)\n", - "letters" - ] - }, - { - "cell_type": "code", - "execution_count": 25, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "['C', 'D']" - ] - }, - "execution_count": 25, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# list slicing\n", - "sliced_letter_list = letters_list[2:]\n", - "sliced_letter_list" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Sliced Series retains original Series index, whereas integer positions are renumbered." - ] - }, - { - "cell_type": "code", - "execution_count": 26, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "2 C\n", - "3 D\n", - "dtype: object" - ] - }, - "execution_count": 26, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "sliced_letters = letters[2:]\n", - "sliced_letters" - ] - }, - { - "cell_type": "code", - "execution_count": 27, - "metadata": {}, - "outputs": [], - "source": [ - "# Note: integer positions get renumbered, whereas indexes do not.\n", - "\n", - "# IP Index values\n", - "# 0 2 C\n", - "# 1 3 D\n", - "# dtype: object" - ] - }, - { - "cell_type": "code", - "execution_count": 28, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "C\n", - "C\n" - ] - } - ], - "source": [ - "print(sliced_letters.loc[2])\n", - "print(sliced_letters.iloc[0])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Slicing series using index" - ] - }, - { - "cell_type": "code", - "execution_count": 29, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "one 7\n", - "two 8\n", - "three 9\n", - "dtype: int64" - ] - }, - "execution_count": 29, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s = pd.Series({\"one\": 7, \"two\": 8, \"three\": 9})\n", - "s" - ] - }, - { - "cell_type": "code", - "execution_count": 30, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "two 8\n", - "three 9\n", - "dtype: int64" - ] - }, - "execution_count": 30, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "#slicing with indexes\n", - "s[\"two\":]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Statistics on Series" - ] - }, - { - "cell_type": "code", - "execution_count": 31, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "0 44\n", - "1 32\n", - "2 19\n", - "3 67\n", - "4 23\n", - "5 23\n", - "6 92\n", - "7 47\n", - "8 47\n", - "9 78\n", - "10 84\n", - "dtype: int64" - ] - }, - "execution_count": 31, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "scores = pd.Series([44, 32, 19, 67, 23, 23, 92, 47, 47, 78, 84])\n", - "scores" - ] - }, - { - "cell_type": "code", - "execution_count": 32, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "50.54545454545455" - ] - }, - "execution_count": 32, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "scores.mean()" - ] - }, - { - "cell_type": "code", - "execution_count": 33, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "26.051347897426098" - ] - }, - "execution_count": 33, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "scores.std()" - ] - }, - { - "cell_type": "code", - "execution_count": 34, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "47.0" - ] - }, - "execution_count": 34, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "scores.median()" - ] - }, - { - "cell_type": "code", - "execution_count": 35, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "0 23\n", - "1 47\n", - "dtype: int64" - ] - }, - "execution_count": 35, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "scores.mode()" - ] - }, - { - "cell_type": "code", - "execution_count": 36, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "1.00 92.0\n", - "0.75 72.5\n", - "0.50 47.0\n", - "0.25 27.5\n", - "0.00 19.0\n", - "dtype: float64" - ] - }, - "execution_count": 36, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "scores.quantile([1.0, 0.75, 0.5, 0.25, 0])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## CS220 information survey data" - ] - }, - { - "cell_type": "code", - "execution_count": 37, - "metadata": {}, - "outputs": [], - "source": [ - "# Modified from https://automatetheboringstuff.com/chapter14/\n", - "import csv\n", - "def process_csv(filename):\n", - " example_file = open(filename, encoding=\"utf-8\")\n", - " example_reader = csv.reader(example_file)\n", - " example_data = list(example_reader)\n", - " example_file.close()\n", - " return example_data\n", - "\n", - "data = process_csv(\"cs220_survey_data.csv\")\n", - "header = data[0]\n", - "data = data[1:]" - ] - }, - { - "cell_type": "code", - "execution_count": 38, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "['lecture', 'age', 'major', 'topping']" - ] - }, - "execution_count": 38, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "header" - ] - }, - { - "cell_type": "code", - "execution_count": 39, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[['LEC001', '19', 'Computer Science', 'basil/spinach'],\n", - " ['LEC002', '18', 'Engineering', 'pineapple'],\n", - " ['LEC003', '19', 'Business', 'pepperoni']]" - ] - }, - "execution_count": 39, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "data[:3]" - ] - }, - { - "cell_type": "code", - "execution_count": 40, - "metadata": {}, - "outputs": [], - "source": [ - "# use list comprehension to extract just ages\n", - "# age_list = [int(row[1]) for row in data if row[1] != \"\"]\n", - "age_list = [int(row[header.index(\"age\")]) for row in data if row[header.index(\"age\")] != \"\"]\n", - "#age_list" - ] - }, - { - "cell_type": "code", - "execution_count": 41, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "0 19\n", - "1 18\n", - "2 19\n", - "3 19\n", - "4 19\n", - " ..\n", - "877 19\n", - "878 20\n", - "879 21\n", - "880 19\n", - "881 18\n", - "Length: 882, dtype: int64" - ] - }, - "execution_count": 41, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "cs220_ages = pd.Series(age_list)\n", - "cs220_ages" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Unique values in a Series" - ] - }, - { - "cell_type": "code", - "execution_count": 42, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "19 290\n", - "18 214\n", - "20 178\n", - "21 101\n", - "22 41\n", - "23 13\n", - "17 11\n", - "25 7\n", - "24 6\n", - "26 4\n", - "28 3\n", - "29 2\n", - "30 2\n", - "27 2\n", - "34 1\n", - "37 1\n", - "35 1\n", - "16 1\n", - "33 1\n", - "32 1\n", - "31 1\n", - "46 1\n", - "dtype: int64" - ] - }, - "execution_count": 42, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "cs220_ages.value_counts()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Series sorting\n", - "- can be done using index or values" - ] - }, - { - "cell_type": "code", - "execution_count": 43, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "16 1\n", - "17 11\n", - "18 214\n", - "19 290\n", - "20 178\n", - "21 101\n", - "22 41\n", - "23 13\n", - "24 6\n", - "25 7\n", - "26 4\n", - "27 2\n", - "28 3\n", - "29 2\n", - "30 2\n", - "31 1\n", - "32 1\n", - "33 1\n", - "34 1\n", - "35 1\n", - "37 1\n", - "46 1\n", - "dtype: int64" - ] - }, - "execution_count": 43, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "cs220_ages.value_counts().sort_index()" - ] - }, - { - "cell_type": "code", - "execution_count": 44, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "46 1\n", - "32 1\n", - "33 1\n", - "16 1\n", - "35 1\n", - "37 1\n", - "34 1\n", - "31 1\n", - "27 2\n", - "30 2\n", - "29 2\n", - "28 3\n", - "26 4\n", - "24 6\n", - "25 7\n", - "17 11\n", - "23 13\n", - "22 41\n", - "21 101\n", - "20 178\n", - "18 214\n", - "19 290\n", - "dtype: int64" - ] - }, - "execution_count": 44, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "cs220_ages.value_counts().sort_values()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Statistics" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### What is the mode of CS220 student ages?" - ] - }, - { - "cell_type": "code", - "execution_count": 45, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "0 19\n", - "dtype: int64\n" - ] - } - ], - "source": [ - "print(cs220_ages.mode())" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### What is the 75th percentile of ages?" - ] - }, - { - "cell_type": "code", - "execution_count": 46, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "20.0\n" - ] - } - ], - "source": [ - "print(cs220_ages.quantile(.75))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Element-wise operations\n", - "1. SERIES op SCALAR\n", - "2. SERIES op SERIES" - ] - }, - { - "cell_type": "code", - "execution_count": 47, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Chris 10\n", - "Kiara 3\n", - "Mikayla 7\n", - "Ann 8\n", - "Trish 6\n", - "dtype: int64\n", - "Kiara 7\n", - "Chris 3\n", - "Trish 11\n", - "Mikayla 2\n", - "Ann 5\n", - "Meena 20\n", - "dtype: int64\n" - ] - } - ], - "source": [ - "## Series from a dict\n", - "game1_points = pd.Series({\"Chris\": 10, \"Kiara\": 3, \"Mikayla\": 7, \"Ann\": 8, \"Trish\": 6})\n", - "print(game1_points)\n", - "game2_points = pd.Series({\"Kiara\": 7, \"Chris\": 3, \"Trish\": 11, \"Mikayla\": 2, \"Ann\": 5, \"Meena\": 20})\n", - "print(game2_points)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Give 2 additional points for every player's game 1 score" - ] - }, - { - "cell_type": "code", - "execution_count": 49, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "Chris 12\n", - "Kiara 5\n", - "Mikayla 9\n", - "Ann 10\n", - "Trish 8\n", - "dtype: int64" - ] - }, - "execution_count": 49, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "game1_points + 2" - ] - }, - { - "cell_type": "code", - "execution_count": 50, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "Chris 12\n", - "Kiara 5\n", - "Mikayla 9\n", - "Ann 10\n", - "Trish 8\n", - "dtype: int64" - ] - }, - "execution_count": 50, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "game1_points = game1_points + 2\n", - "game1_points" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Give 3 additional points for every player's game 2 score" - ] - }, - { - "cell_type": "code", - "execution_count": 51, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "Kiara 10\n", - "Chris 6\n", - "Trish 14\n", - "Mikayla 5\n", - "Ann 8\n", - "Meena 23\n", - "dtype: int64" - ] - }, - "execution_count": 51, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "game2_points += 3\n", - "game2_points" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Compute total of two series" - ] - }, - { - "cell_type": "code", - "execution_count": 52, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "Ann 18.0\n", - "Chris 18.0\n", - "Kiara 15.0\n", - "Meena NaN\n", - "Mikayla 14.0\n", - "Trish 22.0\n", - "dtype: float64" - ] - }, - "execution_count": 52, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Pandas can perform operations on two series by matching up their indices\n", - "total = game1_points + game2_points\n", - "total" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Who has the highest points?" - ] - }, - { - "cell_type": "code", - "execution_count": 53, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "22.0\n", - "Trish\n" - ] - } - ], - "source": [ - "## Who has the most points?\n", - "print(total.max())\n", - "print(total.idxmax())" - ] - }, - { - "cell_type": "code", - "execution_count": 54, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "15.0 15.0\n" - ] - } - ], - "source": [ - "print(total['Kiara'], total[2])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Boolean indexing\n", - "- applying boolean expressions on a Series\n", - "- boolean expression will be specified within the pair of [ ]\n", - "- Boolean operators:\n", - " - & means 'and'\n", - " - | means 'or'\n", - " - ~ means 'not'\n", - " - we must use () for compound boolean expressions" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "s = pd.Series([10, 2, 3, 15])\n", - "s" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Find all values > 8" - ] - }, - { - "cell_type": "code", - "execution_count": 55, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "0 True\n", - "1 False\n", - "2 False\n", - "3 True\n", - "dtype: bool" - ] - }, - "execution_count": 55, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# gives a boolean Series, where each value is True if the original Series values satifies the condition\n", - "b = s > 8\n", - "b" - ] - }, - { - "cell_type": "code", - "execution_count": 56, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "0 10\n", - "3 15\n", - "dtype: int64" - ] - }, - "execution_count": 56, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# now let's apply the boolean expression, which gives a boolean Series\n", - "s[b]" - ] - }, - { - "cell_type": "code", - "execution_count": 57, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "0 10\n", - "3 15\n", - "dtype: int64" - ] - }, - "execution_count": 57, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Equivalently, you can directly specify boolean expression inside the [ ]\n", - "s[s > 8]" - ] - }, - { - "cell_type": "code", - "execution_count": 58, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "0 10\n", - "3 15\n", - "dtype: int64" - ] - }, - "execution_count": 58, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Decomposing the steps here\n", - "# Above example is equivalent to\n", - "b = pd.Series([True, False, False, True])\n", - "s[b]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### How many students are 25 years or older?" - ] - }, - { - "cell_type": "code", - "execution_count": 59, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "0 False\n", - "1 False\n", - "2 False\n", - "3 False\n", - "4 False\n", - " ... \n", - "877 False\n", - "878 False\n", - "879 False\n", - "880 False\n", - "881 False\n", - "Length: 882, dtype: bool" - ] - }, - "execution_count": 59, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "cs220_ages > 25" - ] - }, - { - "cell_type": "code", - "execution_count": 60, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "38 32\n", - "93 46\n", - "169 30\n", - "170 35\n", - "173 29\n", - "266 28\n", - "369 28\n", - "409 27\n", - "479 26\n", - "495 31\n", - "669 26\n", - "686 26\n", - "696 30\n", - "698 34\n", - "732 29\n", - "756 26\n", - "786 27\n", - "790 37\n", - "794 28\n", - "804 33\n", - "dtype: int64" - ] - }, - "execution_count": 60, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "cs220_ages[cs220_ages > 25]" - ] - }, - { - "cell_type": "code", - "execution_count": 61, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "20\n" - ] - } - ], - "source": [ - "print(len(cs220_ages[cs220_ages > 25]))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### How many students are in the age range 18 to 20, inclusive?" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "(ages >= 18) & (ages <= 20)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "ages[(ages >= 18) & (ages <= 20)]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "len(ages[(ages >= 18) & (ages <= 20)])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### what percentage of students are ages 18 OR 21?" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "len((ages[ (ages == 18) | (ages == 20)])) / len(ages)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Plotting age information as a bar plot" - ] - }, - { - "cell_type": "code", - "execution_count": 62, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[Text(0.5, 0, 'age'), Text(0, 0.5, 'count')]" - ] - }, - "execution_count": 62, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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\n", - "text/plain": [ - "<Figure size 432x288 with 1 Axes>" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], - "source": [ - "age_plot = cs220_ages.value_counts().sort_index().plot.bar()\n", - "age_plot.set(xlabel = \"age\", ylabel = \"count\")" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "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.8.8" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/f22/meena_lec_notes/lec-29/.ipynb_checkpoints/pandas_1_worksheet-checkpoint.ipynb b/f22/meena_lec_notes/lec-29/.ipynb_checkpoints/pandas_1_worksheet-checkpoint.ipynb deleted file mode 100644 index f70acea..0000000 --- a/f22/meena_lec_notes/lec-29/.ipynb_checkpoints/pandas_1_worksheet-checkpoint.ipynb +++ /dev/null @@ -1,2042 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Pandas 1 worksheet\n", - "\n", - "- Observe syntax, predict output and run cell to confirm your output" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "<style>.container { width:100% !important; }</style>" - ], - "text/plain": [ - "<IPython.core.display.HTML object>" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "from IPython.core.display import display, HTML\n", - "display(HTML(\"<style>.container { width:100% !important; }</style>\"))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Learning objectives" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " - Pandas helps deal with tabular (tables) data\n", - " - List of list is not adequate alternative to excel\n", - " - Series: new data structure\n", - " - hybrid of a dict and a list\n", - " - Python dict \"key\" equivalent to \"index\" in pandas\n", - " - Python list \"index\" quivalent to \"integer position\" in pandas\n", - " - supports complicated expressions within lookup [...]\n", - " - element-wise operation\n", - " - boolean indexing\n", - " - DataFrames aka tables (next lecture)\n", - " - built from series\n", - " - each series will be a column in the table" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# pandas comes with Anaconda installation\n", - "If for some reason, you don't have pandas installed, run the following command in terminal or powershell\n", - "<pre> pip install pandas </pre>" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [], - "source": [ - "import pandas" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "pandas.core.series.Series" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "pandas.Series" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Module naming abbreviation" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [], - "source": [ - "import pandas as pd" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "pandas.core.series.Series" - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "pd.Series" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Create a series from a dict" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'one': 7, 'two': 8, 'three': 9}" - ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "#create a series from a dict\n", - "d = {\"one\":7, \"two\":8, \"three\":9}\n", - "d" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "one 7\n", - "two 8\n", - "three 9\n", - "dtype: int64" - ] - }, - "execution_count": 7, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s = pd.Series({\"one\":7, \"two\":8, \"three\":9})\n", - "s" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [], - "source": [ - "# IP index value\n", - "# 0 one 7\n", - "# 1 two 8\n", - "# 2 three 9\n", - "\n", - "# dtype: int64" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Accessing values with index (.loc[...])" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "7" - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# dict access with key\n", - "d[\"one\"]" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "7" - ] - }, - "execution_count": 10, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s.loc[\"one\"]" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "8" - ] - }, - "execution_count": 11, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s.loc[\"two\"]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Accessing values with integer position (.iloc[...])" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "7" - ] - }, - "execution_count": 12, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s.iloc[0]" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "8" - ] - }, - "execution_count": 13, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s.iloc[1]" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "9" - ] - }, - "execution_count": 14, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s.iloc[-1]" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "7" - ] - }, - "execution_count": 15, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s[\"one\"]" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "7" - ] - }, - "execution_count": 16, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s[0]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Accessing multiple values with a list of integer positions" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "one 7\n", - "three 9\n", - "dtype: int64" - ] - }, - "execution_count": 17, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s[[0, 2]]" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "one 7\n", - "three 9\n", - "dtype: int64" - ] - }, - "execution_count": 18, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "#series access with a list of indexes\n", - "s[[\"one\", \"three\"]]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Create a series from a list" - ] - }, - { - "cell_type": "code", - "execution_count": 19, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "0 100\n", - "1 200\n", - "2 300\n", - "dtype: int64" - ] - }, - "execution_count": 19, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Series created from a list\n", - "num_list = [100, 200, 300]\n", - "s = pd.Series([100, 200, 300])\n", - "s" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "metadata": {}, - "outputs": [], - "source": [ - "# IP index value\n", - "# 0 0 100\n", - "# 1 1 200\n", - "# 2 2 300\n", - "# dtype: int64" - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "200\n", - "200\n" - ] - } - ], - "source": [ - "print(s.loc[1])\n", - "print(s.iloc[1])" - ] - }, - { - "cell_type": "code", - "execution_count": 22, - "metadata": {}, - "outputs": [], - "source": [ - "letters_list = [\"A\", \"B\", \"C\", \"D\"]\n", - "letters = pd.Series(letters_list)\n", - "# letters[-1] #Avoid negative indexes, unless we use .iloc" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Slicing series using integer positions" - ] - }, - { - "cell_type": "code", - "execution_count": 23, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "0 A\n", - "1 B\n", - "2 C\n", - "3 D\n", - "dtype: object" - ] - }, - "execution_count": 23, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "letters_list = [\"A\", \"B\", \"C\", \"D\"]\n", - "letters = pd.Series(letters_list)\n", - "letters" - ] - }, - { - "cell_type": "code", - "execution_count": 24, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "['A', 'B', 'C', 'D']" - ] - }, - "execution_count": 24, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "#list slicing reveiw\n", - "letters_list" - ] - }, - { - "cell_type": "code", - "execution_count": 25, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "['C', 'D']" - ] - }, - "execution_count": 25, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "sliced_letter_list = letters_list[2:]\n", - "sliced_letter_list" - ] - }, - { - "cell_type": "code", - "execution_count": 26, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'C'" - ] - }, - "execution_count": 26, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "sliced_letter_list[0]" - ] - }, - { - "cell_type": "code", - "execution_count": 27, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "0 A\n", - "1 B\n", - "2 C\n", - "3 D\n", - "dtype: object" - ] - }, - "execution_count": 27, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "#series slicing\n", - "letters" - ] - }, - { - "cell_type": "code", - "execution_count": 28, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "2 C\n", - "3 D\n", - "dtype: object" - ] - }, - "execution_count": 28, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "sliced_letters = letters[2:]\n", - "sliced_letters" - ] - }, - { - "cell_type": "code", - "execution_count": 29, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'C'" - ] - }, - "execution_count": 29, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "sliced_letters.loc[2]" - ] - }, - { - "cell_type": "code", - "execution_count": 30, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'C'" - ] - }, - "execution_count": 30, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "sliced_letters.iloc[0]" - ] - }, - { - "cell_type": "code", - "execution_count": 31, - "metadata": {}, - "outputs": [], - "source": [ - "# sliced_letter.loc[0] # index 0 doesn't exist in the sliced series!" - ] - }, - { - "cell_type": "code", - "execution_count": 32, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'C'" - ] - }, - "execution_count": 32, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "sliced_letters[2]" - ] - }, - { - "cell_type": "code", - "execution_count": 33, - "metadata": {}, - "outputs": [], - "source": [ - "# Note: integer positions get renumbered, whereas indexes do not.\n", - "\n", - "# IP Index values\n", - "# 0 2 c\n", - "# 1 3 d\n", - "# 2 4 e\n", - "# 3 5 f\n", - "# dtype: object" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Slicing series using index" - ] - }, - { - "cell_type": "code", - "execution_count": 34, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "one 7\n", - "two 8\n", - "three 9\n", - "dtype: int64" - ] - }, - "execution_count": 34, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s = pd.Series({\"one\":7, \"two\":8, \"three\":9})\n", - "s" - ] - }, - { - "cell_type": "code", - "execution_count": 35, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "two 8\n", - "three 9\n", - "dtype: int64" - ] - }, - "execution_count": 35, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "#slicing with indexes\n", - "s[\"two\":]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Element-wise operations\n", - "1. SERIES op SCALAR\n", - "2. SERIES op SERIES" - ] - }, - { - "cell_type": "code", - "execution_count": 36, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[1, 2, 3, 1, 2, 3, 1, 2, 3]" - ] - }, - "execution_count": 36, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "#list recap\n", - "nums = [1, 2, 3]\n", - "nums * 3" - ] - }, - { - "cell_type": "code", - "execution_count": 37, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "0 1\n", - "1 2\n", - "2 3\n", - "dtype: int64" - ] - }, - "execution_count": 37, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "snum = pd.Series(nums)\n", - "snum" - ] - }, - { - "cell_type": "code", - "execution_count": 38, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "0 3\n", - "1 6\n", - "2 9\n", - "dtype: int64" - ] - }, - "execution_count": 38, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "snum * 3" - ] - }, - { - "cell_type": "code", - "execution_count": 39, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "0 4\n", - "1 5\n", - "2 6\n", - "dtype: int64" - ] - }, - "execution_count": 39, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "snum + 3" - ] - }, - { - "cell_type": "code", - "execution_count": 40, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "0 0.333333\n", - "1 0.666667\n", - "2 1.000000\n", - "dtype: float64" - ] - }, - "execution_count": 40, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "snum / 3" - ] - }, - { - "cell_type": "code", - "execution_count": 41, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[1, 2, 3]" - ] - }, - "execution_count": 41, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "nums" - ] - }, - { - "cell_type": "code", - "execution_count": 42, - "metadata": {}, - "outputs": [], - "source": [ - "# nums / 3 # doesn't work with lists" - ] - }, - { - "cell_type": "code", - "execution_count": 43, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "0 1\n", - "1 2\n", - "2 3\n", - "dtype: int64" - ] - }, - "execution_count": 43, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "snum" - ] - }, - { - "cell_type": "code", - "execution_count": 44, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "0 3\n", - "1 4\n", - "2 5\n", - "dtype: int64" - ] - }, - "execution_count": 44, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "snum += 2\n", - "snum" - ] - }, - { - "cell_type": "code", - "execution_count": 45, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[1, 2, 3, 4, 5, 6]" - ] - }, - "execution_count": 45, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "#list recap\n", - "l1 = [1, 2, 3]\n", - "l2 = [4, 5, 6]\n", - "l1 + l2" - ] - }, - { - "cell_type": "code", - "execution_count": 46, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "0 1\n", - "1 2\n", - "2 3\n", - "dtype: int64\n", - "0 4\n", - "1 5\n", - "2 6\n", - "dtype: int64\n" - ] - }, - { - "data": { - "text/plain": [ - "0 5\n", - "1 7\n", - "2 9\n", - "dtype: int64" - ] - }, - "execution_count": 46, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s1 = pd.Series(l1)\n", - "s2 = pd.Series(l2)\n", - "print(s1)\n", - "print(s2)\n", - "s1 + s2" - ] - }, - { - "cell_type": "code", - "execution_count": 47, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "0 1\n", - "1 2\n", - "2 3\n", - "dtype: int64\n", - "0 4\n", - "1 5\n", - "2 6\n", - "dtype: int64\n" - ] - }, - { - "data": { - "text/plain": [ - "0 4\n", - "1 10\n", - "2 18\n", - "dtype: int64" - ] - }, - "execution_count": 47, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "print(s1)\n", - "print(s2)\n", - "s1 * s2" - ] - }, - { - "cell_type": "code", - "execution_count": 48, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "0 1\n", - "1 2\n", - "2 3\n", - "dtype: int64\n", - "0 4\n", - "1 5\n", - "2 6\n", - "dtype: int64\n" - ] - }, - { - "data": { - "text/plain": [ - "0 0.25\n", - "1 0.40\n", - "2 0.50\n", - "dtype: float64" - ] - }, - "execution_count": 48, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "print(s1)\n", - "print(s2)\n", - "s1 / s2" - ] - }, - { - "cell_type": "code", - "execution_count": 49, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "0 1\n", - "1 2\n", - "2 3\n", - "dtype: int64\n", - "0 4\n", - "1 5\n", - "2 6\n", - "dtype: int64\n" - ] - }, - { - "data": { - "text/plain": [ - "0 4\n", - "1 25\n", - "2 216\n", - "dtype: int64" - ] - }, - "execution_count": 49, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "print(s1)\n", - "print(s2)\n", - "s2 ** s1" - ] - }, - { - "cell_type": "code", - "execution_count": 50, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "0 1\n", - "1 2\n", - "2 3\n", - "dtype: int64\n", - "0 4\n", - "1 5\n", - "2 6\n", - "dtype: int64\n" - ] - }, - { - "data": { - "text/plain": [ - "0 True\n", - "1 True\n", - "2 True\n", - "dtype: bool" - ] - }, - "execution_count": 50, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "print(s1)\n", - "print(s2)\n", - "s1 < s2" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## What happens to element-wise operation if we have two series with different sizes?" - ] - }, - { - "cell_type": "code", - "execution_count": 51, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "0 5.0\n", - "1 7.0\n", - "2 NaN\n", - "dtype: float64" - ] - }, - "execution_count": 51, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "pd.Series([1,2,3]) + pd.Series([4,5])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Series with different types" - ] - }, - { - "cell_type": "code", - "execution_count": 52, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "0 a\n", - "1 Alice\n", - "2 True\n", - "3 1\n", - "4 4.5\n", - "5 [1, 2]\n", - "6 {'a': 'Alice'}\n", - "dtype: object" - ] - }, - "execution_count": 52, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "pd.Series([\"a\", \"Alice\", True, 1, 4.5, [1,2], {\"a\":\"Alice\"}])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## How do you merge two series?" - ] - }, - { - "cell_type": "code", - "execution_count": 53, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "0 1\n", - "1 2\n", - "2 3\n", - "dtype: int64\n", - "0 4\n", - "1 5\n", - "dtype: int64\n" - ] - } - ], - "source": [ - "s1 = pd.Series([1,2,3]) \n", - "s2 = pd.Series([4,5])\n", - "print(s1)\n", - "print(s2)" - ] - }, - { - "cell_type": "code", - "execution_count": 54, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "0 1\n", - "1 2\n", - "2 3\n", - "0 4\n", - "1 5\n", - "dtype: int64" - ] - }, - "execution_count": 54, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s = pd.concat( [s1, s2] )\n", - "s" - ] - }, - { - "cell_type": "code", - "execution_count": 55, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "0 1\n", - "0 4\n", - "dtype: int64" - ] - }, - "execution_count": 55, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s.loc[0]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Element-wise Ambiguity" - ] - }, - { - "cell_type": "code", - "execution_count": 56, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "A 10\n", - "B 20\n", - "dtype: int64\n", - "B 1\n", - "A 2\n", - "dtype: int64\n" - ] - } - ], - "source": [ - "s1 = pd.Series({\"A\":10, \"B\": 20 })\n", - "s2 = pd.Series({\"B\":1, \"A\": 2 })\n", - "print(s1)\n", - "print(s2)" - ] - }, - { - "cell_type": "code", - "execution_count": 57, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "A 12\n", - "B 21\n", - "dtype: int64" - ] - }, - "execution_count": 57, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# INDEX ALIGNMENT\n", - "s1 + s2" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## How to insert an index-value pair?" - ] - }, - { - "cell_type": "code", - "execution_count": 58, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "A 10\n", - "B 20\n", - "dtype: int64\n" - ] - }, - { - "data": { - "text/plain": [ - "A 10\n", - "B 20\n", - "Z 100\n", - "dtype: int64" - ] - }, - "execution_count": 58, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s = pd.Series({\"A\":10, \"B\": 20 })\n", - "print(s)\n", - "s[\"Z\"] = 100\n", - "s" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Boolean indexing" - ] - }, - { - "cell_type": "code", - "execution_count": 59, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "0 10\n", - "1 2\n", - "2 3\n", - "3 15\n", - "dtype: int64" - ] - }, - "execution_count": 59, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s = pd.Series([10, 2, 3, 15])\n", - "s" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## How to extract numbers > 8?" - ] - }, - { - "cell_type": "code", - "execution_count": 60, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "0 True\n", - "1 False\n", - "2 False\n", - "3 True\n", - "dtype: bool" - ] - }, - "execution_count": 60, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "b = pd.Series([True, False, False, True])\n", - "b" - ] - }, - { - "cell_type": "code", - "execution_count": 61, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "0 10\n", - "3 15\n", - "dtype: int64" - ] - }, - "execution_count": 61, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s[b]" - ] - }, - { - "cell_type": "code", - "execution_count": 62, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "0 10\n", - "1 2\n", - "2 3\n", - "3 15\n", - "dtype: int64" - ] - }, - "execution_count": 62, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s" - ] - }, - { - "cell_type": "code", - "execution_count": 63, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "0 True\n", - "1 False\n", - "2 False\n", - "3 True\n", - "dtype: bool" - ] - }, - "execution_count": 63, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "b = s > 8\n", - "b" - ] - }, - { - "cell_type": "code", - "execution_count": 64, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "0 10\n", - "3 15\n", - "dtype: int64" - ] - }, - "execution_count": 64, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s[b]" - ] - }, - { - "cell_type": "code", - "execution_count": 65, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "0 10\n", - "3 15\n", - "dtype: int64" - ] - }, - "execution_count": 65, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s[s > 8]" - ] - }, - { - "cell_type": "code", - "execution_count": 66, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "0 10\n", - "3 15\n", - "dtype: int64" - ] - }, - "execution_count": 66, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s[pd.Series([True, False, False, True])]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Element-wise String operations" - ] - }, - { - "cell_type": "code", - "execution_count": 67, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "0 APPLE\n", - "1 boy\n", - "2 CAT\n", - "3 dog\n", - "dtype: object" - ] - }, - "execution_count": 67, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "words = pd.Series([\"APPLE\", \"boy\", \"CAT\", \"dog\"])\n", - "words" - ] - }, - { - "cell_type": "code", - "execution_count": 68, - "metadata": {}, - "outputs": [], - "source": [ - "# words.upper() # can't call string functions on Series" - ] - }, - { - "cell_type": "code", - "execution_count": 69, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "0 APPLE\n", - "1 BOY\n", - "2 CAT\n", - "3 DOG\n", - "dtype: object" - ] - }, - "execution_count": 69, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "words.str.upper()" - ] - }, - { - "cell_type": "code", - "execution_count": 70, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "0 True\n", - "1 False\n", - "2 True\n", - "3 False\n", - "dtype: bool" - ] - }, - "execution_count": 70, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "#words[BOOLEAN SERIES]\n", - "#How do we get BOOLEAN SERIES?\n", - "b = words == words.str.upper()\n", - "b" - ] - }, - { - "cell_type": "code", - "execution_count": 71, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "0 APPLE\n", - "2 CAT\n", - "dtype: object" - ] - }, - "execution_count": 71, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "words[b]" - ] - }, - { - "cell_type": "code", - "execution_count": 72, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "0 APPLE\n", - "2 CAT\n", - "dtype: object" - ] - }, - "execution_count": 72, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "words[words == words.str.upper()]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## How to get the odd numbers from a list?" - ] - }, - { - "cell_type": "code", - "execution_count": 73, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "0 10\n", - "1 19\n", - "2 11\n", - "3 30\n", - "4 35\n", - "dtype: int64" - ] - }, - "execution_count": 73, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s = pd.Series([10, 19, 11, 30, 35])\n", - "s" - ] - }, - { - "cell_type": "code", - "execution_count": 74, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "0 0\n", - "1 1\n", - "2 1\n", - "3 0\n", - "4 1\n", - "dtype: int64" - ] - }, - "execution_count": 74, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s % 2" - ] - }, - { - "cell_type": "code", - "execution_count": 75, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "0 False\n", - "1 True\n", - "2 True\n", - "3 False\n", - "4 True\n", - "dtype: bool" - ] - }, - "execution_count": 75, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "b = s % 2 == 1\n", - "b" - ] - }, - { - "cell_type": "code", - "execution_count": 76, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "0 10\n", - "1 19\n", - "2 11\n", - "3 30\n", - "4 35\n", - "dtype: int64" - ] - }, - "execution_count": 76, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s" - ] - }, - { - "cell_type": "code", - "execution_count": 77, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "1 19\n", - "2 11\n", - "4 35\n", - "dtype: int64" - ] - }, - "execution_count": 77, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s[b]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## BOOLEAN OPERATORS on series: and, or, not " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## How to get numbers < 12 or numbers > 33?" - ] - }, - { - "cell_type": "code", - "execution_count": 78, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "0 10\n", - "1 19\n", - "2 11\n", - "3 30\n", - "4 35\n", - "dtype: int64" - ] - }, - "execution_count": 78, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s" - ] - }, - { - "cell_type": "code", - "execution_count": 79, - "metadata": {}, - "outputs": [], - "source": [ - "# s[s < 12 or s > 33] # doesn't work with or, and, not" - ] - }, - { - "cell_type": "code", - "execution_count": 80, - "metadata": {}, - "outputs": [ - { - "ename": "ValueError", - "evalue": "The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m<ipython-input-80-743185dad521>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;31m# use | instead of or\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0ms\u001b[0m\u001b[0;34m[\u001b[0m \u001b[0ms\u001b[0m \u001b[0;34m<\u001b[0m \u001b[0;36m12\u001b[0m \u001b[0;34m|\u001b[0m \u001b[0ms\u001b[0m \u001b[0;34m>\u001b[0m \u001b[0;36m33\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 3\u001b[0m \u001b[0;31m# error because precedence is so high\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0;31m# s[ s < (12 | s) > 33]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/opt/anaconda3/lib/python3.8/site-packages/pandas/core/generic.py\u001b[0m in \u001b[0;36m__nonzero__\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 1440\u001b[0m \u001b[0;34m@\u001b[0m\u001b[0mfinal\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1441\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0m__nonzero__\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1442\u001b[0;31m raise ValueError(\n\u001b[0m\u001b[1;32m 1443\u001b[0m \u001b[0;34mf\"The truth value of a {type(self).__name__} is ambiguous. \"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1444\u001b[0m \u001b[0;34m\"Use a.empty, a.bool(), a.item(), a.any() or a.all().\"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;31mValueError\u001b[0m: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all()." - ] - } - ], - "source": [ - "# use | instead of or\n", - "s[ s < 12 | s > 33]\n", - "# error because precedence is so high\n", - "# s[ s < (12 | s) > 33]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Use lots of parenthesis\n", - "s[ (s < 12) | (s > 33)]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# AND is &\n", - "s[ (s > 12) & (s < 33)]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# NOT is ~\n", - "s[ ~((s > 12) & (s < 33))]" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "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.8.8" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/f22/meena_lec_notes/lec-29/lec_29_web1.ipynb b/f22/meena_lec_notes/lec-29/lec_29_web1.ipynb index e214a4a..655dcac 100644 --- a/f22/meena_lec_notes/lec-29/lec_29_web1.ipynb +++ b/f22/meena_lec_notes/lec-29/lec_29_web1.ipynb @@ -1375,7 +1375,7 @@ "metadata": {}, "source": [ "## requests.get : Simple string example\n", - "- URL: https://www.msyamkumar.com/hello.txt" + "- URL: https://cs220.cs.wisc.edu/hello.txt" ] }, { @@ -1394,7 +1394,7 @@ } ], "source": [ - "url = \"https://www.msyamkumar.com/hello.txt\"\n", + "url = \"https://cs220.cs.wisc.edu/hello.txt\"\n", "r = requests.get(url) # r is the response\n", "print(r.status_code)\n", "print(r.text)" @@ -1409,20 +1409,38 @@ "name": "stdout", "output_type": "stream", "text": [ - "404\n", - "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n", - "<Error><Code>NoSuchKey</Code><Message>The specified key does not exist.</Message><Key>meena/hello.txttttt</Key><RequestId>9PAFR0FANW1CRPTP</RequestId><HostId>Y+VL63r3qTktX1ZLIpaUvaSXOhstWA4yhSSA6RKCRumeA5+WK+ht7TbROpUZtVjmpGT/QaJcYA0=</HostId></Error>\n" + "403\n", + "<html>\n", + "<head><title>403 Forbidden</title></head>\n", + "<body>\n", + "<h1>403 Forbidden</h1>\n", + "<ul>\n", + "<li>Code: AccessDenied</li>\n", + "<li>Message: Access Denied</li>\n", + "<li>RequestId: RSKJ3EYVNRYREDMQ</li>\n", + "<li>HostId: l6ZMrsw5g6KOT3fA0zTwyNHdXcngrnGkpT2nJe92rIBllfDi2Vbrz6jLPcUVl3yvQ+45SAg8ebg=</li>\n", + "</ul>\n", + "<h3>An Error Occurred While Attempting to Retrieve a Custom Error Document</h3>\n", + "<ul>\n", + "<li>Code: AccessDenied</li>\n", + "<li>Message: Access Denied</li>\n", + "</ul>\n", + "<hr/>\n", + "</body>\n", + "</html>\n", + "\n" ] } ], "source": [ "# Q: What if the web site does not exist?\n", - "typo_url = \"https://www.msyamkumar.com/hello.txttttt\"\n", + "typo_url = \"https://cs220.cs.wisc.edu/hello.txttttt\"\n", "r = requests.get(typo_url)\n", "print(r.status_code)\n", "print(r.text)\n", "\n", - "# A: We get a 404 (client error)" + "# A: We get a 403 (Forbidden error)\n", + "# The most common error that you will encounter is 404 (File not found)" ] }, { @@ -1437,14 +1455,14 @@ "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mAssertionError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m/var/folders/k6/kcy8b4f57hx9f1wh4sbs8mn40000gn/T/ipykernel_11873/2682133174.py\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0mtypo_url\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m\"https://www.msyamkumar.com/hello.txttttt\"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[0mr\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mrequests\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtypo_url\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 4\u001b[0;31m \u001b[0;32massert\u001b[0m \u001b[0mr\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mstatus_code\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;36m200\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 5\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mr\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mstatus_code\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 6\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mr\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtext\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "Input \u001b[0;32mIn [14]\u001b[0m, in \u001b[0;36m<cell line: 4>\u001b[0;34m()\u001b[0m\n\u001b[1;32m 2\u001b[0m typo_url \u001b[38;5;241m=\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mhttps://cs220.cs.wisc.edu/hello.txttttt\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m 3\u001b[0m r \u001b[38;5;241m=\u001b[39m requests\u001b[38;5;241m.\u001b[39mget(typo_url)\n\u001b[0;32m----> 4\u001b[0m \u001b[38;5;28;01massert\u001b[39;00m r\u001b[38;5;241m.\u001b[39mstatus_code \u001b[38;5;241m==\u001b[39m \u001b[38;5;241m200\u001b[39m\n\u001b[1;32m 5\u001b[0m \u001b[38;5;28mprint\u001b[39m(r\u001b[38;5;241m.\u001b[39mstatus_code)\n\u001b[1;32m 6\u001b[0m \u001b[38;5;28mprint\u001b[39m(r\u001b[38;5;241m.\u001b[39mtext)\n", "\u001b[0;31mAssertionError\u001b[0m: " ] } ], "source": [ "# We can check for a status_code error by using an assert\n", - "typo_url = \"https://www.msyamkumar.com/hello.txttttt\"\n", + "typo_url = \"https://cs220.cs.wisc.edu/hello.txttttt\"\n", "r = requests.get(typo_url)\n", "assert r.status_code == 200\n", "print(r.status_code)\n", @@ -1458,14 +1476,14 @@ "outputs": [ { "ename": "HTTPError", - "evalue": "404 Client Error: Not Found for url: https://www.msyamkumar.com/hello.txttttt", + "evalue": "403 Client Error: Forbidden for url: https://cs220.cs.wisc.edu/hello.txttttt", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mHTTPError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m/var/folders/k6/kcy8b4f57hx9f1wh4sbs8mn40000gn/T/ipykernel_11873/4051826470.py\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;31m# Instead of using an assert, we often use raise_for_status()\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0mr\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mrequests\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtypo_url\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 3\u001b[0;31m \u001b[0mr\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mraise_for_status\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;31m#similar to asserting r.status_code == 200\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 4\u001b[0m \u001b[0mr\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtext\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/opt/anaconda3/lib/python3.9/site-packages/requests/models.py\u001b[0m in \u001b[0;36mraise_for_status\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 951\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 952\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mhttp_error_msg\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 953\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mHTTPError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mhttp_error_msg\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mresponse\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 954\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 955\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mclose\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;31mHTTPError\u001b[0m: 404 Client Error: Not Found for url: https://www.msyamkumar.com/hello.txttttt" + "Input \u001b[0;32mIn [15]\u001b[0m, in \u001b[0;36m<cell line: 3>\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[38;5;66;03m# Instead of using an assert, we often use raise_for_status()\u001b[39;00m\n\u001b[1;32m 2\u001b[0m r \u001b[38;5;241m=\u001b[39m requests\u001b[38;5;241m.\u001b[39mget(typo_url)\n\u001b[0;32m----> 3\u001b[0m \u001b[43mr\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mraise_for_status\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m \u001b[38;5;66;03m#similar to asserting r.status_code == 200\u001b[39;00m\n\u001b[1;32m 4\u001b[0m r\u001b[38;5;241m.\u001b[39mtext\n", + "File \u001b[0;32m~/opt/anaconda3/lib/python3.9/site-packages/requests/models.py:960\u001b[0m, in \u001b[0;36mResponse.raise_for_status\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 957\u001b[0m http_error_msg \u001b[38;5;241m=\u001b[39m \u001b[38;5;124mu\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;132;01m%s\u001b[39;00m\u001b[38;5;124m Server Error: \u001b[39m\u001b[38;5;132;01m%s\u001b[39;00m\u001b[38;5;124m for url: \u001b[39m\u001b[38;5;132;01m%s\u001b[39;00m\u001b[38;5;124m'\u001b[39m \u001b[38;5;241m%\u001b[39m (\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mstatus_code, reason, \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39murl)\n\u001b[1;32m 959\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m http_error_msg:\n\u001b[0;32m--> 960\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m HTTPError(http_error_msg, response\u001b[38;5;241m=\u001b[39m\u001b[38;5;28mself\u001b[39m)\n", + "\u001b[0;31mHTTPError\u001b[0m: 403 Client Error: Forbidden for url: https://cs220.cs.wisc.edu/hello.txttttt" ] } ], @@ -1484,19 +1502,10 @@ "metadata": {}, "outputs": [ { - "ename": "NameError", - "evalue": "name 'HTTPError' is not defined", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mHTTPError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m/var/folders/k6/kcy8b4f57hx9f1wh4sbs8mn40000gn/T/ipykernel_11873/2028031330.py\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0mr\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mrequests\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtypo_url\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 5\u001b[0;31m \u001b[0mr\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mraise_for_status\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;31m#similar to asserting r.status_code == 200\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 6\u001b[0m \u001b[0mr\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtext\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/opt/anaconda3/lib/python3.9/site-packages/requests/models.py\u001b[0m in \u001b[0;36mraise_for_status\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 952\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mhttp_error_msg\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 953\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mHTTPError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mhttp_error_msg\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mresponse\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 954\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;31mHTTPError\u001b[0m: 404 Client Error: Not Found for url: https://www.msyamkumar.com/hello.txttttt", - "\nDuring handling of the above exception, another exception occurred:\n", - "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m/var/folders/k6/kcy8b4f57hx9f1wh4sbs8mn40000gn/T/ipykernel_11873/2028031330.py\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0mr\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mraise_for_status\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;31m#similar to asserting r.status_code == 200\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 6\u001b[0m \u001b[0mr\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtext\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 7\u001b[0;31m \u001b[0;32mexcept\u001b[0m \u001b[0mHTTPError\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0me\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;31m# What's still wrong here?\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 8\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"oops!!\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0me\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;31mNameError\u001b[0m: name 'HTTPError' is not defined" + "name": "stdout", + "output_type": "stream", + "text": [ + "oops!! 403 Client Error: Forbidden for url: https://cs220.cs.wisc.edu/hello.txttttt\n" ] } ], @@ -1507,15 +1516,23 @@ " r = requests.get(typo_url)\n", " r.raise_for_status() #similar to asserting r.status_code == 200\n", " r.text\n", - "except HTTPError as e: # What's still wrong here?\n", + "except requests.exceptions.HTTPError as e: # What's still wrong here?\n", " print(\"oops!!\", e)" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 17, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "oops!! 403 Client Error: Forbidden for url: https://cs220.cs.wisc.edu/hello.txttttt\n" + ] + } + ], "source": [ "# we often need to prepend the names of exceptions with the name of the module\n", "# fix the error from above\n", @@ -1525,8 +1542,7 @@ " r.raise_for_status() #similar to asserting r.status_code == 200\n", " r.text\n", "except requests.HTTPError as e: #correct way to catch the error.\n", - " print(\"oops!!\", e)\n", - " \n" + " print(\"oops!!\", e)" ] }, { @@ -1534,14 +1550,14 @@ "metadata": {}, "source": [ "## requests.get : JSON file example\n", - "- URL: https://www.msyamkumar.com/scores.json\n", + "- URL: https://cs220.cs.wisc.edu/scores.json\n", "- `json.load` (FILE_OBJECT)\n", "- `json.loads` (STRING)" ] }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 18, "metadata": {}, "outputs": [ { @@ -1560,7 +1576,7 @@ ], "source": [ "# GETting a JSON file, the long way\n", - "url = \"https://www.msyamkumar.com/scores.json\"\n", + "url = \"https://cs220.cs.wisc.edu/scores.json\"\n", "r = requests.get(url)\n", "r.raise_for_status()\n", "urltext = r.text\n", @@ -1571,7 +1587,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 19, "metadata": {}, "outputs": [ { @@ -1584,7 +1600,7 @@ ], "source": [ "# GETting a JSON file, the shortcut way\n", - "url = \"https://www.msyamkumar.com/scores.json\"\n", + "url = \"https://cs220.cs.wisc.edu/scores.json\"\n", "#Shortcut to bypass using json.loads()\n", "r = requests.get(url)\n", "r.raise_for_status()\n", @@ -1610,1597 +1626,761 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## DEMO: Course Enrollment" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Explore the API!\n", - "\n", - "https://coletnelson.us/cs220-api/classes\n", - "\n", - "https://coletnelson.us/cs220-api/classes_as_txt\n", - "\n", - "https://coletnelson.us/cs220-api/classes/MATH_221\n", + "### Explore real-world JSON\n", "\n", - "https://coletnelson.us/cs220-api/classes/COMPSCI_200\n", + "How to explore an unknown JSON?\n", + "- If you run into a `dict`, try `.keys()` method to look at the keys of the dictionary, then use lookup process to explore further\n", + "- If you run into a `list`, iterate over the list and print each item\n", "\n", - "... etc\n", - "\n", - "https://coletnelson.us/cs220-api/all_data" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Get the list of classes." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### When the data is `json`" + "### Weather for UW-Madison campus\n", + "- URL: https://api.weather.gov/gridpoints/MKX/37,63/forecast" ] }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 20, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "<class 'list'>\n", - "['PSYCH_202', 'COMPSCI_537', 'COMPSCI_300', 'CHEM_104', 'COMPSCI_200', 'MATH_114', 'PSYCH_456', 'COMPSCI_252', 'COMPSCI_400', 'MATH_221', 'BIOLOGY_101', 'COMPSCI_354', 'CHEM_103', 'COMPSCI_639', 'PSYCH_401', 'COMPSCI_240', 'STATS_302']\n" + "<class 'dict'>\n" ] } ], "source": [ - "url = \"https://coletnelson.us/cs220-api/classes\"\n", + "# TODO: GET the forecast\n", + "url = \"https://api.weather.gov/gridpoints/MKX/37,63/forecast\"\n", "r = requests.get(url)\n", "r.raise_for_status()\n", - "classes_list = r.json()\n", - "print(type(classes_list))\n", - "print(classes_list)" + "weather_data = r.json()\n", + "\n", + "# TODO: explore the type of the data structure \n", + "print(type(weather_data))\n", + "\n", + "# display the data\n", + "# weather_data # uncomment to see the whole JSON" ] }, { - "cell_type": "markdown", + "cell_type": "code", + "execution_count": 21, "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "['@context', 'type', 'geometry', 'properties']\n", + "<class 'dict'>\n" + ] + } + ], "source": [ - "#### When the data is `text`" + "# TODO: display the keys of the weather_data dict\n", + "print(list(weather_data.keys()))\n", + "\n", + "# TODO: lookup the value corresponding to the 'properties'\n", + "weather_data[\"properties\"]\n", + "\n", + "# TODO: you know what to do next ... explore type again\n", + "print(type(weather_data[\"properties\"]))" ] }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 22, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "<class 'str'>\n", - "PSYCH_202\n", - "COMPSCI_537\n", - "COMPSCI_300\n", - "CHEM_104\n", - "COMPSCI_200\n", - "MATH_114\n", - "PSYCH_456\n", - "COMPSCI_252\n", - "COMPSCI_400\n", - "MATH_221\n", - "BIOLOGY_101\n", - "COMPSCI_354\n", - "CHEM_103\n", - "COMPSCI_639\n", - "PSYCH_401\n", - "COMPSCI_240\n", - "STATS_302\n" + "['updated', 'units', 'forecastGenerator', 'generatedAt', 'updateTime', 'validTimes', 'elevation', 'periods']\n", + "<class 'list'>\n" ] } ], "source": [ - "url = \"https://coletnelson.us/cs220-api/classes_as_txt\"\n", - "r = requests.get(url)\n", - "r.raise_for_status()\n", - "classes_txt = r.text\n", - "print(type(classes_txt))\n", - "print(classes_txt)" + "# TODO: display the keys of the properties dict\n", + "print(list(weather_data[\"properties\"].keys()))\n", + "\n", + "# TODO: lookup the value corresponding to the 'periods'\n", + "# weather_data[\"properties\"][\"periods\"] # uncomment to see the output\n", + "\n", + "# TODO: you know what to do next ... explore type again\n", + "print(type(weather_data[\"properties\"][\"periods\"]))" ] }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 23, "metadata": {}, "outputs": [ { "data": { + "text/html": [ + "<div>\n", + "<style scoped>\n", + " .dataframe tbody tr th:only-of-type {\n", + " vertical-align: middle;\n", + " }\n", + "\n", + " .dataframe tbody tr th {\n", + " vertical-align: top;\n", + " }\n", + "\n", + " .dataframe thead th {\n", + " text-align: right;\n", + " }\n", + "</style>\n", + "<table border=\"1\" class=\"dataframe\">\n", + " <thead>\n", + " <tr style=\"text-align: right;\">\n", + " <th></th>\n", + " <th>number</th>\n", + " <th>name</th>\n", + " <th>startTime</th>\n", + " <th>endTime</th>\n", + " <th>isDaytime</th>\n", + " <th>temperature</th>\n", + " <th>temperatureUnit</th>\n", + " <th>temperatureTrend</th>\n", + " <th>windSpeed</th>\n", + " <th>windDirection</th>\n", + " <th>icon</th>\n", + " <th>shortForecast</th>\n", + " <th>detailedForecast</th>\n", + " </tr>\n", + " </thead>\n", + " <tbody>\n", + " <tr>\n", + " <th>0</th>\n", + " <td>1</td>\n", + " <td>Today</td>\n", + " <td>2022-11-16T08:00:00-06:00</td>\n", + " <td>2022-11-16T18:00:00-06:00</td>\n", + " <td>True</td>\n", + " <td>34</td>\n", + " <td>F</td>\n", + " <td>None</td>\n", + " <td>5 to 10 mph</td>\n", + " <td>NW</td>\n", + " <td>https://api.weather.gov/icons/land/day/snow,60...</td>\n", + " <td>Snow Showers Likely</td>\n", + " <td>Snow showers likely. Cloudy, with a high near ...</td>\n", + " </tr>\n", + " <tr>\n", + " <th>1</th>\n", + " <td>2</td>\n", + " <td>Tonight</td>\n", + " <td>2022-11-16T18:00:00-06:00</td>\n", + " <td>2022-11-17T06:00:00-06:00</td>\n", + " <td>False</td>\n", + " <td>23</td>\n", + " <td>F</td>\n", + " <td>None</td>\n", + " <td>5 to 10 mph</td>\n", + " <td>W</td>\n", + " <td>https://api.weather.gov/icons/land/night/snow?...</td>\n", + " <td>Chance Snow Showers</td>\n", + " <td>A chance of snow showers after 9pm. Mostly clo...</td>\n", + " </tr>\n", + " <tr>\n", + " <th>2</th>\n", + " <td>3</td>\n", + " <td>Thursday</td>\n", + " <td>2022-11-17T06:00:00-06:00</td>\n", + " <td>2022-11-17T18:00:00-06:00</td>\n", + " <td>True</td>\n", + " <td>28</td>\n", + " <td>F</td>\n", + " <td>None</td>\n", + " <td>10 to 15 mph</td>\n", + " <td>W</td>\n", + " <td>https://api.weather.gov/icons/land/day/snow,30...</td>\n", + " <td>Chance Snow Showers</td>\n", + " <td>A chance of snow showers. Mostly cloudy, with ...</td>\n", + " </tr>\n", + " <tr>\n", + " <th>3</th>\n", + " <td>4</td>\n", + " <td>Thursday Night</td>\n", + " <td>2022-11-17T18:00:00-06:00</td>\n", + " <td>2022-11-18T06:00:00-06:00</td>\n", + " <td>False</td>\n", + " <td>17</td>\n", + " <td>F</td>\n", + " <td>None</td>\n", + " <td>15 mph</td>\n", + " <td>W</td>\n", + " <td>https://api.weather.gov/icons/land/night/bkn?s...</td>\n", + " <td>Mostly Cloudy</td>\n", + " <td>Mostly cloudy, with a low around 17. West wind...</td>\n", + " </tr>\n", + " <tr>\n", + " <th>4</th>\n", + " <td>5</td>\n", + " <td>Friday</td>\n", + " <td>2022-11-18T06:00:00-06:00</td>\n", + " <td>2022-11-18T18:00:00-06:00</td>\n", + " <td>True</td>\n", + " <td>23</td>\n", + " <td>F</td>\n", + " <td>None</td>\n", + " <td>15 mph</td>\n", + " <td>W</td>\n", + " <td>https://api.weather.gov/icons/land/day/bkn?siz...</td>\n", + " <td>Mostly Cloudy</td>\n", + " <td>Mostly cloudy, with a high near 23. West wind ...</td>\n", + " </tr>\n", + " <tr>\n", + " <th>5</th>\n", + " <td>6</td>\n", + " <td>Friday Night</td>\n", + " <td>2022-11-18T18:00:00-06:00</td>\n", + " <td>2022-11-19T06:00:00-06:00</td>\n", + " <td>False</td>\n", + " <td>12</td>\n", + " <td>F</td>\n", + " <td>None</td>\n", + " <td>15 mph</td>\n", + " <td>SW</td>\n", + " <td>https://api.weather.gov/icons/land/night/bkn?s...</td>\n", + " <td>Mostly Cloudy</td>\n", + " <td>Mostly cloudy, with a low around 12. Southwest...</td>\n", + " </tr>\n", + " <tr>\n", + " <th>6</th>\n", + " <td>7</td>\n", + " <td>Saturday</td>\n", + " <td>2022-11-19T06:00:00-06:00</td>\n", + " <td>2022-11-19T18:00:00-06:00</td>\n", + " <td>True</td>\n", + " <td>23</td>\n", + " <td>F</td>\n", + " <td>None</td>\n", + " <td>15 mph</td>\n", + " <td>W</td>\n", + " <td>https://api.weather.gov/icons/land/day/bkn/sno...</td>\n", + " <td>Mostly Cloudy then Slight Chance Snow Showers</td>\n", + " <td>A slight chance of snow showers after noon. Mo...</td>\n", + " </tr>\n", + " <tr>\n", + " <th>7</th>\n", + " <td>8</td>\n", + " <td>Saturday Night</td>\n", + " <td>2022-11-19T18:00:00-06:00</td>\n", + " <td>2022-11-20T06:00:00-06:00</td>\n", + " <td>False</td>\n", + " <td>7</td>\n", + " <td>F</td>\n", + " <td>None</td>\n", + " <td>10 to 15 mph</td>\n", + " <td>W</td>\n", + " <td>https://api.weather.gov/icons/land/night/cold?...</td>\n", + " <td>Mostly Cloudy</td>\n", + " <td>Mostly cloudy, with a low around 7. West wind ...</td>\n", + " </tr>\n", + " <tr>\n", + " <th>8</th>\n", + " <td>9</td>\n", + " <td>Sunday</td>\n", + " <td>2022-11-20T06:00:00-06:00</td>\n", + " <td>2022-11-20T18:00:00-06:00</td>\n", + " <td>True</td>\n", + " <td>23</td>\n", + " <td>F</td>\n", + " <td>None</td>\n", + " <td>10 mph</td>\n", + " <td>W</td>\n", + " <td>https://api.weather.gov/icons/land/day/few?siz...</td>\n", + " <td>Sunny</td>\n", + " <td>Sunny, with a high near 23.</td>\n", + " </tr>\n", + " <tr>\n", + " <th>9</th>\n", + " <td>10</td>\n", + " <td>Sunday Night</td>\n", + " <td>2022-11-20T18:00:00-06:00</td>\n", + " <td>2022-11-21T06:00:00-06:00</td>\n", + " <td>False</td>\n", + " <td>15</td>\n", + " <td>F</td>\n", + " <td>rising</td>\n", + " <td>10 mph</td>\n", + " <td>SW</td>\n", + " <td>https://api.weather.gov/icons/land/night/sct?s...</td>\n", + " <td>Partly Cloudy</td>\n", + " <td>Partly cloudy. Low around 15, with temperature...</td>\n", + " </tr>\n", + " <tr>\n", + " <th>10</th>\n", + " <td>11</td>\n", + " <td>Monday</td>\n", + " <td>2022-11-21T06:00:00-06:00</td>\n", + " <td>2022-11-21T18:00:00-06:00</td>\n", + " <td>True</td>\n", + " <td>34</td>\n", + " <td>F</td>\n", + " <td>falling</td>\n", + " <td>5 to 10 mph</td>\n", + " <td>W</td>\n", + " <td>https://api.weather.gov/icons/land/day/few?siz...</td>\n", + " <td>Sunny</td>\n", + " <td>Sunny. High near 34, with temperatures falling...</td>\n", + " </tr>\n", + " <tr>\n", + " <th>11</th>\n", + " <td>12</td>\n", + " <td>Monday Night</td>\n", + " <td>2022-11-21T18:00:00-06:00</td>\n", + " <td>2022-11-22T06:00:00-06:00</td>\n", + " <td>False</td>\n", + " <td>18</td>\n", + " <td>F</td>\n", + " <td>None</td>\n", + " <td>5 mph</td>\n", + " <td>SW</td>\n", + " <td>https://api.weather.gov/icons/land/night/sct?s...</td>\n", + " <td>Partly Cloudy</td>\n", + " <td>Partly cloudy, with a low around 18.</td>\n", + " </tr>\n", + " <tr>\n", + " <th>12</th>\n", + " <td>13</td>\n", + " <td>Tuesday</td>\n", + " <td>2022-11-22T06:00:00-06:00</td>\n", + " <td>2022-11-22T18:00:00-06:00</td>\n", + " <td>True</td>\n", + " <td>36</td>\n", + " <td>F</td>\n", + " <td>falling</td>\n", + " <td>5 to 10 mph</td>\n", + " <td>SW</td>\n", + " <td>https://api.weather.gov/icons/land/day/sct?siz...</td>\n", + " <td>Mostly Sunny</td>\n", + " <td>Mostly sunny. High near 36, with temperatures ...</td>\n", + " </tr>\n", + " <tr>\n", + " <th>13</th>\n", + " <td>14</td>\n", + " <td>Tuesday Night</td>\n", + " <td>2022-11-22T18:00:00-06:00</td>\n", + " <td>2022-11-23T06:00:00-06:00</td>\n", + " <td>False</td>\n", + " <td>26</td>\n", + " <td>F</td>\n", + " <td>None</td>\n", + " <td>5 mph</td>\n", + " <td>S</td>\n", + " <td>https://api.weather.gov/icons/land/night/bkn?s...</td>\n", + " <td>Mostly Cloudy</td>\n", + " <td>Mostly cloudy, with a low around 26.</td>\n", + " </tr>\n", + " </tbody>\n", + "</table>\n", + "</div>" + ], "text/plain": [ - "['PSYCH_202',\n", - " 'COMPSCI_537',\n", - " 'COMPSCI_300',\n", - " 'CHEM_104',\n", - " 'COMPSCI_200',\n", - " 'MATH_114',\n", - " 'PSYCH_456',\n", - " 'COMPSCI_252',\n", - " 'COMPSCI_400',\n", - " 'MATH_221',\n", - " 'BIOLOGY_101',\n", - " 'COMPSCI_354',\n", - " 'CHEM_103',\n", - " 'COMPSCI_639',\n", - " 'PSYCH_401',\n", - " 'COMPSCI_240',\n", - " 'STATS_302']" + " number name startTime \\\n", + "0 1 Today 2022-11-16T08:00:00-06:00 \n", + "1 2 Tonight 2022-11-16T18:00:00-06:00 \n", + "2 3 Thursday 2022-11-17T06:00:00-06:00 \n", + "3 4 Thursday Night 2022-11-17T18:00:00-06:00 \n", + "4 5 Friday 2022-11-18T06:00:00-06:00 \n", + "5 6 Friday Night 2022-11-18T18:00:00-06:00 \n", + "6 7 Saturday 2022-11-19T06:00:00-06:00 \n", + "7 8 Saturday Night 2022-11-19T18:00:00-06:00 \n", + "8 9 Sunday 2022-11-20T06:00:00-06:00 \n", + "9 10 Sunday Night 2022-11-20T18:00:00-06:00 \n", + "10 11 Monday 2022-11-21T06:00:00-06:00 \n", + "11 12 Monday Night 2022-11-21T18:00:00-06:00 \n", + "12 13 Tuesday 2022-11-22T06:00:00-06:00 \n", + "13 14 Tuesday Night 2022-11-22T18:00:00-06:00 \n", + "\n", + " endTime isDaytime temperature temperatureUnit \\\n", + "0 2022-11-16T18:00:00-06:00 True 34 F \n", + "1 2022-11-17T06:00:00-06:00 False 23 F \n", + "2 2022-11-17T18:00:00-06:00 True 28 F \n", + "3 2022-11-18T06:00:00-06:00 False 17 F \n", + "4 2022-11-18T18:00:00-06:00 True 23 F \n", + "5 2022-11-19T06:00:00-06:00 False 12 F \n", + "6 2022-11-19T18:00:00-06:00 True 23 F \n", + "7 2022-11-20T06:00:00-06:00 False 7 F \n", + "8 2022-11-20T18:00:00-06:00 True 23 F \n", + "9 2022-11-21T06:00:00-06:00 False 15 F \n", + "10 2022-11-21T18:00:00-06:00 True 34 F \n", + "11 2022-11-22T06:00:00-06:00 False 18 F \n", + "12 2022-11-22T18:00:00-06:00 True 36 F \n", + "13 2022-11-23T06:00:00-06:00 False 26 F \n", + "\n", + " temperatureTrend windSpeed windDirection \\\n", + "0 None 5 to 10 mph NW \n", + "1 None 5 to 10 mph W \n", + "2 None 10 to 15 mph W \n", + "3 None 15 mph W \n", + "4 None 15 mph W \n", + "5 None 15 mph SW \n", + "6 None 15 mph W \n", + "7 None 10 to 15 mph W \n", + "8 None 10 mph W \n", + "9 rising 10 mph SW \n", + "10 falling 5 to 10 mph W \n", + "11 None 5 mph SW \n", + "12 falling 5 to 10 mph SW \n", + "13 None 5 mph S \n", + "\n", + " icon \\\n", + "0 https://api.weather.gov/icons/land/day/snow,60... \n", + "1 https://api.weather.gov/icons/land/night/snow?... \n", + "2 https://api.weather.gov/icons/land/day/snow,30... \n", + "3 https://api.weather.gov/icons/land/night/bkn?s... \n", + "4 https://api.weather.gov/icons/land/day/bkn?siz... \n", + "5 https://api.weather.gov/icons/land/night/bkn?s... \n", + "6 https://api.weather.gov/icons/land/day/bkn/sno... \n", + "7 https://api.weather.gov/icons/land/night/cold?... \n", + "8 https://api.weather.gov/icons/land/day/few?siz... \n", + "9 https://api.weather.gov/icons/land/night/sct?s... \n", + "10 https://api.weather.gov/icons/land/day/few?siz... \n", + "11 https://api.weather.gov/icons/land/night/sct?s... \n", + "12 https://api.weather.gov/icons/land/day/sct?siz... \n", + "13 https://api.weather.gov/icons/land/night/bkn?s... \n", + "\n", + " shortForecast \\\n", + "0 Snow Showers Likely \n", + "1 Chance Snow Showers \n", + "2 Chance Snow Showers \n", + "3 Mostly Cloudy \n", + "4 Mostly Cloudy \n", + "5 Mostly Cloudy \n", + "6 Mostly Cloudy then Slight Chance Snow Showers \n", + "7 Mostly Cloudy \n", + "8 Sunny \n", + "9 Partly Cloudy \n", + "10 Sunny \n", + "11 Partly Cloudy \n", + "12 Mostly Sunny \n", + "13 Mostly Cloudy \n", + "\n", + " detailedForecast \n", + "0 Snow showers likely. Cloudy, with a high near ... \n", + "1 A chance of snow showers after 9pm. Mostly clo... \n", + "2 A chance of snow showers. Mostly cloudy, with ... \n", + "3 Mostly cloudy, with a low around 17. West wind... \n", + "4 Mostly cloudy, with a high near 23. West wind ... \n", + "5 Mostly cloudy, with a low around 12. Southwest... \n", + "6 A slight chance of snow showers after noon. Mo... \n", + "7 Mostly cloudy, with a low around 7. West wind ... \n", + "8 Sunny, with a high near 23. \n", + "9 Partly cloudy. Low around 15, with temperature... \n", + "10 Sunny. High near 34, with temperatures falling... \n", + "11 Partly cloudy, with a low around 18. \n", + "12 Mostly sunny. High near 36, with temperatures ... \n", + "13 Mostly cloudy, with a low around 26. " ] }, - "execution_count": 21, + "execution_count": 23, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "classes_txt_as_list = classes_txt.split('\\n')\n", - "classes_txt_as_list" + "# TODO: extract periods list into a variable\n", + "periods_list = weather_data[\"properties\"][\"periods\"]\n", + "\n", + "# TODO: create a DataFrame using periods_list\n", + "# TODO: What does each inner data structure represent in your DataFrame?\n", + "# Keep in mind that outer data structure is a list.\n", + "# A. rows (because outer data structure is a list)\n", + "periods_df = DataFrame(periods_list)\n", + "periods_df" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "### Get data for a specific class" + "#### What is the maximum and minimum observed temperatures? Include the temperatureUnit in your display" ] }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 24, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "<class 'dict'>\n", - "{'credits': 3, 'description': 'Learn the process of incrementally developing small (200-500 lines) programs along with the fundamental Computer Science topics. These topics include: problem abstraction and decomposition, the edit-compile-run cycle, using variables of primitive and more complex data types, conditional and loop-based flow control, basic testing and debugging techniques, how to define and call functions (methods), and IO processing techniques. Also teaches and reinforces good programming practices including the use of a consistent style, and meaningful documentation. Intended for students who have no prior programming experience.', 'keywords': ['computer', 'science', 'programming', 'java'], 'name': 'Programming 1', 'number': 'COMPSCI_200', 'requisites': [], 'sections': [{'instructor': 'Jim Williams', 'location': '132 Noland Hall', 'subsections': [{'location': '1350 Computer Sciences and Statistics', 'time': {'wednesday': '9:30am - 10:45am'}, 'number': 'LAB_311'}, {'location': '1350 Computer Sciences and Statistics', 'time': {'wednesday': '11:00am - 12:15pm'}, 'number': 'LAB_312'}, {'location': '1350 Computer Sciences and Statistics', 'time': {'wednesday': '2:30pm - 3:45pm'}, 'number': 'LAB_314'}, {'location': '1350 Computer Sciences and Statistics', 'time': {'wednesday': '4:00pm - 5:15pm'}, 'number': 'LAB_315'}], 'time': {'thursday': '8:00am - 9:15am', 'tuesday': '8:00am - 9:15am'}, 'number': 'LEC_001'}, {'instructor': 'Jim Williams', 'location': '132 Noland Hall', 'subsections': [{'location': '1370 Computer Sciences and Statistics', 'time': {'wednesday': '9:30am - 10:45am'}, 'number': 'LAB_321'}, {'location': '1370 Computer Sciences and Statistics', 'time': {'wednesday': '1:00pm - 2:15pm'}, 'number': 'LAB_323'}, {'location': '1370 Computer Sciences and Statistics', 'time': {'wednesday': '2:30pm - 3:45pm'}, 'number': 'LAB_324'}, {'location': '1370 Computer Sciences and Statistics', 'time': {'wednesday': '4:00pm - 5:15pm'}, 'number': 'LAB_325'}], 'time': {'thursday': '11:00am - 12:15pm', 'tuesday': '11:00am - 12:15pm'}, 'number': 'LEC_002'}, {'instructor': 'Marc Renault', 'location': '113 Brogden Psychology Building', 'subsections': [{'location': '1350 Computer Sciences and Statistics', 'time': {'tuesday': '9:30am - 10:45am'}, 'number': 'LAB_331'}, {'location': '1350 Computer Sciences and Statistics', 'time': {'tuesday': '11:00am - 12:15pm'}, 'number': 'LAB_332'}, {'location': '1350 Computer Sciences and Statistics', 'time': {'tuesday': '1:00pm - 2:15pm'}, 'number': 'LAB_333'}, {'location': '1350 Computer Sciences and Statistics', 'time': {'tuesday': '2:30pm - 3:45pm'}, 'number': 'LAB_334'}], 'time': {'friday': '1:20pm - 2:10pm', 'monday': '1:20pm - 2:10pm', 'wednesday': '1:20pm - 2:10pm'}, 'number': 'LEC_003'}, {'instructor': 'Marc Renault', 'location': '113 Brogden Psychology Building', 'subsections': [{'location': '1370 Computer Sciences and Statistics', 'time': {'tuesday': '9:30am - 10:45am'}, 'number': 'LAB_341'}, {'location': '1370 Computer Sciences and Statistics', 'time': {'tuesday': '11:00am - 12:15pm'}, 'number': 'LAB_342'}, {'location': '1370 Computer Sciences and Statistics', 'time': {'tuesday': '1:00pm - 2:15pm'}, 'number': 'LAB_343'}, {'location': '1370 Computer Sciences and Statistics', 'time': {'tuesday': '2:30pm - 3:45pm'}, 'number': 'LAB_344'}, {'location': '1370 Computer Sciences and Statistics', 'time': {'tuesday': '4:00pm - 5:15pm'}, 'number': 'LAB_345'}], 'time': {'friday': '3:30pm - 4:20pm', 'monday': '3:30pm - 4:20pm', 'wednesday': '3:30pm - 4:20pm'}, 'number': 'LEC_004'}], 'subject': 'Computer Science'}\n" + "Minimum observed temperature is: 7 degree F\n", + "Maximum observed temperature is: 36 degree F\n" ] } ], "source": [ - "url = \"https://coletnelson.us/cs220-api/classes/COMPSCI_200\"\n", - "r = requests.get(url)\n", - "r.raise_for_status()\n", - "cs200_data = r.json()\n", - "print(type(cs200_data))\n", - "print(cs200_data) # Too much data? Try print(cs220_data.keys())" + "min_temp = periods_df[\"temperature\"].min()\n", + "idx_min = periods_df[\"temperature\"].idxmin()\n", + "min_unit = periods_df.loc[idx_min, \"temperatureUnit\"]\n", + "\n", + "max_temp = periods_df[\"temperature\"].max()\n", + "idx_max = periods_df[\"temperature\"].idxmax()\n", + "max_unit = periods_df.loc[idx_max, \"temperatureUnit\"]\n", + "\n", + "print(\"Minimum observed temperature is: {} degree {}\".format(min_temp, min_unit))\n", + "print(\"Maximum observed temperature is: {} degree {}\".format(max_temp, max_unit))" ] }, { - "cell_type": "code", - "execution_count": 23, + "cell_type": "markdown", "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "dict_keys(['credits', 'description', 'keywords', 'name', 'number', 'requisites', 'sections', 'subject'])" - ] - }, - "execution_count": 23, - "metadata": {}, - "output_type": "execute_result" - } - ], "source": [ - "cs200_data.keys()" + "#### Which days `detailedForecast` contains `snow`?" ] }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 25, "metadata": {}, "outputs": [ { "data": { + "text/html": [ + "<div>\n", + "<style scoped>\n", + " .dataframe tbody tr th:only-of-type {\n", + " vertical-align: middle;\n", + " }\n", + "\n", + " .dataframe tbody tr th {\n", + " vertical-align: top;\n", + " }\n", + "\n", + " .dataframe thead th {\n", + " text-align: right;\n", + " }\n", + "</style>\n", + "<table border=\"1\" class=\"dataframe\">\n", + " <thead>\n", + " <tr style=\"text-align: right;\">\n", + " <th></th>\n", + " <th>number</th>\n", + " <th>name</th>\n", + " <th>startTime</th>\n", + " <th>endTime</th>\n", + " <th>isDaytime</th>\n", + " <th>temperature</th>\n", + " <th>temperatureUnit</th>\n", + " <th>temperatureTrend</th>\n", + " <th>windSpeed</th>\n", + " <th>windDirection</th>\n", + " <th>icon</th>\n", + " <th>shortForecast</th>\n", + " <th>detailedForecast</th>\n", + " </tr>\n", + " </thead>\n", + " <tbody>\n", + " <tr>\n", + " <th>0</th>\n", + " <td>1</td>\n", + " <td>Today</td>\n", + " <td>2022-11-16T08:00:00-06:00</td>\n", + " <td>2022-11-16T18:00:00-06:00</td>\n", + " <td>True</td>\n", + " <td>34</td>\n", + " <td>F</td>\n", + " <td>None</td>\n", + " <td>5 to 10 mph</td>\n", + " <td>NW</td>\n", + " <td>https://api.weather.gov/icons/land/day/snow,60...</td>\n", + " <td>Snow Showers Likely</td>\n", + " <td>Snow showers likely. Cloudy, with a high near ...</td>\n", + " </tr>\n", + " <tr>\n", + " <th>1</th>\n", + " <td>2</td>\n", + " <td>Tonight</td>\n", + " <td>2022-11-16T18:00:00-06:00</td>\n", + " <td>2022-11-17T06:00:00-06:00</td>\n", + " <td>False</td>\n", + " <td>23</td>\n", + " <td>F</td>\n", + " <td>None</td>\n", + " <td>5 to 10 mph</td>\n", + " <td>W</td>\n", + " <td>https://api.weather.gov/icons/land/night/snow?...</td>\n", + " <td>Chance Snow Showers</td>\n", + " <td>A chance of snow showers after 9pm. Mostly clo...</td>\n", + " </tr>\n", + " <tr>\n", + " <th>2</th>\n", + " <td>3</td>\n", + " <td>Thursday</td>\n", + " <td>2022-11-17T06:00:00-06:00</td>\n", + " <td>2022-11-17T18:00:00-06:00</td>\n", + " <td>True</td>\n", + " <td>28</td>\n", + " <td>F</td>\n", + " <td>None</td>\n", + " <td>10 to 15 mph</td>\n", + " <td>W</td>\n", + " <td>https://api.weather.gov/icons/land/day/snow,30...</td>\n", + " <td>Chance Snow Showers</td>\n", + " <td>A chance of snow showers. Mostly cloudy, with ...</td>\n", + " </tr>\n", + " <tr>\n", + " <th>6</th>\n", + " <td>7</td>\n", + " <td>Saturday</td>\n", + " <td>2022-11-19T06:00:00-06:00</td>\n", + " <td>2022-11-19T18:00:00-06:00</td>\n", + " <td>True</td>\n", + " <td>23</td>\n", + " <td>F</td>\n", + " <td>None</td>\n", + " <td>15 mph</td>\n", + " <td>W</td>\n", + " <td>https://api.weather.gov/icons/land/day/bkn/sno...</td>\n", + " <td>Mostly Cloudy then Slight Chance Snow Showers</td>\n", + " <td>A slight chance of snow showers after noon. Mo...</td>\n", + " </tr>\n", + " </tbody>\n", + "</table>\n", + "</div>" + ], "text/plain": [ - "3" + " number name startTime endTime \\\n", + "0 1 Today 2022-11-16T08:00:00-06:00 2022-11-16T18:00:00-06:00 \n", + "1 2 Tonight 2022-11-16T18:00:00-06:00 2022-11-17T06:00:00-06:00 \n", + "2 3 Thursday 2022-11-17T06:00:00-06:00 2022-11-17T18:00:00-06:00 \n", + "6 7 Saturday 2022-11-19T06:00:00-06:00 2022-11-19T18:00:00-06:00 \n", + "\n", + " isDaytime temperature temperatureUnit temperatureTrend windSpeed \\\n", + "0 True 34 F None 5 to 10 mph \n", + "1 False 23 F None 5 to 10 mph \n", + "2 True 28 F None 10 to 15 mph \n", + "6 True 23 F None 15 mph \n", + "\n", + " windDirection icon \\\n", + "0 NW https://api.weather.gov/icons/land/day/snow,60... \n", + "1 W https://api.weather.gov/icons/land/night/snow?... \n", + "2 W https://api.weather.gov/icons/land/day/snow,30... \n", + "6 W https://api.weather.gov/icons/land/day/bkn/sno... \n", + "\n", + " shortForecast \\\n", + "0 Snow Showers Likely \n", + "1 Chance Snow Showers \n", + "2 Chance Snow Showers \n", + "6 Mostly Cloudy then Slight Chance Snow Showers \n", + "\n", + " detailedForecast \n", + "0 Snow showers likely. Cloudy, with a high near ... \n", + "1 A chance of snow showers after 9pm. Mostly clo... \n", + "2 A chance of snow showers. Mostly cloudy, with ... \n", + "6 A slight chance of snow showers after noon. Mo... " ] }, - "execution_count": 24, + "execution_count": 25, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "# Get the number of credits the course is worth\n", - "cs200_data['credits']" + "# What courses contain the keyword \"programming\"?\n", + "snow_days_df = periods_df[periods_df[\"detailedForecast\"].str.contains(\"snow\")]\n", + "snow_days_df" ] }, { "cell_type": "code", - "execution_count": 25, + "execution_count": 26, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "['computer', 'science', 'programming', 'java']" + "0 Today\n", + "1 Tonight\n", + "2 Thursday\n", + "6 Saturday\n", + "Name: name, dtype: object" ] }, - "execution_count": 25, + "execution_count": 26, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "# Get the list of keywords for the course\n", - "cs200_data['keywords']" + "snow_days_df[\"name\"]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Which day's `detailedForecast` has the most lengthy description?" ] }, { "cell_type": "code", - "execution_count": 26, + "execution_count": 27, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "'Programming 1'" + "'Thursday'" ] }, - "execution_count": 26, + "execution_count": 27, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "# Get the official course name\n", - "cs200_data['name']" + "idx_max_desc = periods_df[\"detailedForecast\"].str.len().idxmax()\n", + "periods_df.iloc[idx_max_desc]['name']" ] }, { "cell_type": "code", - "execution_count": 27, + "execution_count": 28, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "4" + "'A chance of snow showers. Mostly cloudy, with a high near 28. West wind 10 to 15 mph, with gusts as high as 25 mph. Chance of precipitation is 30%. New snow accumulation of less than half an inch possible.'" ] }, - "execution_count": 27, + "execution_count": 28, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "# Get the number of sections offered.\n", - "len(cs200_data['sections'])" + "# What was that forecast?\n", + "periods_df.iloc[idx_max_desc]['detailedForecast']" ] }, { - "cell_type": "code", - "execution_count": 28, + "cell_type": "markdown", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[{'credits': 3, 'description': 'Behavior, including its development, motivation, frustrations, emotion, intelligence, learning, forgetting, personality, language, thinking, and social behavior.', 'keywords': ['psychology', 'behavior', 'emotion', 'intelligence', 'brain'], 'name': 'Introduction to Psychology', 'number': 'PSYCH_202', 'requisites': [], 'sections': [{'instructor': 'Jeff Henriques', 'location': '105 Brogden Psychology Building', 'subsections': [], 'time': {'thursday': '9:30am - 10:45am', 'tuesday': '9:30am - 10:45am'}, 'number': 'LEC_001'}, {'instructor': 'Jeff Henriques', 'location': '105 Brogden Psychology Building', 'subsections': [], 'time': {'thursday': '11:00am - 12:15pm', 'tuesday': '11:00am - 12:15pm'}, 'number': 'LEC_002'}, {'instructor': 'C. Shawn Green', 'location': '105 Brogden Psychology Building', 'subsections': [], 'time': {'monday': '8:00am - 9:15am', 'wednesday': '8:00am - 9:15am'}, 'number': 'LEC_003'}, {'instructor': 'Patti Coffey', 'location': '105 Brogden Psychology Building', 'subsections': [], 'time': {'thursday': '1:00pm - 2:15pm', 'tuesday': '1:00pm - 2:15pm'}, 'number': 'LEC_004'}, {'instructor': 'Sarah Gavac', 'location': '105 Brogden Psychology Building', 'subsections': [], 'time': {'thursday': '2:30pm - 3:45pm', 'tuesday': '2:30pm - 3:45pm'}, 'number': 'LEC_005'}, {'instructor': 'Patti Coffey', 'location': '101 Brogden Psychology Building', 'subsections': [], 'time': {'thursday': '2:30pm - 3:45pm', 'tuesday': '2:30pm - 3:45pm'}, 'number': 'LEC_006'}, {'instructor': 'Baoyu Wang', 'location': '105 Brogden Psychology Building', 'subsections': [], 'time': {'monday': '4:30pm - 5:15pm', 'wednesday': '4:30pm - 5:15pm'}, 'number': 'LEC_009'}], 'subject': 'Psychology'}, {'credits': 4, 'description': 'Input-output hardware, interrupt handling, properties of magnetic tapes, discs and drums, associative memories and virtual address translation techniques. Batch processing, time sharing and real-time systems, scheduling resource allocation, modular software systems, performance measurement and system evaluation.', 'keywords': ['computer', 'science', 'operating', 'system', 'systems'], 'name': 'Introduction to Operating Systems', 'number': 'COMPSCI_537', 'requisites': [['COMPSCI_354', 'COMPSCI_400']], 'sections': [{'instructor': 'Andrea Arpaci-Dusseau', 'location': '1125 DeLuca Biochemistry Building', 'subsections': [{'location': '2317 Engineering Hall', 'time': {'wednesday': '11:00am - 11:50am'}, 'number': 'DIS_301'}, {'location': '1325 Computer Sciences and Statistics', 'time': {'wednesday': '12:05pm - 12:55pm'}, 'number': 'DIS_302'}, {'location': '1325 Computer Sciences and Statistics', 'time': {'wednesday': '1:20pm - 2:10pm'}, 'number': 'DIS_303'}, {'location': '2255 Engineering Hall', 'time': {'wednesday': '3:30pm - 4:20pm'}, 'number': 'DIS_304'}, {'location': '1325 Computer Sciences and Statistics', 'time': {'wednesday': '4:15pm - 5:25pm'}, 'number': 'DIS_305'}], 'time': {'thursday': '11:00am - 12:15pm', 'tuesday': '11:00am - 12:15pm'}, 'number': 'LEC_001'}], 'subject': 'Computer Science'}, {'credits': 3, 'description': 'Introduces students to Object-Oriented Programming using classes and objects to solve more complex problems. Introduces array-based and linked data structures: including lists, stacks, and queues. Programming assignments require writing and developing multi-class (file) programs using interfaces, generics, and exception handling to solve challenging real world problems. Topics reviewed include reading/writing data and objects from/to files and exception handling, and command line arguments. Topics introduced: object-oriented design; class vs. object; create and define interfaces and iterators; searching and sorting; abstract data types (List,Stack,Queue,PriorityQueue(Heap),Binary Search Tree); generic interfaces (parametric polymorphism); how to design and write test methods and classes; array based vs. linked node implementations; introduction to complexity analysis; recursion.', 'keywords': ['computer', 'science', 'programming', 'java'], 'name': 'Programming 2', 'number': 'COMPSCI_300', 'requisites': [['COMPSCI_200']], 'sections': [{'instructor': 'Gary Dahl', 'location': 'AB20 Weeks Hall for Geological Sciences', 'subsections': [], 'time': {'thursday': '2:30pm - 3:45pm', 'tuesday': '2:30pm - 3:45pm'}, 'number': 'LEC_001'}, {'instructor': 'Gary Dahl', 'location': '132 Noland Hall', 'subsections': [], 'time': {'thursday': '1:00pm - 2:15pm', 'tuesday': '1:00pm - 2:15pm'}, 'number': 'LEC_002'}, {'instructor': 'Mouna Ayari Ben Hadj Kacem', 'location': 'AB20 Weeks Hall for Geological Sciences', 'subsections': [], 'time': {'friday': '11:00am - 11:50pm', 'monday': '11:00am - 11:50pm', 'wednesday': '11:00am - 11:50pm'}, 'number': 'LEC_003'}, {'instructor': 'Mouna Ayari Ben Hadj Kacem', 'location': '1310 Sterling Hall', 'subsections': [], 'time': {'friday': '2:25pm - 3:15pm', 'monday': '2:25pm - 3:15pm', 'wednesday': '2:25pm - 3:15pm'}, 'number': 'LEC_004'}], 'subject': 'Computer Science'}, {'credits': 5, 'description': 'Principles and application of chemical equilibrium, coordination chemistry, oxidation-reduction and electrochemistry, kinetics, nuclear chemistry, introduction to organic chemistry. Lecture, lab, and discussion.', 'keywords': ['chemistry'], 'name': 'General Chemistry II', 'number': 'CHEM_104', 'requisites': [['MATH_114'], ['CHEM_103']], 'sections': [{'instructor': 'Linda Zelewski', 'location': 'B10 Ingraham Hall', 'subsections': [{'location': '123 Van Hise Hall', 'time': {'monday': '2:25pm - 5:25pm', 'thursday': '11:00am - 11:50am', 'tuesday': '11:00am - 11:50am'}, 'number': 'DIS_401'}, {'location': '123 Van Hise Hall', 'time': {'monday': '2:25pm - 5:25pm', 'thursday': '12:05pm - 12:55pm', 'tuesday': '12:05pm - 12:55pm'}, 'number': 'DIS_402'}, {'location': 'B387 Chemistry Building', 'time': {'monday': '2:25pm - 5:25pm', 'thursday': '11:00am - 11:50am', 'tuesday': '11:00am - 11:50am'}, 'number': 'DIS_403'}, {'location': 'B387 Chemistry Building', 'time': {'monday': '2:25pm - 5:25pm', 'thursday': '12:05pm - 12:55pm', 'tuesday': '12:05pm - 12:55pm'}, 'number': 'DIS_404'}], 'time': {'thursday': '9:30am - 10:45am', 'tuesday': '9:30am - 10:45am'}, 'number': 'LEC_001'}, {'instructor': 'Lea Gustin', 'location': '204 Educational Sciences', 'subsections': [{'location': '2377 Chemistry Building', 'time': {'monday': '9:55am - 10:45am', 'tuesday': '5:40pm - 8:40pm', 'wednesday': '9:55am - 10:45am'}, 'number': 'DIS_421'}, {'location': '2377 Chemistry Building', 'time': {'monday': '11:00am - 11:50am', 'tuesday': '5:40pm - 8:40pm', 'wednesday': '11:00am - 11:50am'}, 'number': 'DIS_422'}, {'location': '2381 Chemistry Building', 'time': {'monday': '11:00am - 11:50am', 'tuesday': '5:40pm - 8:40pm', 'wednesday': '11:00am - 11:50am'}, 'number': 'DIS_423'}, {'location': '2377 Chemistry Building', 'time': {'monday': '12:05pm - 12:55pm', 'tuesday': '5:40pm - 8:40pm', 'wednesday': '12:05pm - 12:55pm'}, 'number': 'DIS_424'}], 'time': {'thursday': '1:00pm - 2:15pm', 'tuesday': '1:00pm - 2:15pm'}, 'number': 'LEC_002'}], 'subject': 'Chemistry'}, {'credits': 3, 'description': 'Learn the process of incrementally developing small (200-500 lines) programs along with the fundamental Computer Science topics. These topics include: problem abstraction and decomposition, the edit-compile-run cycle, using variables of primitive and more complex data types, conditional and loop-based flow control, basic testing and debugging techniques, how to define and call functions (methods), and IO processing techniques. Also teaches and reinforces good programming practices including the use of a consistent style, and meaningful documentation. Intended for students who have no prior programming experience.', 'keywords': ['computer', 'science', 'programming', 'java'], 'name': 'Programming 1', 'number': 'COMPSCI_200', 'requisites': [], 'sections': [{'instructor': 'Jim Williams', 'location': '132 Noland Hall', 'subsections': [{'location': '1350 Computer Sciences and Statistics', 'time': {'wednesday': '9:30am - 10:45am'}, 'number': 'LAB_311'}, {'location': '1350 Computer Sciences and Statistics', 'time': {'wednesday': '11:00am - 12:15pm'}, 'number': 'LAB_312'}, {'location': '1350 Computer Sciences and Statistics', 'time': {'wednesday': '2:30pm - 3:45pm'}, 'number': 'LAB_314'}, {'location': '1350 Computer Sciences and Statistics', 'time': {'wednesday': '4:00pm - 5:15pm'}, 'number': 'LAB_315'}], 'time': {'thursday': '8:00am - 9:15am', 'tuesday': '8:00am - 9:15am'}, 'number': 'LEC_001'}, {'instructor': 'Jim Williams', 'location': '132 Noland Hall', 'subsections': [{'location': '1370 Computer Sciences and Statistics', 'time': {'wednesday': '9:30am - 10:45am'}, 'number': 'LAB_321'}, {'location': '1370 Computer Sciences and Statistics', 'time': {'wednesday': '1:00pm - 2:15pm'}, 'number': 'LAB_323'}, {'location': '1370 Computer Sciences and Statistics', 'time': {'wednesday': '2:30pm - 3:45pm'}, 'number': 'LAB_324'}, {'location': '1370 Computer Sciences and Statistics', 'time': {'wednesday': '4:00pm - 5:15pm'}, 'number': 'LAB_325'}], 'time': {'thursday': '11:00am - 12:15pm', 'tuesday': '11:00am - 12:15pm'}, 'number': 'LEC_002'}, {'instructor': 'Marc Renault', 'location': '113 Brogden Psychology Building', 'subsections': [{'location': '1350 Computer Sciences and Statistics', 'time': {'tuesday': '9:30am - 10:45am'}, 'number': 'LAB_331'}, {'location': '1350 Computer Sciences and Statistics', 'time': {'tuesday': '11:00am - 12:15pm'}, 'number': 'LAB_332'}, {'location': '1350 Computer Sciences and Statistics', 'time': {'tuesday': '1:00pm - 2:15pm'}, 'number': 'LAB_333'}, {'location': '1350 Computer Sciences and Statistics', 'time': {'tuesday': '2:30pm - 3:45pm'}, 'number': 'LAB_334'}], 'time': {'friday': '1:20pm - 2:10pm', 'monday': '1:20pm - 2:10pm', 'wednesday': '1:20pm - 2:10pm'}, 'number': 'LEC_003'}, {'instructor': 'Marc Renault', 'location': '113 Brogden Psychology Building', 'subsections': [{'location': '1370 Computer Sciences and Statistics', 'time': {'tuesday': '9:30am - 10:45am'}, 'number': 'LAB_341'}, {'location': '1370 Computer Sciences and Statistics', 'time': {'tuesday': '11:00am - 12:15pm'}, 'number': 'LAB_342'}, {'location': '1370 Computer Sciences and Statistics', 'time': {'tuesday': '1:00pm - 2:15pm'}, 'number': 'LAB_343'}, {'location': '1370 Computer Sciences and Statistics', 'time': {'tuesday': '2:30pm - 3:45pm'}, 'number': 'LAB_344'}, {'location': '1370 Computer Sciences and Statistics', 'time': {'tuesday': '4:00pm - 5:15pm'}, 'number': 'LAB_345'}], 'time': {'friday': '3:30pm - 4:20pm', 'monday': '3:30pm - 4:20pm', 'wednesday': '3:30pm - 4:20pm'}, 'number': 'LEC_004'}], 'subject': 'Computer Science'}, {'credits': 5, 'description': 'The two semester sequence MATH_112-MATH_113 covers similar material as MATH_114, but in a slower pace.', 'keywords': ['math', 'mathematics', 'algebra', 'trigonometry'], 'name': 'Algebra and Trigonometry', 'number': 'MATH_114', 'requisites': [], 'sections': [{'instructor': 'Sharad Chandarana', 'location': 'B130 Van Vleck Hall', 'subsections': [{'location': 'B113 Van Vleck Hall', 'time': {'monday': '7:45am - 8:35am', 'wednesday': '7:45am - 8:35am'}, 'number': 'DIS_301'}, {'location': 'B113 Van Vleck Hall', 'time': {'monday': '8:50am - 9:40am', 'wednesday': '8:50am - 9:40am'}, 'number': 'DIS_303'}, {'location': 'B219 Van Vleck Hall', 'time': {'monday': '8:50am - 9:40am', 'wednesday': '8:50am - 9:40am'}, 'number': 'DIS_304'}, {'location': 'B113 Van Vleck Hall', 'time': {'monday': '9:55am - 10:45am', 'wednesday': '9:55am - 10:45am'}, 'number': 'DIS_305'}, {'location': 'B219 Van Vleck Hall', 'time': {'monday': '9:55am - 10:45am', 'wednesday': '9:55am - 10:45am'}, 'number': 'DIS_306'}, {'location': 'B341 Van Vleck Hall', 'time': {'monday': '1:20pm - 2:10pm', 'wednesday': '1:20pm - 2:10pm'}, 'number': 'DIS_307'}, {'location': 'B317 Van Vleck Hall', 'time': {'monday': '1:20pm - 2:10pm', 'wednesday': '1:20pm - 2:10pm'}, 'number': 'DIS_308'}, {'location': 'B341 Van Vleck Hall', 'time': {'monday': '2:25pm - 3:15pm', 'wednesday': '2:25pm - 3:15pm'}, 'number': 'DIS_309'}, {'location': 'B329 Van Vleck Hall', 'time': {'monday': '2:25pm - 3:15pm', 'wednesday': '2:25pm - 3:15pm'}, 'number': 'DIS_310'}, {'location': 'B317 Van Vleck Hall', 'time': {'monday': '7:45am - 8:35am', 'wednesday': '7:45am - 8:35am'}, 'number': 'DIS_311'}], 'time': {'thursday': '2:30pm - 3:45pm', 'tuesday': '2:30pm - 3:45pm'}, 'number': 'LEC_001'}, {'instructor': 'Sharad Chandarana', 'location': '19 Ingraham Hall', 'subsections': [{'location': '591 Van Hise Hall', 'time': {'thursday': '8:50am - 9:40am', 'tuesday': '8:50am - 9:40am'}, 'number': 'DIS_321'}, {'location': 'B219 Van Vleck Hall', 'time': {'thursday': '9:55am - 10:45am', 'tuesday': '9:55am - 10:45am'}, 'number': 'DIS_322'}, {'location': '4020 Vilas Hall', 'time': {'thursday': '11:00am - 11:50am', 'tuesday': '11:00am - 11:50am'}, 'number': 'DIS_323'}, {'location': '599 Van Hise Hall', 'time': {'thursday': '11:00am - 11:50am', 'tuesday': '11:00am - 11:50am'}, 'number': 'DIS_324'}, {'location': 'B341 Van Vleck Hall', 'time': {'thursday': '1:20pm - 2:10pm', 'tuesday': '1:20pm - 2:10pm'}, 'number': 'DIS_325'}, {'location': '223 Van Hise Hall', 'time': {'thursday': '1:20pm - 2:10pm', 'tuesday': '1:20pm - 2:10pm'}, 'number': 'DIS_326'}, {'location': '223 Van Hise Hall', 'time': {'thursday': '2:25pm - 3:15pm', 'tuesday': '2:25pm - 3:15pm'}, 'number': 'DIS_328'}, {'location': 'B219 Van Vleck Hall', 'time': {'thursday': '3:30pm - 4:20pm', 'tuesday': '3:30pm - 4:20pm'}, 'number': 'DIS_329'}, {'location': 'B341 Van Vleck Hall', 'time': {'thursday': '3:30pm - 4:20pm', 'tuesday': '3:30pm - 4:20pm'}, 'number': 'DIS_330'}], 'time': {'friday': '8:50am - 9:40am', 'monday': '8:50am - 9:40am', 'wednesday': '8:50am - 9:40am'}, 'number': 'LEC_002'}], 'subject': 'Mathematics'}, {'credits': 4, 'description': 'The systematic study of the individual in a social context, including social interaction, motivation, attitudes, conformity, communication, leadership, personal relationships, and behavior in small groups.', 'keywords': ['psychology', 'science', 'social', 'interaction', 'behavior'], 'name': 'Introductory Social Psychology', 'number': 'PSYCH_456', 'requisites': [['PSYCH_202']], 'sections': [{'instructor': 'Abigail Letak', 'location': '6104 Sewell Social Sciences', 'subsections': [{'location': '6121 Sewell Social Sciences', 'time': {'tuesday': '8:50am - 9:40am'}, 'number': 'DIS_301'}, {'location': '6121 Sewell Social Sciences', 'time': {'tuesday': '9:55am - 10:45am'}, 'number': 'DIS_302'}, {'location': '6121 Sewell Social Sciences', 'time': {'tuesday': '11:00am - 11:50am'}, 'number': 'DIS_303'}, {'location': '6121 Sewell Social Sciences', 'time': {'tuesday': '1:20pm - 2:10pm'}, 'number': 'DIS_304'}, {'location': '6121 Sewell Social Sciences', 'time': {'tuesday': '2:25pm - 3:15pm'}, 'number': 'DIS_305'}], 'time': {'friday': '11:00am - 11:50am', 'monday': '11:00am - 11:50am', 'wednesday': '11:00am - 11:50am'}, 'number': 'LEC_001'}], 'subject': 'Psychology'}, {'credits': 2, 'description': 'Logic components built with transistors, rudimentary Boolean algebra, basic combinational logic design, basic synchronous sequential logic design, basic computer organization and design, introductory machine- and assembly-language programming.', 'keywords': ['computer', 'science', 'engineering', 'programming'], 'name': 'Introduction to Computer Engineering', 'number': 'COMPSCI_252', 'requisites': [], 'sections': [{'instructor': 'Joseph Krachey', 'location': '1610 Engineering Hall', 'subsections': [], 'time': {'friday': '2:25pm - 3:15pm', 'monday': '2:25pm - 3:15pm', 'wednesday': '2:25pm - 3:15pm'}, 'number': 'LEC_001'}, {'instructor': 'Adil Ibrahim', 'location': '113 Brogden Psychology Building', 'subsections': [], 'time': {'friday': '8:50am - 9:40am', 'monday': '8:50am - 9:40am', 'wednesday': '8:50am - 9:40am'}, 'number': 'LEC_002'}, {'instructor': 'Adil Ibrahim', 'location': '113 Brogden Psychology Building', 'subsections': [], 'time': {'friday': '12:05pm - 12:55pm', 'monday': '12:05pm - 12:55pm', 'wednesday': '12:05pm - 12:55pm'}, 'number': 'LEC_005'}], 'subject': 'Computer Science'}, {'credits': 3, 'description': 'The third course in our programming fundamentals sequence. It presumes that students understand and use functional and object-oriented design and abstract data types as needed. This course introduces balanced search trees, graphs, graph traversal algorithms, hash tables and sets, and complexity analysis and about classes of problems that require each data type. Students are required to design and implement using high quality professional code, a medium sized program, that demonstrates knowledge and use of latest language features, tools, and conventions. Additional topics introduced will include as needed for projects: inheritance and polymorphism; anonymous inner classes, lambda functions, performance analysis to discover and optimize critical code blocks. Students learn about industry standards for code development. Students will design and implement a medium size project with a more advanced user-interface design, such as a web or mobile application with a GUI and event- driven implementation; use of version-control software.', 'keywords': ['computer', 'science', 'programming', 'java'], 'name': 'Programming 3', 'number': 'COMPSCI_400', 'requisites': [['COMPSCI_300']], 'sections': [{'instructor': 'Gary Dahl', 'location': 'AB20 Weeks Hall for Geological Sciences', 'subsections': [], 'time': {'thursday': '2:30pm - 3:45pm', 'tuesday': '2:30pm - 3:45pm'}, 'number': 'LEC_001'}, {'instructor': 'Gary Dahl', 'location': '132 Noland Hall', 'subsections': [], 'time': {'thursday': '1:00pm - 2:15pm', 'tuesday': '1:00pm - 2:15pm'}, 'number': 'LEC_002'}, {'instructor': 'Mouna Ayari Ben Hadj Kacem', 'location': 'AB20 Weeks Hall for Geological Sciences', 'subsections': [], 'time': {'friday': '11:00am - 11:50pm', 'monday': '11:00am - 11:50pm', 'wednesday': '11:00am - 11:50pm'}, 'number': 'LEC_003'}, {'instructor': 'Mouna Ayari Ben Hadj Kacem', 'location': '1310 Sterling Hall', 'subsections': [], 'time': {'friday': '2:25pm - 3:15pm', 'monday': '2:25pm - 3:15pm', 'wednesday': '2:25pm - 3:15pm'}, 'number': 'LEC_004'}], 'subject': 'Computer Science'}, {'credits': 5, 'description': 'Introduction to differential and integral calculus and plane analytic geometry; applications; transcendental functions.', 'keywords': ['math', 'mathematics', 'calculus', 'analytical', 'geometry', 'differential', 'integral'], 'name': 'Calculus and Analytical Geometry 1', 'number': 'MATH_221', 'requisites': [['MATH_114']], 'sections': [{'instructor': 'Laurentiu Maxim', 'location': '6210 Sewell Social Sciences', 'subsections': [{'location': 'B231 Van Vleck Hall', 'time': {'monday': '7:45am - 8:35am', 'wednesday': '7:45am - 8:35am'}, 'number': 'DIS_301'}, {'location': 'B215 Van Vleck Hall', 'time': {'monday': '7:45am - 8:35am', 'wednesday': '7:45am - 8:35am'}, 'number': 'DIS_302'}, {'location': 'B309 Van Vleck Hall', 'time': {'monday': '3:30pm - 4:20pm', 'wednesday': '3:30pm - 4:20pm'}, 'number': 'DIS_303'}, {'location': 'B211 Van Vleck Hall', 'time': {'monday': '3:30pm - 4:20pm', 'wednesday': '3:30pm - 4:20pm'}, 'number': 'DIS_304'}, {'location': 'B129 Van Vleck Hall', 'time': {'monday': '11:00am - 11:50am', 'wednesday': '11:00am - 11:50am'}, 'number': 'DIS_305'}, {'location': 'B131 Van Vleck Hall', 'time': {'monday': '11:00am - 11:50am', 'wednesday': '11:00am - 11:50am'}, 'number': 'DIS_306'}, {'location': 'B231 Van Vleck Hall', 'time': {'monday': '12:05pm - 12:55pm', 'wednesday': '12:05pm - 12:55pm'}, 'number': 'DIS_307'}, {'location': 'B215 Van Vleck Hall', 'time': {'monday': '12:05pm - 12:55pm', 'wednesday': '12:05pm - 12:55pm'}, 'number': 'DIS_308'}, {'location': 'B313 Van Vleck Hall', 'time': {'monday': '1:20pm - 2:10pm', 'wednesday': '1:20pm - 2:10pm'}, 'number': 'DIS_309'}, {'location': 'B309 Van Vleck Hall', 'time': {'monday': '1:20pm - 2:10pm', 'wednesday': '1:20pm - 2:10pm'}, 'number': 'DIS_310'}, {'location': 'B305 Van Vleck Hall', 'time': {'monday': '2:25pm - 3:15pm', 'wednesday': '2:25pm - 3:15pm'}, 'number': 'DIS_311'}, {'location': 'B105 Van Vleck Hall', 'time': {'monday': '2:25pm - 3:15pm', 'wednesday': '2:25pm - 3:15pm'}, 'number': 'DIS_312'}, {'location': 'B321 Van Vleck Hall', 'time': {'friday': '9:55am - 10:45am', 'monday': '9:55am - 10:45am', 'wednesday': '9:55am - 10:45am'}, 'number': 'DIS_313'}], 'time': {'thursday': '1:00pm - 2:15pm', 'tuesday': '1:00pm - 2:15pm'}, 'number': 'LEC_001'}], 'subject': 'Mathematics'}, {'credits': 3, 'description': 'General biological principles. Topics include: evolution, ecology, animal behavior, cell structure and function, genetics and molecular genetics and the physiology of a variety of organ systems emphasizing function in humans.', 'keywords': ['biology', 'science', 'animal', 'evolution', 'genetics', 'ecology'], 'name': 'Animal Biology', 'number': 'BIOLOGY_101', 'requisites': [], 'sections': [{'instructor': 'Sharon Thoma', 'location': '272 Bascom Hall', 'subsections': [], 'time': {'friday': '11:00am - 11:50am', 'monday': '11:00am - 11:50am', 'wednesday': '11:00am - 11:50am'}, 'number': 'LEC_001'}, {'instructor': 'Sharon Thoma', 'location': '272 Bascom Hall', 'subsections': [], 'time': {'friday': '12:05pm - 12:55pm', 'monday': '12:05pm - 12:55pm', 'wednesday': '12:05pm - 12:55pm'}, 'number': 'LEC_002'}], 'subject': 'Biology'}, {'credits': 3, 'description': 'An introduction to fundamental structures of computer systems and the C programming language with a focus on the low-level interrelationships and impacts on performance. Topics include the virtual address space and virtual memory, the heap and dynamic memory management, the memory hierarchy and caching, assembly language and the stack, communication and interrupts/signals, compiling and assemblers/linkers.', 'keywords': ['computer', 'science', 'engineering', 'electrical', 'machine', 'programming'], 'name': 'Machine Organization and Programming', 'number': 'COMPSCI_354', 'requisites': [['COMPSCI_252'], ['COMPSCI_300']], 'sections': [{'instructor': 'James Skrentny', 'location': '132 Noland Hall', 'subsections': [], 'time': {'thursday': '2:30pm - 3:45pm', 'tuesday': '2:30pm - 3:45pm'}, 'number': 'LEC_001'}, {'instructor': 'James Skrentny', 'location': '132 Noland Hall', 'subsections': [], 'time': {'thursday': '4:00pm - 5:15pm', 'tuesday': '4:00pm - 5:15pm'}, 'number': 'LEC_002'}], 'subject': 'Computer Science'}, {'credits': 4, 'description': 'Introduction. Stoichiometry and the mole concept, the behavior of gases, liquids and solids, thermochemistry, electronic structure of atoms and chemical bonding, descriptive chemistry of selected elements and compounds, intermolecular forces. For students taking one year or more of college chemistry; serves as a prereq for CHEM_104; lecture, lab and discussion.', 'keywords': ['chemistry'], 'name': 'General Chemistry I', 'number': 'CHEM_103', 'requisites': [], 'sections': [{'instructor': 'Unknown', 'location': 'B10 Ingraham Hall', 'subsections': [{'location': '49 Sellery Residence Hall', 'time': {'monday': '3:30pm - 4:20pm', 'wednesday': '3:30pm - 4:20pm'}, 'number': 'DIS_301'}, {'location': '2307 Chemistry Building', 'time': {'monday': '4:35pm - 5:25pm', 'wednesday': '4:35pm - 5:25pm'}, 'number': 'DIS_302'}, {'location': '123 Van Hise Hall', 'time': {'monday': '1:20pm - 2:10pm', 'wednesday': '1:20pm - 2:10pm'}, 'number': 'DIS_303'}, {'location': '123 Van Hise Hall', 'time': {'monday': '2:25pm - 3:15pm', 'wednesday': '2:25pm - 3:15pm'}, 'number': 'DIS_304'}], 'time': {'friday': '11:00am - 11:50am', 'monday': '11:00am - 11:50am', 'wednesday': '11:00am - 11:50am'}, 'number': 'LEC_001'}], 'subject': 'Chemistry'}, {'credits': 3, 'description': 'This course introduces students to the software development of user interfaces (UIs). Topics covered include state-of-the-art (1) UI paradigms, such as event-driven interfaces, direct-manipulation interfaces, and dialogue-based interaction; (2) methods for capturing, interpreting, and responding to different forms of user input and states, including pointing, text entry, speech, touch, gestures, user activity, context, and physiological states; and (3) platform-specific UI development APIs, frameworks, and toolkits for platforms including web/mobile/desktop interfaces, natural user interfaces, and voice user interfaces. Through readings, lectures, and hands-on-activities, students will learn about the fundamental concepts, technologies, and methods in building user interfaces. Assignments will provide an opportunity to gain hands-on experience in the use of state-of-the-art UI development tools and build a UI development portfolio.', 'keywords': ['computer', 'science', 'building', 'user', 'interface', 'interfaces', 'design', 'ui'], 'name': 'Building User Interfaces', 'number': 'COMPSCI_639', 'requisites': [['COMPSCI_300']], 'sections': [{'instructor': 'Bilge Mutlu', 'location': '1221 Computer Sciences and Statistics', 'subsections': [], 'time': {'thursday': '1:00pm - 2:15pm', 'tuesday': '1:00pm - 2:15pm'}, 'number': 'LEC_002'}], 'subject': 'Computer Science'}, {'credits': 3, 'description': 'Focuses on the role that psychological principles, research evidence and social science play in the laws of U.S. society, especially in the policies and mechanisms of social control of human behavior. The course will address the ways that society defines membership, and the role of psychology in how it determines who should be excluded or restricted from open society, in order to maintain a more civil society. In addition to learning the factual information about how selected processes work in the legal and social context, students will be asked to consider the role they can play as citizens in supporting or changing these social processes. The course will take a particular interest in psycholegal issues \"in action\" and in learning about the clinical-legal processes used to determine the disposition of individuals considered marginal in society. Finally, the course will address the mechanisms that are used to exclude individuals from open society through criminal and civil court processes, the role of psychology as a science, and the role of psychologists as behavioral experts in criminal and civil courts, and in shaping social policies.', 'keywords': ['psychology', 'science', 'law', 'social', 'policy', 'behavior'], 'name': 'Psychology, Law, and Social Policy', 'number': 'PSYCH_401', 'requisites': [['PSYCH_202']], 'sections': [{'instructor': 'Gregory Van Rybroek', 'location': '121 Brogden Psychology Building', 'subsections': [], 'time': {'monday': '4:00pm - 5:15pm', 'wednesday': '4:00pm - 5:15pm'}, 'number': 'LEC_001'}], 'subject': 'Psychology'}, {'credits': 3, 'description': 'Basic concepts of logic, sets, partial order and other relations, and functions. Basic concepts of mathematics (definitions, proofs, sets, functions, and relations) with a focus on discrete structures: integers, bits, strings, trees, and graphs. Propositional logic, Boolean algebra, and predicate logic. Mathematical induction and recursion. Invariants and algorithmic correctness. Recurrences and asymptotic growth analysis. Fundamentals of counting.', 'keywords': ['computer', 'science', 'math', 'mathematics', 'discrete', 'logic', 'algorithm', 'algorithms'], 'name': 'Introduction To Discrete Mathematics', 'number': 'COMPSCI_240', 'requisites': [['MATH_221']], 'sections': [{'instructor': 'Beck Hasti', 'location': '105 Brogden Psychology Building', 'subsections': [{'location': '1257 Computer Sciences and Statistics', 'time': {'tuesday': '8:50am - 9:40am'}, 'number': 'DIS_310'}, {'location': '1257 Computer Sciences and Statistics', 'time': {'thursday': '8:50am - 9:40am'}, 'number': 'DIS_311'}, {'location': '3024 Engineering Hall', 'time': {'tuesday': '9:55am - 10:45am'}, 'number': 'DIS_312'}, {'location': '2345 Engineering Hall', 'time': {'thursday': '9:55am - 10:45am'}, 'number': 'DIS_313'}, {'location': '2535 Engineering Hall', 'time': {'tuesday': '11:00am - 11:50am'}, 'number': 'DIS_314'}, {'location': '2535 Engineering Hall', 'time': {'thursday': '11:00am - 11:50am'}, 'number': 'DIS_315'}, {'location': 'B309 Van Vleck Hall', 'time': {'tuesday': '9:55am - 10:45am'}, 'number': 'DIS_316'}], 'time': {'friday': '9:55am - 10:45am', 'monday': '9:55am - 10:45am', 'wednesday': '9:55am - 10:45am'}, 'number': 'LEC_001'}, {'instructor': 'Beck Hasti', 'location': '132 Noland Hall', 'subsections': [{'location': 'B211 Van Vleck Hall', 'time': {'thursday': '11:00am - 11:50am'}, 'number': 'DIS_320'}, {'location': 'B211 Van Vleck Hall', 'time': {'tuesday': '12:05pm - 12:55pm'}, 'number': 'DIS_321'}, {'location': '2255 Engineering Hall', 'time': {'thursday': '12:05pm - 12:55pm'}, 'number': 'DIS_322'}, {'location': '2349 Engineering Hall', 'time': {'tuesday': '1:20pm - 2:10pm'}, 'number': 'DIS_323'}, {'location': '1263 Computer Sciences and Statistics', 'time': {'thursday': '1:20pm - 2:10pm'}, 'number': 'DIS_324'}, {'location': '3418 Engineering Hall', 'time': {'tuesday': '2:25pm - 3:15pm'}, 'number': 'DIS_325'}, {'location': '3418 Engineering Hall', 'time': {'thursday': '2:25pm - 3:15pm'}, 'number': 'DIS_326'}], 'time': {'friday': '1:20pm - 2:10pm', 'monday': '1:20pm - 2:10pm', 'wednesday': '1:20pm - 2:10pm'}, 'number': 'LEC_002'}, {'instructor': 'Beck Hasti', 'location': '168 Noland Hall', 'subsections': [{'location': '1263 Computer Sciences and Statistics', 'time': {'tuesday': '8:50am - 9:40am'}, 'number': 'DIS_330'}, {'location': '1263 Computer Sciences and Statistics', 'time': {'tuesday': '1:20pm - 2:10pm'}, 'number': 'DIS_331'}, {'location': '3024 Engineering Hall', 'time': {'thursday': '9:55am - 10:45am'}, 'number': 'DIS_332'}, {'location': '2349 Engineering Hall', 'time': {'thursday': '12:05am - 12:55am'}, 'number': 'DIS_333'}], 'time': {'friday': '2:25pm - 3:15pm', 'monday': '2:25pm - 3:15pm', 'wednesday': '2:25pm - 3:15pm'}, 'number': 'LEC_003'}], 'subject': 'Computer Science'}, {'credits': 3, 'description': 'Graphical and numerical exploration of data; standard errors; distributions for statistical models including binomial, Poisson, normal; estimation; hypothesis testing; randomization tests; basic principles of experimental design; regression; ANOVA; categorical data analysis; goodness of fit; application. (intended for students wishing to take additional statistics courses).', 'keywords': ['statistics', 'statistical', 'math', 'mathematics', 'methods'], 'name': 'Accelerated Introduction to Statistical Methods', 'number': 'STATS_302', 'requisites': [['MATH_221']], 'sections': [{'instructor': 'Unknown', 'location': '331 Service Memorial Institute', 'subsections': [{'location': '212 Educational Sciences', 'time': {'tuesday': '1:20pm - 2:10pm'}, 'number': 'DIS_311'}, {'location': '1313 Sterling Hall', 'time': {'wednesday': '7:45am - 8:35am'}, 'number': 'DIS_312'}, {'location': '1313 Sterling Hall', 'time': {'wednesday': '11:00am - 11:50am'}, 'number': 'DIS_313'}], 'time': {'monday': '4:00pm - 5:15pm', 'wednesday': '4:00pm - 5:15pm'}, 'number': 'LEC_001'}], 'subject': 'Statistics'}]\n" - ] - } - ], "source": [ - "# Collect all the class data in a list called 'all_class_data'\n", - "all_class_data = []\n", - "for class_num in classes_list:\n", - " url = \"https://coletnelson.us/cs220-api/classes/\" + class_num\n", - " r = requests.get(url)\n", - " r.raise_for_status()\n", - " class_data = r.json()\n", - " all_class_data.append(class_data)\n", - "\n", - "print(all_class_data) # Too much data? Try print(len(all_class_data))" + "### Write it out to a CSV file on your drive\n", + "You now have your own copy!" ] }, { "cell_type": "code", "execution_count": 29, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "17\n" - ] - } - ], - "source": [ - "print(len(all_class_data))" - ] - }, - { - "cell_type": "code", - "execution_count": 30, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "3 PSYCH_202 Introduction to Psychology\n", - "4 COMPSCI_537 Introduction to Operating Systems\n", - "3 COMPSCI_300 Programming 2\n", - "5 CHEM_104 General Chemistry II\n", - "3 COMPSCI_200 Programming 1\n", - "5 MATH_114 Algebra and Trigonometry\n", - "4 PSYCH_456 Introductory Social Psychology\n", - "2 COMPSCI_252 Introduction to Computer Engineering\n", - "3 COMPSCI_400 Programming 3\n", - "5 MATH_221 Calculus and Analytical Geometry 1\n", - "3 BIOLOGY_101 Animal Biology\n", - "3 COMPSCI_354 Machine Organization and Programming\n", - "4 CHEM_103 General Chemistry I\n", - "3 COMPSCI_639 Building User Interfaces\n", - "3 PSYCH_401 Psychology, Law, and Social Policy\n", - "3 COMPSCI_240 Introduction To Discrete Mathematics\n", - "3 STATS_302 Accelerated Introduction to Statistical Methods\n" - ] - } - ], - "source": [ - "# Print the number of credits, course number, and name for each class.\n", - "for spec_class in all_class_data:\n", - " print(spec_class['credits'], spec_class['number'], spec_class['name'])" - ] - }, - { - "cell_type": "code", - "execution_count": 31, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "3.4705882352941178" - ] - }, - "execution_count": 31, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# What is the average number of credits per course?\n", - "num_credits = 0 \n", - "for spec_class in all_class_data:\n", - " num_credits += spec_class['credits']\n", - "num_credits / len(all_class_data)" - ] - }, - { - "cell_type": "code", - "execution_count": 32, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "['Biology',\n", - " 'Chemistry',\n", - " 'Computer Science',\n", - " 'Mathematics',\n", - " 'Psychology',\n", - " 'Statistics']" - ] - }, - "execution_count": 32, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# What are the unique subjects?\n", - "subjects = []\n", - "for spec_class in all_class_data:\n", - " subjects.append(spec_class['subject'])\n", - "list(set(subjects))" - ] - }, - { - "cell_type": "code", - "execution_count": 33, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "['COMPSCI_300', 'COMPSCI_200', 'COMPSCI_400']" - ] - }, - "execution_count": 33, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Besides PYSCH 202, what are the course numbers of the courses\n", - "# with the most sections offered (not including subsections)?\n", - "high_courses = []\n", - "high_sections = 0\n", - "for spec_class in all_class_data:\n", - " current_course_num = spec_class['number']\n", - " current_num_sects = len(spec_class['sections'])\n", - " \n", - " if current_course_num == 'PSYCH_202':\n", - " continue\n", - " \n", - " if current_num_sects == high_sections:\n", - " high_courses.append(current_course_num)\n", - " elif current_num_sects > high_sections:\n", - " high_courses = []\n", - " high_courses.append(current_course_num)\n", - " high_sections = current_num_sects\n", - "high_courses" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Can we make a Pandas dataframe? Yes!" - ] - }, - { - "cell_type": "code", - "execution_count": 34, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "<div>\n", - "<style scoped>\n", - " .dataframe tbody tr th:only-of-type {\n", - " vertical-align: middle;\n", - " }\n", - "\n", - " .dataframe tbody tr th {\n", - " vertical-align: top;\n", - " }\n", - "\n", - " .dataframe thead th {\n", - " text-align: right;\n", - " }\n", - "</style>\n", - "<table border=\"1\" class=\"dataframe\">\n", - " <thead>\n", - " <tr style=\"text-align: right;\">\n", - " <th></th>\n", - " <th>credits</th>\n", - " <th>description</th>\n", - " <th>keywords</th>\n", - " <th>name</th>\n", - " <th>number</th>\n", - " <th>requisites</th>\n", - " <th>sections</th>\n", - " <th>subject</th>\n", - " </tr>\n", - " </thead>\n", - " <tbody>\n", - " <tr>\n", - " <th>0</th>\n", - " <td>3</td>\n", - " <td>Behavior, including its development, motivatio...</td>\n", - " <td>[psychology, behavior, emotion, intelligence, ...</td>\n", - " <td>Introduction to Psychology</td>\n", - " <td>PSYCH_202</td>\n", - " <td>[]</td>\n", - " <td>[{'instructor': 'Jeff Henriques', 'location': ...</td>\n", - " <td>Psychology</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1</th>\n", - " <td>4</td>\n", - " <td>Input-output hardware, interrupt handling, pro...</td>\n", - " <td>[computer, science, operating, system, systems]</td>\n", - " <td>Introduction to Operating Systems</td>\n", - " <td>COMPSCI_537</td>\n", - " <td>[[COMPSCI_354, COMPSCI_400]]</td>\n", - " <td>[{'instructor': 'Andrea Arpaci-Dusseau', 'loca...</td>\n", - " <td>Computer Science</td>\n", - " </tr>\n", - " <tr>\n", - " <th>2</th>\n", - " <td>3</td>\n", - " <td>Introduces students to Object-Oriented Program...</td>\n", - " <td>[computer, science, programming, java]</td>\n", - " <td>Programming 2</td>\n", - " <td>COMPSCI_300</td>\n", - " <td>[[COMPSCI_200]]</td>\n", - " <td>[{'instructor': 'Gary Dahl', 'location': 'AB20...</td>\n", - " <td>Computer Science</td>\n", - " </tr>\n", - " <tr>\n", - " <th>3</th>\n", - " <td>5</td>\n", - " <td>Principles and application of chemical equilib...</td>\n", - " <td>[chemistry]</td>\n", - " <td>General Chemistry II</td>\n", - " <td>CHEM_104</td>\n", - " <td>[[MATH_114], [CHEM_103]]</td>\n", - " <td>[{'instructor': 'Linda Zelewski', 'location': ...</td>\n", - " <td>Chemistry</td>\n", - " </tr>\n", - " <tr>\n", - " <th>4</th>\n", - " <td>3</td>\n", - " <td>Learn the process of incrementally developing ...</td>\n", - " <td>[computer, science, programming, java]</td>\n", - " <td>Programming 1</td>\n", - " <td>COMPSCI_200</td>\n", - " <td>[]</td>\n", - " <td>[{'instructor': 'Jim Williams', 'location': '1...</td>\n", - " <td>Computer Science</td>\n", - " </tr>\n", - " <tr>\n", - " <th>5</th>\n", - " <td>5</td>\n", - " <td>The two semester sequence MATH_112-MATH_113 co...</td>\n", - " <td>[math, mathematics, algebra, trigonometry]</td>\n", - " <td>Algebra and Trigonometry</td>\n", - " <td>MATH_114</td>\n", - " <td>[]</td>\n", - " <td>[{'instructor': 'Sharad Chandarana', 'location...</td>\n", - " <td>Mathematics</td>\n", - " </tr>\n", - " <tr>\n", - " <th>6</th>\n", - " <td>4</td>\n", - " <td>The systematic study of the individual in a so...</td>\n", - " <td>[psychology, science, social, interaction, beh...</td>\n", - " <td>Introductory Social Psychology</td>\n", - " <td>PSYCH_456</td>\n", - " <td>[[PSYCH_202]]</td>\n", - " <td>[{'instructor': 'Abigail Letak', 'location': '...</td>\n", - " <td>Psychology</td>\n", - " </tr>\n", - " <tr>\n", - " <th>7</th>\n", - " <td>2</td>\n", - " <td>Logic components built with transistors, rudim...</td>\n", - " <td>[computer, science, engineering, programming]</td>\n", - " <td>Introduction to Computer Engineering</td>\n", - " <td>COMPSCI_252</td>\n", - " <td>[]</td>\n", - " <td>[{'instructor': 'Joseph Krachey', 'location': ...</td>\n", - " <td>Computer Science</td>\n", - " </tr>\n", - " <tr>\n", - " <th>8</th>\n", - " <td>3</td>\n", - " <td>The third course in our programming fundamenta...</td>\n", - " <td>[computer, science, programming, java]</td>\n", - " <td>Programming 3</td>\n", - " <td>COMPSCI_400</td>\n", - " <td>[[COMPSCI_300]]</td>\n", - " <td>[{'instructor': 'Gary Dahl', 'location': 'AB20...</td>\n", - " <td>Computer Science</td>\n", - " </tr>\n", - " <tr>\n", - " <th>9</th>\n", - " <td>5</td>\n", - " <td>Introduction to differential and integral calc...</td>\n", - " <td>[math, mathematics, calculus, analytical, geom...</td>\n", - " <td>Calculus and Analytical Geometry 1</td>\n", - " <td>MATH_221</td>\n", - " <td>[[MATH_114]]</td>\n", - " <td>[{'instructor': 'Laurentiu Maxim', 'location':...</td>\n", - " <td>Mathematics</td>\n", - " </tr>\n", - " <tr>\n", - " <th>10</th>\n", - " <td>3</td>\n", - " <td>General biological principles. Topics include:...</td>\n", - " <td>[biology, science, animal, evolution, genetics...</td>\n", - " <td>Animal Biology</td>\n", - " <td>BIOLOGY_101</td>\n", - " <td>[]</td>\n", - " <td>[{'instructor': 'Sharon Thoma', 'location': '2...</td>\n", - " <td>Biology</td>\n", - " </tr>\n", - " <tr>\n", - " <th>11</th>\n", - " <td>3</td>\n", - " <td>An introduction to fundamental structures of c...</td>\n", - " <td>[computer, science, engineering, electrical, m...</td>\n", - " <td>Machine Organization and Programming</td>\n", - " <td>COMPSCI_354</td>\n", - " <td>[[COMPSCI_252], [COMPSCI_300]]</td>\n", - " <td>[{'instructor': 'James Skrentny', 'location': ...</td>\n", - " <td>Computer Science</td>\n", - " </tr>\n", - " <tr>\n", - " <th>12</th>\n", - " <td>4</td>\n", - " <td>Introduction. Stoichiometry and the mole conce...</td>\n", - " <td>[chemistry]</td>\n", - " <td>General Chemistry I</td>\n", - " <td>CHEM_103</td>\n", - " <td>[]</td>\n", - " <td>[{'instructor': 'Unknown', 'location': 'B10 In...</td>\n", - " <td>Chemistry</td>\n", - " </tr>\n", - " <tr>\n", - " <th>13</th>\n", - " <td>3</td>\n", - " <td>This course introduces students to the softwar...</td>\n", - " <td>[computer, science, building, user, interface,...</td>\n", - " <td>Building User Interfaces</td>\n", - " <td>COMPSCI_639</td>\n", - " <td>[[COMPSCI_300]]</td>\n", - " <td>[{'instructor': 'Bilge Mutlu', 'location': '12...</td>\n", - " <td>Computer Science</td>\n", - " </tr>\n", - " <tr>\n", - " <th>14</th>\n", - " <td>3</td>\n", - " <td>Focuses on the role that psychological princip...</td>\n", - " <td>[psychology, science, law, social, policy, beh...</td>\n", - " <td>Psychology, Law, and Social Policy</td>\n", - " <td>PSYCH_401</td>\n", - " <td>[[PSYCH_202]]</td>\n", - " <td>[{'instructor': 'Gregory Van Rybroek', 'locati...</td>\n", - " <td>Psychology</td>\n", - " </tr>\n", - " <tr>\n", - " <th>15</th>\n", - " <td>3</td>\n", - " <td>Basic concepts of logic, sets, partial order a...</td>\n", - " <td>[computer, science, math, mathematics, discret...</td>\n", - " <td>Introduction To Discrete Mathematics</td>\n", - " <td>COMPSCI_240</td>\n", - " <td>[[MATH_221]]</td>\n", - " <td>[{'instructor': 'Beck Hasti', 'location': '105...</td>\n", - " <td>Computer Science</td>\n", - " </tr>\n", - " <tr>\n", - " <th>16</th>\n", - " <td>3</td>\n", - " <td>Graphical and numerical exploration of data; s...</td>\n", - " <td>[statistics, statistical, math, mathematics, m...</td>\n", - " <td>Accelerated Introduction to Statistical Methods</td>\n", - " <td>STATS_302</td>\n", - " <td>[[MATH_221]]</td>\n", - " <td>[{'instructor': 'Unknown', 'location': '331 Se...</td>\n", - " <td>Statistics</td>\n", - " </tr>\n", - " </tbody>\n", - "</table>\n", - "</div>" - ], - "text/plain": [ - " credits description \\\n", - "0 3 Behavior, including its development, motivatio... \n", - "1 4 Input-output hardware, interrupt handling, pro... \n", - "2 3 Introduces students to Object-Oriented Program... \n", - "3 5 Principles and application of chemical equilib... \n", - "4 3 Learn the process of incrementally developing ... \n", - "5 5 The two semester sequence MATH_112-MATH_113 co... \n", - "6 4 The systematic study of the individual in a so... \n", - "7 2 Logic components built with transistors, rudim... \n", - "8 3 The third course in our programming fundamenta... \n", - "9 5 Introduction to differential and integral calc... \n", - "10 3 General biological principles. Topics include:... \n", - "11 3 An introduction to fundamental structures of c... \n", - "12 4 Introduction. Stoichiometry and the mole conce... \n", - "13 3 This course introduces students to the softwar... \n", - "14 3 Focuses on the role that psychological princip... \n", - "15 3 Basic concepts of logic, sets, partial order a... \n", - "16 3 Graphical and numerical exploration of data; s... \n", - "\n", - " keywords \\\n", - "0 [psychology, behavior, emotion, intelligence, ... \n", - "1 [computer, science, operating, system, systems] \n", - "2 [computer, science, programming, java] \n", - "3 [chemistry] \n", - "4 [computer, science, programming, java] \n", - "5 [math, mathematics, algebra, trigonometry] \n", - "6 [psychology, science, social, interaction, beh... \n", - "7 [computer, science, engineering, programming] \n", - "8 [computer, science, programming, java] \n", - "9 [math, mathematics, calculus, analytical, geom... \n", - "10 [biology, science, animal, evolution, genetics... \n", - "11 [computer, science, engineering, electrical, m... \n", - "12 [chemistry] \n", - "13 [computer, science, building, user, interface,... \n", - "14 [psychology, science, law, social, policy, beh... \n", - "15 [computer, science, math, mathematics, discret... \n", - "16 [statistics, statistical, math, mathematics, m... \n", - "\n", - " name number \\\n", - "0 Introduction to Psychology PSYCH_202 \n", - "1 Introduction to Operating Systems COMPSCI_537 \n", - "2 Programming 2 COMPSCI_300 \n", - "3 General Chemistry II CHEM_104 \n", - "4 Programming 1 COMPSCI_200 \n", - "5 Algebra and Trigonometry MATH_114 \n", - "6 Introductory Social Psychology PSYCH_456 \n", - "7 Introduction to Computer Engineering COMPSCI_252 \n", - "8 Programming 3 COMPSCI_400 \n", - "9 Calculus and Analytical Geometry 1 MATH_221 \n", - "10 Animal Biology BIOLOGY_101 \n", - "11 Machine Organization and Programming COMPSCI_354 \n", - "12 General Chemistry I CHEM_103 \n", - "13 Building User Interfaces COMPSCI_639 \n", - "14 Psychology, Law, and Social Policy PSYCH_401 \n", - "15 Introduction To Discrete Mathematics COMPSCI_240 \n", - "16 Accelerated Introduction to Statistical Methods STATS_302 \n", - "\n", - " requisites \\\n", - "0 [] \n", - "1 [[COMPSCI_354, COMPSCI_400]] \n", - "2 [[COMPSCI_200]] \n", - "3 [[MATH_114], [CHEM_103]] \n", - "4 [] \n", - "5 [] \n", - "6 [[PSYCH_202]] \n", - "7 [] \n", - "8 [[COMPSCI_300]] \n", - "9 [[MATH_114]] \n", - "10 [] \n", - "11 [[COMPSCI_252], [COMPSCI_300]] \n", - "12 [] \n", - "13 [[COMPSCI_300]] \n", - "14 [[PSYCH_202]] \n", - "15 [[MATH_221]] \n", - "16 [[MATH_221]] \n", - "\n", - " sections subject \n", - "0 [{'instructor': 'Jeff Henriques', 'location': ... Psychology \n", - "1 [{'instructor': 'Andrea Arpaci-Dusseau', 'loca... Computer Science \n", - "2 [{'instructor': 'Gary Dahl', 'location': 'AB20... Computer Science \n", - "3 [{'instructor': 'Linda Zelewski', 'location': ... Chemistry \n", - "4 [{'instructor': 'Jim Williams', 'location': '1... Computer Science \n", - "5 [{'instructor': 'Sharad Chandarana', 'location... Mathematics \n", - "6 [{'instructor': 'Abigail Letak', 'location': '... Psychology \n", - "7 [{'instructor': 'Joseph Krachey', 'location': ... Computer Science \n", - "8 [{'instructor': 'Gary Dahl', 'location': 'AB20... Computer Science \n", - "9 [{'instructor': 'Laurentiu Maxim', 'location':... Mathematics \n", - "10 [{'instructor': 'Sharon Thoma', 'location': '2... Biology \n", - "11 [{'instructor': 'James Skrentny', 'location': ... Computer Science \n", - "12 [{'instructor': 'Unknown', 'location': 'B10 In... Chemistry \n", - "13 [{'instructor': 'Bilge Mutlu', 'location': '12... Computer Science \n", - "14 [{'instructor': 'Gregory Van Rybroek', 'locati... Psychology \n", - "15 [{'instructor': 'Beck Hasti', 'location': '105... Computer Science \n", - "16 [{'instructor': 'Unknown', 'location': '331 Se... Statistics " - ] - }, - "execution_count": 34, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "all_course_frame = DataFrame(all_class_data)\n", - "all_course_frame" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### We may want to do some \"plumbing\" with our data." - ] - }, - { - "cell_type": "code", - "execution_count": 35, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "<div>\n", - "<style scoped>\n", - " .dataframe tbody tr th:only-of-type {\n", - " vertical-align: middle;\n", - " }\n", - "\n", - " .dataframe tbody tr th {\n", - " vertical-align: top;\n", - " }\n", - "\n", - " .dataframe thead th {\n", - " text-align: right;\n", - " }\n", - "</style>\n", - "<table border=\"1\" class=\"dataframe\">\n", - " <thead>\n", - " <tr style=\"text-align: right;\">\n", - " <th></th>\n", - " <th>credits</th>\n", - " <th>description</th>\n", - " <th>keywords</th>\n", - " <th>name</th>\n", - " <th>number</th>\n", - " <th>subject</th>\n", - " </tr>\n", - " </thead>\n", - " <tbody>\n", - " <tr>\n", - " <th>0</th>\n", - " <td>3</td>\n", - " <td>Behavior, including its development, motivatio...</td>\n", - " <td>[psychology, behavior, emotion, intelligence, ...</td>\n", - " <td>Introduction to Psychology</td>\n", - " <td>PSYCH_202</td>\n", - " <td>Psychology</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1</th>\n", - " <td>4</td>\n", - " <td>Input-output hardware, interrupt handling, pro...</td>\n", - " <td>[computer, science, operating, system, systems]</td>\n", - " <td>Introduction to Operating Systems</td>\n", - " <td>COMPSCI_537</td>\n", - " <td>Computer Science</td>\n", - " </tr>\n", - " <tr>\n", - " <th>2</th>\n", - " <td>3</td>\n", - " <td>Introduces students to Object-Oriented Program...</td>\n", - " <td>[computer, science, programming, java]</td>\n", - " <td>Programming 2</td>\n", - " <td>COMPSCI_300</td>\n", - " <td>Computer Science</td>\n", - " </tr>\n", - " <tr>\n", - " <th>3</th>\n", - " <td>5</td>\n", - " <td>Principles and application of chemical equilib...</td>\n", - " <td>[chemistry]</td>\n", - " <td>General Chemistry II</td>\n", - " <td>CHEM_104</td>\n", - " <td>Chemistry</td>\n", - " </tr>\n", - " <tr>\n", - " <th>4</th>\n", - " <td>3</td>\n", - " <td>Learn the process of incrementally developing ...</td>\n", - " <td>[computer, science, programming, java]</td>\n", - " <td>Programming 1</td>\n", - " <td>COMPSCI_200</td>\n", - " <td>Computer Science</td>\n", - " </tr>\n", - " <tr>\n", - " <th>5</th>\n", - " <td>5</td>\n", - " <td>The two semester sequence MATH_112-MATH_113 co...</td>\n", - " <td>[math, mathematics, algebra, trigonometry]</td>\n", - " <td>Algebra and Trigonometry</td>\n", - " <td>MATH_114</td>\n", - " <td>Mathematics</td>\n", - " </tr>\n", - " <tr>\n", - " <th>6</th>\n", - " <td>4</td>\n", - " <td>The systematic study of the individual in a so...</td>\n", - " <td>[psychology, science, social, interaction, beh...</td>\n", - " <td>Introductory Social Psychology</td>\n", - " <td>PSYCH_456</td>\n", - " <td>Psychology</td>\n", - " </tr>\n", - " <tr>\n", - " <th>7</th>\n", - " <td>2</td>\n", - " <td>Logic components built with transistors, rudim...</td>\n", - " <td>[computer, science, engineering, programming]</td>\n", - " <td>Introduction to Computer Engineering</td>\n", - " <td>COMPSCI_252</td>\n", - " <td>Computer Science</td>\n", - " </tr>\n", - " <tr>\n", - " <th>8</th>\n", - " <td>3</td>\n", - " <td>The third course in our programming fundamenta...</td>\n", - " <td>[computer, science, programming, java]</td>\n", - " <td>Programming 3</td>\n", - " <td>COMPSCI_400</td>\n", - " <td>Computer Science</td>\n", - " </tr>\n", - " <tr>\n", - " <th>9</th>\n", - " <td>5</td>\n", - " <td>Introduction to differential and integral calc...</td>\n", - " <td>[math, mathematics, calculus, analytical, geom...</td>\n", - " <td>Calculus and Analytical Geometry 1</td>\n", - " <td>MATH_221</td>\n", - " <td>Mathematics</td>\n", - " </tr>\n", - " <tr>\n", - " <th>10</th>\n", - " <td>3</td>\n", - " <td>General biological principles. Topics include:...</td>\n", - " <td>[biology, science, animal, evolution, genetics...</td>\n", - " <td>Animal Biology</td>\n", - " <td>BIOLOGY_101</td>\n", - " <td>Biology</td>\n", - " </tr>\n", - " <tr>\n", - " <th>11</th>\n", - " <td>3</td>\n", - " <td>An introduction to fundamental structures of c...</td>\n", - " <td>[computer, science, engineering, electrical, m...</td>\n", - " <td>Machine Organization and Programming</td>\n", - " <td>COMPSCI_354</td>\n", - " <td>Computer Science</td>\n", - " </tr>\n", - " <tr>\n", - " <th>12</th>\n", - " <td>4</td>\n", - " <td>Introduction. Stoichiometry and the mole conce...</td>\n", - " <td>[chemistry]</td>\n", - " <td>General Chemistry I</td>\n", - " <td>CHEM_103</td>\n", - " <td>Chemistry</td>\n", - " </tr>\n", - " <tr>\n", - " <th>13</th>\n", - " <td>3</td>\n", - " <td>This course introduces students to the softwar...</td>\n", - " <td>[computer, science, building, user, interface,...</td>\n", - " <td>Building User Interfaces</td>\n", - " <td>COMPSCI_639</td>\n", - " <td>Computer Science</td>\n", - " </tr>\n", - " <tr>\n", - " <th>14</th>\n", - " <td>3</td>\n", - " <td>Focuses on the role that psychological princip...</td>\n", - " <td>[psychology, science, law, social, policy, beh...</td>\n", - " <td>Psychology, Law, and Social Policy</td>\n", - " <td>PSYCH_401</td>\n", - " <td>Psychology</td>\n", - " </tr>\n", - " <tr>\n", - " <th>15</th>\n", - " <td>3</td>\n", - " <td>Basic concepts of logic, sets, partial order a...</td>\n", - " <td>[computer, science, math, mathematics, discret...</td>\n", - " <td>Introduction To Discrete Mathematics</td>\n", - " <td>COMPSCI_240</td>\n", - " <td>Computer Science</td>\n", - " </tr>\n", - " <tr>\n", - " <th>16</th>\n", - " <td>3</td>\n", - " <td>Graphical and numerical exploration of data; s...</td>\n", - " <td>[statistics, statistical, math, mathematics, m...</td>\n", - " <td>Accelerated Introduction to Statistical Methods</td>\n", - " <td>STATS_302</td>\n", - " <td>Statistics</td>\n", - " </tr>\n", - " </tbody>\n", - "</table>\n", - "</div>" - ], - "text/plain": [ - " credits description \\\n", - "0 3 Behavior, including its development, motivatio... \n", - "1 4 Input-output hardware, interrupt handling, pro... \n", - "2 3 Introduces students to Object-Oriented Program... \n", - "3 5 Principles and application of chemical equilib... \n", - "4 3 Learn the process of incrementally developing ... \n", - "5 5 The two semester sequence MATH_112-MATH_113 co... \n", - "6 4 The systematic study of the individual in a so... \n", - "7 2 Logic components built with transistors, rudim... \n", - "8 3 The third course in our programming fundamenta... \n", - "9 5 Introduction to differential and integral calc... \n", - "10 3 General biological principles. Topics include:... \n", - "11 3 An introduction to fundamental structures of c... \n", - "12 4 Introduction. Stoichiometry and the mole conce... \n", - "13 3 This course introduces students to the softwar... \n", - "14 3 Focuses on the role that psychological princip... \n", - "15 3 Basic concepts of logic, sets, partial order a... \n", - "16 3 Graphical and numerical exploration of data; s... \n", - "\n", - " keywords \\\n", - "0 [psychology, behavior, emotion, intelligence, ... \n", - "1 [computer, science, operating, system, systems] \n", - "2 [computer, science, programming, java] \n", - "3 [chemistry] \n", - "4 [computer, science, programming, java] \n", - "5 [math, mathematics, algebra, trigonometry] \n", - "6 [psychology, science, social, interaction, beh... \n", - "7 [computer, science, engineering, programming] \n", - "8 [computer, science, programming, java] \n", - "9 [math, mathematics, calculus, analytical, geom... \n", - "10 [biology, science, animal, evolution, genetics... \n", - "11 [computer, science, engineering, electrical, m... \n", - "12 [chemistry] \n", - "13 [computer, science, building, user, interface,... \n", - "14 [psychology, science, law, social, policy, beh... \n", - "15 [computer, science, math, mathematics, discret... \n", - "16 [statistics, statistical, math, mathematics, m... \n", - "\n", - " name number \\\n", - "0 Introduction to Psychology PSYCH_202 \n", - "1 Introduction to Operating Systems COMPSCI_537 \n", - "2 Programming 2 COMPSCI_300 \n", - "3 General Chemistry II CHEM_104 \n", - "4 Programming 1 COMPSCI_200 \n", - "5 Algebra and Trigonometry MATH_114 \n", - "6 Introductory Social Psychology PSYCH_456 \n", - "7 Introduction to Computer Engineering COMPSCI_252 \n", - "8 Programming 3 COMPSCI_400 \n", - "9 Calculus and Analytical Geometry 1 MATH_221 \n", - "10 Animal Biology BIOLOGY_101 \n", - "11 Machine Organization and Programming COMPSCI_354 \n", - "12 General Chemistry I CHEM_103 \n", - "13 Building User Interfaces COMPSCI_639 \n", - "14 Psychology, Law, and Social Policy PSYCH_401 \n", - "15 Introduction To Discrete Mathematics COMPSCI_240 \n", - "16 Accelerated Introduction to Statistical Methods STATS_302 \n", - "\n", - " subject \n", - "0 Psychology \n", - "1 Computer Science \n", - "2 Computer Science \n", - "3 Chemistry \n", - "4 Computer Science \n", - "5 Mathematics \n", - "6 Psychology \n", - "7 Computer Science \n", - "8 Computer Science \n", - "9 Mathematics \n", - "10 Biology \n", - "11 Computer Science \n", - "12 Chemistry \n", - "13 Computer Science \n", - "14 Psychology \n", - "15 Computer Science \n", - "16 Statistics " - ] - }, - "execution_count": 35, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Remove the 'sections' and 'requisites' column.\n", - "new_course_frame = all_course_frame.loc[:, \"credits\":\"number\"]\n", - "new_course_frame[\"subject\"] = all_course_frame.loc[:, \"subject\"]\n", - "new_course_frame" - ] - }, - { - "cell_type": "code", - "execution_count": 36, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "<div>\n", - "<style scoped>\n", - " .dataframe tbody tr th:only-of-type {\n", - " vertical-align: middle;\n", - " }\n", - "\n", - " .dataframe tbody tr th {\n", - " vertical-align: top;\n", - " }\n", - "\n", - " .dataframe thead th {\n", - " text-align: right;\n", - " }\n", - "</style>\n", - "<table border=\"1\" class=\"dataframe\">\n", - " <thead>\n", - " <tr style=\"text-align: right;\">\n", - " <th></th>\n", - " <th>credits</th>\n", - " <th>description</th>\n", - " <th>keywords</th>\n", - " <th>name</th>\n", - " <th>number</th>\n", - " <th>subject</th>\n", - " </tr>\n", - " </thead>\n", - " <tbody>\n", - " <tr>\n", - " <th>0</th>\n", - " <td>3</td>\n", - " <td>Behavior, including its development, motivatio...</td>\n", - " <td>psychology, behavior, emotion, intelligence, b...</td>\n", - " <td>Introduction to Psychology</td>\n", - " <td>PSYCH_202</td>\n", - " <td>Psychology</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1</th>\n", - " <td>4</td>\n", - " <td>Input-output hardware, interrupt handling, pro...</td>\n", - " <td>computer, science, operating, system, systems</td>\n", - " <td>Introduction to Operating Systems</td>\n", - " <td>COMPSCI_537</td>\n", - " <td>Computer Science</td>\n", - " </tr>\n", - " <tr>\n", - " <th>2</th>\n", - " <td>3</td>\n", - " <td>Introduces students to Object-Oriented Program...</td>\n", - " <td>computer, science, programming, java</td>\n", - " <td>Programming 2</td>\n", - " <td>COMPSCI_300</td>\n", - " <td>Computer Science</td>\n", - " </tr>\n", - " <tr>\n", - " <th>3</th>\n", - " <td>5</td>\n", - " <td>Principles and application of chemical equilib...</td>\n", - " <td>chemistry</td>\n", - " <td>General Chemistry II</td>\n", - " <td>CHEM_104</td>\n", - " <td>Chemistry</td>\n", - " </tr>\n", - " <tr>\n", - " <th>4</th>\n", - " <td>3</td>\n", - " <td>Learn the process of incrementally developing ...</td>\n", - " <td>computer, science, programming, java</td>\n", - " <td>Programming 1</td>\n", - " <td>COMPSCI_200</td>\n", - " <td>Computer Science</td>\n", - " </tr>\n", - " <tr>\n", - " <th>5</th>\n", - " <td>5</td>\n", - " <td>The two semester sequence MATH_112-MATH_113 co...</td>\n", - " <td>math, mathematics, algebra, trigonometry</td>\n", - " <td>Algebra and Trigonometry</td>\n", - " <td>MATH_114</td>\n", - " <td>Mathematics</td>\n", - " </tr>\n", - " <tr>\n", - " <th>6</th>\n", - " <td>4</td>\n", - " <td>The systematic study of the individual in a so...</td>\n", - " <td>psychology, science, social, interaction, beha...</td>\n", - " <td>Introductory Social Psychology</td>\n", - " <td>PSYCH_456</td>\n", - " <td>Psychology</td>\n", - " </tr>\n", - " <tr>\n", - " <th>7</th>\n", - " <td>2</td>\n", - " <td>Logic components built with transistors, rudim...</td>\n", - " <td>computer, science, engineering, programming</td>\n", - " <td>Introduction to Computer Engineering</td>\n", - " <td>COMPSCI_252</td>\n", - " <td>Computer Science</td>\n", - " </tr>\n", - " <tr>\n", - " <th>8</th>\n", - " <td>3</td>\n", - " <td>The third course in our programming fundamenta...</td>\n", - " <td>computer, science, programming, java</td>\n", - " <td>Programming 3</td>\n", - " <td>COMPSCI_400</td>\n", - " <td>Computer Science</td>\n", - " </tr>\n", - " <tr>\n", - " <th>9</th>\n", - " <td>5</td>\n", - " <td>Introduction to differential and integral calc...</td>\n", - " <td>math, mathematics, calculus, analytical, geome...</td>\n", - " <td>Calculus and Analytical Geometry 1</td>\n", - " <td>MATH_221</td>\n", - " <td>Mathematics</td>\n", - " </tr>\n", - " <tr>\n", - " <th>10</th>\n", - " <td>3</td>\n", - " <td>General biological principles. Topics include:...</td>\n", - " <td>biology, science, animal, evolution, genetics,...</td>\n", - " <td>Animal Biology</td>\n", - " <td>BIOLOGY_101</td>\n", - " <td>Biology</td>\n", - " </tr>\n", - " <tr>\n", - " <th>11</th>\n", - " <td>3</td>\n", - " <td>An introduction to fundamental structures of c...</td>\n", - " <td>computer, science, engineering, electrical, ma...</td>\n", - " <td>Machine Organization and Programming</td>\n", - " <td>COMPSCI_354</td>\n", - " <td>Computer Science</td>\n", - " </tr>\n", - " <tr>\n", - " <th>12</th>\n", - " <td>4</td>\n", - " <td>Introduction. Stoichiometry and the mole conce...</td>\n", - " <td>chemistry</td>\n", - " <td>General Chemistry I</td>\n", - " <td>CHEM_103</td>\n", - " <td>Chemistry</td>\n", - " </tr>\n", - " <tr>\n", - " <th>13</th>\n", - " <td>3</td>\n", - " <td>This course introduces students to the softwar...</td>\n", - " <td>computer, science, building, user, interface, ...</td>\n", - " <td>Building User Interfaces</td>\n", - " <td>COMPSCI_639</td>\n", - " <td>Computer Science</td>\n", - " </tr>\n", - " <tr>\n", - " <th>14</th>\n", - " <td>3</td>\n", - " <td>Focuses on the role that psychological princip...</td>\n", - " <td>psychology, science, law, social, policy, beha...</td>\n", - " <td>Psychology, Law, and Social Policy</td>\n", - " <td>PSYCH_401</td>\n", - " <td>Psychology</td>\n", - " </tr>\n", - " <tr>\n", - " <th>15</th>\n", - " <td>3</td>\n", - " <td>Basic concepts of logic, sets, partial order a...</td>\n", - " <td>computer, science, math, mathematics, discrete...</td>\n", - " <td>Introduction To Discrete Mathematics</td>\n", - " <td>COMPSCI_240</td>\n", - " <td>Computer Science</td>\n", - " </tr>\n", - " <tr>\n", - " <th>16</th>\n", - " <td>3</td>\n", - " <td>Graphical and numerical exploration of data; s...</td>\n", - " <td>statistics, statistical, math, mathematics, me...</td>\n", - " <td>Accelerated Introduction to Statistical Methods</td>\n", - " <td>STATS_302</td>\n", - " <td>Statistics</td>\n", - " </tr>\n", - " </tbody>\n", - "</table>\n", - "</div>" - ], - "text/plain": [ - " credits description \\\n", - "0 3 Behavior, including its development, motivatio... \n", - "1 4 Input-output hardware, interrupt handling, pro... \n", - "2 3 Introduces students to Object-Oriented Program... \n", - "3 5 Principles and application of chemical equilib... \n", - "4 3 Learn the process of incrementally developing ... \n", - "5 5 The two semester sequence MATH_112-MATH_113 co... \n", - "6 4 The systematic study of the individual in a so... \n", - "7 2 Logic components built with transistors, rudim... \n", - "8 3 The third course in our programming fundamenta... \n", - "9 5 Introduction to differential and integral calc... \n", - "10 3 General biological principles. Topics include:... \n", - "11 3 An introduction to fundamental structures of c... \n", - "12 4 Introduction. Stoichiometry and the mole conce... \n", - "13 3 This course introduces students to the softwar... \n", - "14 3 Focuses on the role that psychological princip... \n", - "15 3 Basic concepts of logic, sets, partial order a... \n", - "16 3 Graphical and numerical exploration of data; s... \n", - "\n", - " keywords \\\n", - "0 psychology, behavior, emotion, intelligence, b... \n", - "1 computer, science, operating, system, systems \n", - "2 computer, science, programming, java \n", - "3 chemistry \n", - "4 computer, science, programming, java \n", - "5 math, mathematics, algebra, trigonometry \n", - "6 psychology, science, social, interaction, beha... \n", - "7 computer, science, engineering, programming \n", - "8 computer, science, programming, java \n", - "9 math, mathematics, calculus, analytical, geome... \n", - "10 biology, science, animal, evolution, genetics,... \n", - "11 computer, science, engineering, electrical, ma... \n", - "12 chemistry \n", - "13 computer, science, building, user, interface, ... \n", - "14 psychology, science, law, social, policy, beha... \n", - "15 computer, science, math, mathematics, discrete... \n", - "16 statistics, statistical, math, mathematics, me... \n", - "\n", - " name number \\\n", - "0 Introduction to Psychology PSYCH_202 \n", - "1 Introduction to Operating Systems COMPSCI_537 \n", - "2 Programming 2 COMPSCI_300 \n", - "3 General Chemistry II CHEM_104 \n", - "4 Programming 1 COMPSCI_200 \n", - "5 Algebra and Trigonometry MATH_114 \n", - "6 Introductory Social Psychology PSYCH_456 \n", - "7 Introduction to Computer Engineering COMPSCI_252 \n", - "8 Programming 3 COMPSCI_400 \n", - "9 Calculus and Analytical Geometry 1 MATH_221 \n", - "10 Animal Biology BIOLOGY_101 \n", - "11 Machine Organization and Programming COMPSCI_354 \n", - "12 General Chemistry I CHEM_103 \n", - "13 Building User Interfaces COMPSCI_639 \n", - "14 Psychology, Law, and Social Policy PSYCH_401 \n", - "15 Introduction To Discrete Mathematics COMPSCI_240 \n", - "16 Accelerated Introduction to Statistical Methods STATS_302 \n", - "\n", - " subject \n", - "0 Psychology \n", - "1 Computer Science \n", - "2 Computer Science \n", - "3 Chemistry \n", - "4 Computer Science \n", - "5 Mathematics \n", - "6 Psychology \n", - "7 Computer Science \n", - "8 Computer Science \n", - "9 Mathematics \n", - "10 Biology \n", - "11 Computer Science \n", - "12 Chemistry \n", - "13 Computer Science \n", - "14 Psychology \n", - "15 Computer Science \n", - "16 Statistics " - ] - }, - "execution_count": 36, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Turn 'keywords' into a series of Strings and remove the '[', ']', '''\n", - "new_course_frame[\"keywords\"] = new_course_frame[\"keywords\"].astype('string')\n", - "new_course_frame[\"keywords\"] = new_course_frame[\"keywords\"].str.replace(\"[\", \"\", regex=False)\n", - "new_course_frame[\"keywords\"] = new_course_frame[\"keywords\"].str.replace(\"]\", \"\", regex=False)\n", - "new_course_frame[\"keywords\"] = new_course_frame[\"keywords\"].str.replace(\"'\", \"\", regex=False)\n", - "new_course_frame" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Pandas Operations" - ] - }, - { - "cell_type": "code", - "execution_count": 37, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "5" - ] - }, - "execution_count": 37, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# What is the most number of credits a course offers?\n", - "new_course_frame[\"credits\"].max()" - ] - }, - { - "cell_type": "code", - "execution_count": 38, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "2" - ] - }, - "execution_count": 38, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# What is the least number of credits a course offers?\n", - "new_course_frame[\"credits\"].min()" - ] - }, - { - "cell_type": "code", - "execution_count": 39, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "credits 2\n", - "description Logic components built with transistors, rudim...\n", - "keywords computer, science, engineering, programming\n", - "name Introduction to Computer Engineering\n", - "number COMPSCI_252\n", - "subject Computer Science\n", - "Name: 7, dtype: object" - ] - }, - "execution_count": 39, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# What is the info for that course?\n", - "new_course_frame.iloc[new_course_frame[\"credits\"].idxmin()]" - ] - }, - { - "cell_type": "code", - "execution_count": 40, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "<div>\n", - "<style scoped>\n", - " .dataframe tbody tr th:only-of-type {\n", - " vertical-align: middle;\n", - " }\n", - "\n", - " .dataframe tbody tr th {\n", - " vertical-align: top;\n", - " }\n", - "\n", - " .dataframe thead th {\n", - " text-align: right;\n", - " }\n", - "</style>\n", - "<table border=\"1\" class=\"dataframe\">\n", - " <thead>\n", - " <tr style=\"text-align: right;\">\n", - " <th></th>\n", - " <th>credits</th>\n", - " <th>description</th>\n", - " <th>keywords</th>\n", - " <th>name</th>\n", - " <th>number</th>\n", - " <th>subject</th>\n", - " </tr>\n", - " </thead>\n", - " <tbody>\n", - " <tr>\n", - " <th>2</th>\n", - " <td>3</td>\n", - " <td>Introduces students to Object-Oriented Program...</td>\n", - " <td>computer, science, programming, java</td>\n", - " <td>Programming 2</td>\n", - " <td>COMPSCI_300</td>\n", - " <td>Computer Science</td>\n", - " </tr>\n", - " <tr>\n", - " <th>4</th>\n", - " <td>3</td>\n", - " <td>Learn the process of incrementally developing ...</td>\n", - " <td>computer, science, programming, java</td>\n", - " <td>Programming 1</td>\n", - " <td>COMPSCI_200</td>\n", - " <td>Computer Science</td>\n", - " </tr>\n", - " <tr>\n", - " <th>7</th>\n", - " <td>2</td>\n", - " <td>Logic components built with transistors, rudim...</td>\n", - " <td>computer, science, engineering, programming</td>\n", - " <td>Introduction to Computer Engineering</td>\n", - " <td>COMPSCI_252</td>\n", - " <td>Computer Science</td>\n", - " </tr>\n", - " <tr>\n", - " <th>8</th>\n", - " <td>3</td>\n", - " <td>The third course in our programming fundamenta...</td>\n", - " <td>computer, science, programming, java</td>\n", - " <td>Programming 3</td>\n", - " <td>COMPSCI_400</td>\n", - " <td>Computer Science</td>\n", - " </tr>\n", - " <tr>\n", - " <th>11</th>\n", - " <td>3</td>\n", - " <td>An introduction to fundamental structures of c...</td>\n", - " <td>computer, science, engineering, electrical, ma...</td>\n", - " <td>Machine Organization and Programming</td>\n", - " <td>COMPSCI_354</td>\n", - " <td>Computer Science</td>\n", - " </tr>\n", - " </tbody>\n", - "</table>\n", - "</div>" - ], - "text/plain": [ - " credits description \\\n", - "2 3 Introduces students to Object-Oriented Program... \n", - "4 3 Learn the process of incrementally developing ... \n", - "7 2 Logic components built with transistors, rudim... \n", - "8 3 The third course in our programming fundamenta... \n", - "11 3 An introduction to fundamental structures of c... \n", - "\n", - " keywords \\\n", - "2 computer, science, programming, java \n", - "4 computer, science, programming, java \n", - "7 computer, science, engineering, programming \n", - "8 computer, science, programming, java \n", - "11 computer, science, engineering, electrical, ma... \n", - "\n", - " name number subject \n", - "2 Programming 2 COMPSCI_300 Computer Science \n", - "4 Programming 1 COMPSCI_200 Computer Science \n", - "7 Introduction to Computer Engineering COMPSCI_252 Computer Science \n", - "8 Programming 3 COMPSCI_400 Computer Science \n", - "11 Machine Organization and Programming COMPSCI_354 Computer Science " - ] - }, - "execution_count": 40, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# What courses contain the keyword \"programming\"?\n", - "mask = new_course_frame[\"keywords\"].str.contains(\"programming\")\n", - "new_course_frame[mask]" - ] - }, - { - "cell_type": "code", - "execution_count": 41, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'Psychology, Law, and Social Policy'" - ] - }, - "execution_count": 41, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# What course has the most lengthy description?\n", - "idx_max_desc = new_course_frame[\"description\"].str.len().idxmax()\n", - "new_course_frame.iloc[idx_max_desc]['name']" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Write it out to a CSV file on your drive\n", - "You now have your own copy!" - ] - }, - { - "cell_type": "code", - "execution_count": 42, - "metadata": {}, "outputs": [], "source": [ "# Write it all out to a single CSV file\n", - "new_course_frame.to_csv(\"my_course_data.csv\", index=False)" + "periods_df.to_csv(\"campus_weather.csv\", index=False)" ] }, { @@ -3247,7 +2427,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.7" + "version": "3.9.12" } }, "nbformat": 4, diff --git a/f22/meena_lec_notes/lec-29/lec_29_web1_template.ipynb b/f22/meena_lec_notes/lec-29/lec_29_web1_template.ipynb index b51ca54..85b3f9b 100644 --- a/f22/meena_lec_notes/lec-29/lec_29_web1_template.ipynb +++ b/f22/meena_lec_notes/lec-29/lec_29_web1_template.ipynb @@ -232,7 +232,7 @@ "metadata": {}, "source": [ "## requests.get : Simple string example\n", - "- URL: https://www.msyamkumar.com/hello.txt" + "- URL: https://cs220.cs.wisc.edu/hello.txt" ] }, { @@ -241,7 +241,7 @@ "metadata": {}, "outputs": [], "source": [ - "url = \"https://www.msyamkumar.com/hello.txt\"\n", + "url = \"https://cs220.cs.wisc.edu/hello.txt\"\n", "r = requests.get(url) # r is the response\n", "print(r.status_code)\n", "print(r.text)" @@ -254,7 +254,7 @@ "outputs": [], "source": [ "# Q: What if the web site does not exist?\n", - "typo_url = \"https://www.msyamkumar.com/hello.txttttt\"\n", + "typo_url = \"https://cs220.cs.wisc.edu/hello.txttttt\"\n", "r = requests.get(typo_url)\n", "print(r.status_code)\n", "print(r.text)\n", @@ -269,7 +269,7 @@ "outputs": [], "source": [ "# We can check for a status_code error by using an assert\n", - "typo_url = \"https://www.msyamkumar.com/hello.txttttt\"\n", + "typo_url = \"https://cs220.cs.wisc.edu/hello.txttttt\"\n", "r = requests.get(typo_url)\n", "assert r.status_code == 200\n", "print(r.status_code)\n", @@ -326,7 +326,7 @@ "metadata": {}, "source": [ "## requests.get : JSON file example\n", - "- URL: https://www.msyamkumar.com/scores.json\n", + "- URL: https://cs220.cs.wisc.edu/scores.json\n", "- `json.load` (FILE_OBJECT)\n", "- `json.loads` (STRING)" ] @@ -338,7 +338,7 @@ "outputs": [], "source": [ "# GETting a JSON file, the long way\n", - "url = \"https://www.msyamkumar.com/scores.json\"\n", + "url = \"https://cs220.cs.wisc.edu/scores.json\"\n", "r = requests.get(url)\n", "r.raise_for_status()\n", "urltext = r.text\n", @@ -354,7 +354,7 @@ "outputs": [], "source": [ "# GETting a JSON file, the shortcut way\n", - "url = \"https://www.msyamkumar.com/scores.json\"\n", + "url = \"https://cs220.cs.wisc.edu/scores.json\"\n", "#Shortcut to bypass using json.loads()\n", "r = requests.get(url)\n", "r.raise_for_status()\n", @@ -380,114 +380,14 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## DEMO: Course Enrollment" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Explore the API!\n", - "\n", - "https://coletnelson.us/cs220-api/classes\n", - "\n", - "https://coletnelson.us/cs220-api/classes_as_txt\n", - "\n", - "https://coletnelson.us/cs220-api/classes/MATH_221\n", - "\n", - "https://coletnelson.us/cs220-api/classes/COMPSCI_200\n", + "### Explore real-world JSON\n", "\n", - "... etc\n", + "How to explore an unknown JSON?\n", + "- If you run into a `dict`, try `.keys()` method to look at the keys of the dictionary, then use lookup process to explore further\n", + "- If you run into a `list`, iterate over the list and print each item\n", "\n", - "https://coletnelson.us/cs220-api/all_data" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Get the list of classes." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### When the data is `json`" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "url = \"https://coletnelson.us/cs220-api/classes\"\n", - "r = requests.get(url)\n", - "r.raise_for_status()\n", - "classes_list = r.json()\n", - "print(type(classes_list))\n", - "print(classes_list)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### When the data is `text`" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "url = \"https://coletnelson.us/cs220-api/classes_as_txt\"\n", - "r = requests.get(url)\n", - "r.raise_for_status()\n", - "classes_txt = r.text\n", - "print(type(classes_txt))\n", - "print(classes_txt)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "classes_txt_as_list = ???" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Get data for a specific class" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "url = \"https://coletnelson.us/cs220-api/classes/COMPSCI_200\"\n", - "r = requests.get(url)\n", - "r.raise_for_status()\n", - "cs200_data = r.json()\n", - "print(type(cs200_data))\n", - "print(cs200_data) # Too much data? Try print(cs220_data.keys())" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "cs200_data.keys()" + "### Weather for UW-Madison campus\n", + "- URL: https://api.weather.gov/gridpoints/MKX/37,63/forecast" ] }, { @@ -496,70 +396,11 @@ "metadata": {}, "outputs": [], "source": [ - "# Get the number of credits the course is worth\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Get the list of keywords for the course\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Get the official course name\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Get the number of sections offered.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Collect all the class data in a list called 'all_class_data'\n", - "all_class_data = []\n", - "for class_num in classes_list:\n", - " url = \"https://coletnelson.us/cs220-api/classes/\" + class_num\n", - " r = requests.get(url)\n", - " r.raise_for_status()\n", - " class_data = r.json()\n", - " all_class_data.append(???)\n", + "# TODO: GET the forecast\n", "\n", - "print(all_class_data) # Too much data? Try print(len(all_class_data))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "print(len(all_class_data))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Print the number of credits, course number, and name for each class.\n" + "# TODO: explore the type of the data structure \n", + "\n", + "# display the data\n" ] }, { @@ -568,7 +409,11 @@ "metadata": {}, "outputs": [], "source": [ - "# What is the average number of credits per course?\n" + "# TODO: display the keys of the weather_data dict\n", + "\n", + "# TODO: lookup the value corresponding to the 'properties'\n", + "\n", + "# TODO: you know what to do next ... explore type again\n" ] }, { @@ -577,7 +422,11 @@ "metadata": {}, "outputs": [], "source": [ - "# What are the unique subjects?\n" + "# TODO: display the keys of the properties dict\n", + "\n", + "# TODO: lookup the value corresponding to the 'periods'\n", + "\n", + "# TODO: you know what to do next ... explore type again\n" ] }, { @@ -586,20 +435,18 @@ "metadata": {}, "outputs": [], "source": [ - "# Besides PYSCH 202, what are the course numbers of the courses\n", - "# with the most sections offered (not including subsections)?\n", - "high_courses = []\n", - "high_sections = 0\n", - "for spec_class in all_class_data:\n", - " pass\n", - "high_courses" + "# TODO: extract periods list into a variable\n", + "\n", + "# TODO: create a DataFrame using periods_list\n", + "# TODO: What does each inner data structure represent in your DataFrame?\n", + "# Keep in mind that outer data structure is a list." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "### Can we make a Pandas dataframe? Yes!" + "#### What is the maximum and minimum observed temperatures? Include the temperatureUnit in your display" ] }, { @@ -608,15 +455,23 @@ "metadata": {}, "outputs": [], "source": [ - "all_course_frame = DataFrame(all_class_data)\n", - "all_course_frame" + "min_temp = \n", + "idx_min = \n", + "min_unit = \n", + "\n", + "max_temp = \n", + "idx_max = \n", + "max_unit = \n", + "\n", + "print(\"Minimum observed temperature is: {} degree {}\".format(min_temp, min_unit))\n", + "print(\"Maximum observed temperature is: {} degree {}\".format(max_temp, max_unit))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "### We may want to do some \"plumbing\" with our data." + "#### Which days `detailedForecast` contains `snow`?" ] }, { @@ -625,10 +480,8 @@ "metadata": {}, "outputs": [], "source": [ - "# Remove the 'sections' and 'requisites' column.\n", - "new_course_frame = all_course_frame.loc[:, \"credits\":\"number\"]\n", - "new_course_frame[\"subject\"] = all_course_frame.loc[:, \"subject\"]\n", - "new_course_frame" + "snow_days_df = \n", + "snow_days_df" ] }, { @@ -637,46 +490,14 @@ "metadata": {}, "outputs": [], "source": [ - "# Turn 'keywords' into a series of Strings and remove the '[', ']', '''\n", - "new_course_frame[\"keywords\"] = new_course_frame[\"keywords\"].astype('string')\n", - "new_course_frame[\"keywords\"] = new_course_frame[\"keywords\"].str.replace(\"[\", \"\", regex=False)\n", - "new_course_frame[\"keywords\"] = new_course_frame[\"keywords\"].str.replace(\"]\", \"\", regex=False)\n", - "new_course_frame[\"keywords\"] = new_course_frame[\"keywords\"].str.replace(\"'\", \"\", regex=False)\n", - "new_course_frame" + "# Extract only the name column information for the subset DataFrame\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "### Pandas Operations" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# What is the most number of credits a course offers?\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# What is the least number of credits a course offers?\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# What is the info for that course?\n" + "#### Which day's `detailedForecast` has the most lengthy description?" ] }, { @@ -685,7 +506,8 @@ "metadata": {}, "outputs": [], "source": [ - "# What courses contain the keyword \"programming\"?\n" + "idx_max_desc = \n", + "periods_df.iloc[idx_max_desc]['name']" ] }, { @@ -694,7 +516,7 @@ "metadata": {}, "outputs": [], "source": [ - "# What course has the most lengthy description?\n" + "# What was that forecast?\n" ] }, { @@ -712,7 +534,7 @@ "outputs": [], "source": [ "# Write it all out to a single CSV file\n", - "new_course_frame.to_csv(\"my_course_data.csv\", index=False)" + "periods_df.to_csv(\"campus_weather.csv\", index=False)" ] }, { @@ -759,7 +581,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.7" + "version": "3.9.12" } }, "nbformat": 4, diff --git a/f22/meena_lec_notes/lec-29/my_course_data.csv b/f22/meena_lec_notes/lec-29/my_course_data.csv deleted file mode 100644 index 7c9adb1..0000000 --- a/f22/meena_lec_notes/lec-29/my_course_data.csv +++ /dev/null @@ -1,18 +0,0 @@ -credits,description,keywords,name,number,subject -3,"Behavior, including its development, motivation, frustrations, emotion, intelligence, learning, forgetting, personality, language, thinking, and social behavior.","psychology, behavior, emotion, intelligence, brain",Introduction to Psychology,PSYCH_202,Psychology -4,"Input-output hardware, interrupt handling, properties of magnetic tapes, discs and drums, associative memories and virtual address translation techniques. Batch processing, time sharing and real-time systems, scheduling resource allocation, modular software systems, performance measurement and system evaluation.","computer, science, operating, system, systems",Introduction to Operating Systems,COMPSCI_537,Computer Science -3,"Introduces students to Object-Oriented Programming using classes and objects to solve more complex problems. Introduces array-based and linked data structures: including lists, stacks, and queues. Programming assignments require writing and developing multi-class (file) programs using interfaces, generics, and exception handling to solve challenging real world problems. Topics reviewed include reading/writing data and objects from/to files and exception handling, and command line arguments. Topics introduced: object-oriented design; class vs. object; create and define interfaces and iterators; searching and sorting; abstract data types (List,Stack,Queue,PriorityQueue(Heap),Binary Search Tree); generic interfaces (parametric polymorphism); how to design and write test methods and classes; array based vs. linked node implementations; introduction to complexity analysis; recursion.","computer, science, programming, java",Programming 2,COMPSCI_300,Computer Science -5,"Principles and application of chemical equilibrium, coordination chemistry, oxidation-reduction and electrochemistry, kinetics, nuclear chemistry, introduction to organic chemistry. Lecture, lab, and discussion.",chemistry,General Chemistry II,CHEM_104,Chemistry -3,"Learn the process of incrementally developing small (200-500 lines) programs along with the fundamental Computer Science topics. These topics include: problem abstraction and decomposition, the edit-compile-run cycle, using variables of primitive and more complex data types, conditional and loop-based flow control, basic testing and debugging techniques, how to define and call functions (methods), and IO processing techniques. Also teaches and reinforces good programming practices including the use of a consistent style, and meaningful documentation. Intended for students who have no prior programming experience.","computer, science, programming, java",Programming 1,COMPSCI_200,Computer Science -5,"The two semester sequence MATH_112-MATH_113 covers similar material as MATH_114, but in a slower pace.","math, mathematics, algebra, trigonometry",Algebra and Trigonometry,MATH_114,Mathematics -4,"The systematic study of the individual in a social context, including social interaction, motivation, attitudes, conformity, communication, leadership, personal relationships, and behavior in small groups.","psychology, science, social, interaction, behavior",Introductory Social Psychology,PSYCH_456,Psychology -2,"Logic components built with transistors, rudimentary Boolean algebra, basic combinational logic design, basic synchronous sequential logic design, basic computer organization and design, introductory machine- and assembly-language programming.","computer, science, engineering, programming",Introduction to Computer Engineering,COMPSCI_252,Computer Science -3,"The third course in our programming fundamentals sequence. It presumes that students understand and use functional and object-oriented design and abstract data types as needed. This course introduces balanced search trees, graphs, graph traversal algorithms, hash tables and sets, and complexity analysis and about classes of problems that require each data type. Students are required to design and implement using high quality professional code, a medium sized program, that demonstrates knowledge and use of latest language features, tools, and conventions. Additional topics introduced will include as needed for projects: inheritance and polymorphism; anonymous inner classes, lambda functions, performance analysis to discover and optimize critical code blocks. Students learn about industry standards for code development. Students will design and implement a medium size project with a more advanced user-interface design, such as a web or mobile application with a GUI and event- driven implementation; use of version-control software.","computer, science, programming, java",Programming 3,COMPSCI_400,Computer Science -5,Introduction to differential and integral calculus and plane analytic geometry; applications; transcendental functions.,"math, mathematics, calculus, analytical, geometry, differential, integral",Calculus and Analytical Geometry 1,MATH_221,Mathematics -3,"General biological principles. Topics include: evolution, ecology, animal behavior, cell structure and function, genetics and molecular genetics and the physiology of a variety of organ systems emphasizing function in humans.","biology, science, animal, evolution, genetics, ecology",Animal Biology,BIOLOGY_101,Biology -3,"An introduction to fundamental structures of computer systems and the C programming language with a focus on the low-level interrelationships and impacts on performance. Topics include the virtual address space and virtual memory, the heap and dynamic memory management, the memory hierarchy and caching, assembly language and the stack, communication and interrupts/signals, compiling and assemblers/linkers.","computer, science, engineering, electrical, machine, programming",Machine Organization and Programming,COMPSCI_354,Computer Science -4,"Introduction. Stoichiometry and the mole concept, the behavior of gases, liquids and solids, thermochemistry, electronic structure of atoms and chemical bonding, descriptive chemistry of selected elements and compounds, intermolecular forces. For students taking one year or more of college chemistry; serves as a prereq for CHEM_104; lecture, lab and discussion.",chemistry,General Chemistry I,CHEM_103,Chemistry -3,"This course introduces students to the software development of user interfaces (UIs). Topics covered include state-of-the-art (1) UI paradigms, such as event-driven interfaces, direct-manipulation interfaces, and dialogue-based interaction; (2) methods for capturing, interpreting, and responding to different forms of user input and states, including pointing, text entry, speech, touch, gestures, user activity, context, and physiological states; and (3) platform-specific UI development APIs, frameworks, and toolkits for platforms including web/mobile/desktop interfaces, natural user interfaces, and voice user interfaces. Through readings, lectures, and hands-on-activities, students will learn about the fundamental concepts, technologies, and methods in building user interfaces. Assignments will provide an opportunity to gain hands-on experience in the use of state-of-the-art UI development tools and build a UI development portfolio.","computer, science, building, user, interface, interfaces, design, ui",Building User Interfaces,COMPSCI_639,Computer Science -3,"Focuses on the role that psychological principles, research evidence and social science play in the laws of U.S. society, especially in the policies and mechanisms of social control of human behavior. The course will address the ways that society defines membership, and the role of psychology in how it determines who should be excluded or restricted from open society, in order to maintain a more civil society. In addition to learning the factual information about how selected processes work in the legal and social context, students will be asked to consider the role they can play as citizens in supporting or changing these social processes. The course will take a particular interest in psycholegal issues ""in action"" and in learning about the clinical-legal processes used to determine the disposition of individuals considered marginal in society. Finally, the course will address the mechanisms that are used to exclude individuals from open society through criminal and civil court processes, the role of psychology as a science, and the role of psychologists as behavioral experts in criminal and civil courts, and in shaping social policies.","psychology, science, law, social, policy, behavior","Psychology, Law, and Social Policy",PSYCH_401,Psychology -3,"Basic concepts of logic, sets, partial order and other relations, and functions. Basic concepts of mathematics (definitions, proofs, sets, functions, and relations) with a focus on discrete structures: integers, bits, strings, trees, and graphs. Propositional logic, Boolean algebra, and predicate logic. Mathematical induction and recursion. Invariants and algorithmic correctness. Recurrences and asymptotic growth analysis. Fundamentals of counting.","computer, science, math, mathematics, discrete, logic, algorithm, algorithms",Introduction To Discrete Mathematics,COMPSCI_240,Computer Science -3,"Graphical and numerical exploration of data; standard errors; distributions for statistical models including binomial, Poisson, normal; estimation; hypothesis testing; randomization tests; basic principles of experimental design; regression; ANOVA; categorical data analysis; goodness of fit; application. (intended for students wishing to take additional statistics courses).","statistics, statistical, math, mathematics, methods",Accelerated Introduction to Statistical Methods,STATS_302,Statistics -- GitLab