{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "arabic-farming",
   "metadata": {},
   "source": [
    "<!--\n",
    "title: Intro to Intermediate Python\n",
    "type: introduction\n",
    "duration: \"00:15\"\n",
    "creator: Brandi Michelle Butler\n",
    "-->\n",
    "\n",
    "\n",
    "<h1>Intro to Intermediate Python</h1>\n",
    "\n",
    "<!--\n",
    "\n",
    "\n",
    "## Overview\n",
    "This lesson starts with a recap of all of the topics covered up to this point, giving students a final chance to express their questions before we move beyond the basics. Most slides are in a \"Lecture + Question -> Answer\" format. It then has a very quick overview of the upcoming unit — user input and file I/O, abstraction, modules, and APIs.\n",
    "\n",
    "- As you go through this lesson, do frequent checks for understanding. It's important that students understand everything before we add more complicated things like `itertools` and APIs.\n",
    "\n",
    "- When you get to the new unit overview, put questions in the parking lot — there's a presentation on each topic.\n",
    "\n",
    "## Differentiation and Extensions\n",
    "\n",
    "- If students are breezing through this lesson, that's great! Don't stop for long on each slide.\n",
    "- If students are having trouble in the recap, add in We Dos.\n",
    "\n",
    "## Learning Objectives\n",
    "In this lesson, students will:\n",
    "\n",
    "- Confidently recap the previous units.\n",
    "- Describe key components of the upcoming unit.\n",
    "\n",
    "## Duration\n",
    "20 minutes\n",
    "\n",
    "## Suggested Agenda\n",
    "\n",
    "| Time | Activity |\n",
    "| --- | --- |\n",
    "| 0:00 - 0:03 | Welcome |\n",
    "| 0:04 - 0:12 | Basic Topics Recap |\n",
    "| 0:13 - 0:17 | Intermediate Topics Preview |\n",
    "| 0:17 - 0:20 | Summary |\n",
    "\n",
    "\n",
    "## In Class: Materials\n",
    "- Projector\n",
    "- Internet connection\n",
    "- Python 3\n",
    "-->\n",
    "\n",
    "\n",
    "---\n",
    "\n",
    "## Learning Objectives\n",
    "*After this lesson, you will be able to:*\n",
    "\n",
    "- Confidently recap the previous units.\n",
    "- Describe key components of the upcoming unit.\n",
    "\n",
    "---\n",
    "\n",
    "## Leveling Up\n",
    "\n",
    "You're leveling up!\n",
    "\n",
    "You have the proper foundation. Now, let's check how you're doing.\n",
    "\n",
    "\n",
    "---\n",
    "\n",
    "## Let's Review: Lists\n",
    "\n",
    "- A collection of items stored in a single variable.\n",
    "- Created with square brackets (`[]`).\n",
    "- Begin counting at `0`.\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "premium-bulgaria",
   "metadata": {},
   "outputs": [],
   "source": [
    "my_queens = [\"Cersei\", \"Daenerys\", \"Arwen\", \"Elsa\", \"Guinevere\"]\n",
    "step_counts_this_week = [8744, 5256, 7453, 3097, 4122, 2908, 6720]\n",
    "\n",
    "# We can also mix types.\n",
    "weird_list = [1, \"weird\", [\"nested list\"], \"eh?\"]\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "surprised-tower",
   "metadata": {},
   "source": [
    "\n",
    "> **Challenge:** Can you recall how to slice a section of the list? For example, items 2 through 5 of `step_counts_this_week`?\n",
    "\n",
    "---\n",
    "\n",
    "## Answer: Lists Challenge\n",
    "\n",
    "- Python uses a `:` to represent a range of indices.\n",
    "- Beware of off-by-one errors!\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "moving-network",
   "metadata": {},
   "outputs": [],
   "source": [
    "days_2_thru_5 = step_counts_this_week[2:6] # Items 2, 3, 4, and 5"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cathedral-hurricane",
   "metadata": {},
   "source": [
    "\n",
    "> **Pro tip:** It's `6` instead of `5` because the range is exclusive.\n",
    "\n",
    "---\n",
    "\n",
    "## Let's Review: Loops and Iteration\n",
    "\n",
    "What about looping a list?\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "legendary-chorus",
   "metadata": {},
   "outputs": [],
   "source": [
    "my_queens = [\"Cersei\", \"Daenerys\", \"Arwen\", \"Elsa\", \"Guinevere\"]\n",
    "\n",
    "for queen in my_queens:\n",
    "    print(queen, \"is the most powerful queen!\")\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "statistical-manor",
   "metadata": {},
   "source": [
    "\n",
    "> **Challenge:** What if I want to loop from 1 to 10 and print out the numbers? How do I do this without a data structure to loop over?\n",
    "\n",
    "\n",
    "---\n",
    "\n",
    "## Answer: Loops Challenge\n",
    "\n",
    "To loop 1–10 without a data structure:\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "processed-initial",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Remember, \"i\" is a common name for a counter/index in programming!\n",
    "for i in range(1, 11):\n",
    "    print(i)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "foster-cabin",
   "metadata": {},
   "source": [
    "\n",
    "- Why do you think we put `11` in the code?\n",
    "- What values does this print?\n",
    "\n",
    "---\n",
    "\n",
    "\n",
    "## Let's Review: Sets\n",
    "\n",
    "- Lists that don't have duplicates.\n",
    "- Created with curly braces (`{}`) or from lists with the `set()` function.\n",
    "- Aren't indexed — elements are in any order!\n",
    "- Handy for storing emails, user names, and other unique elements.\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "isolated-evening",
   "metadata": {},
   "outputs": [],
   "source": [
    "email_set = {'my_email@gmail.com', 'second_email@yahoo.com', \"third_email@hotmail.com\"}\n",
    "# Or from a list:\n",
    "my_list = [\"red\",  \"yellow\", \"green\", \"red\", \"green\"]\n",
    "my_set = set(my_list)\n",
    "# => {\"red\",  \"yellow\", \"green\"}"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "color-trailer",
   "metadata": {},
   "source": [
    "\n",
    "---\n",
    "\n",
    "\n",
    "## Let's Review: Tuples\n",
    "\n",
    "- Lists that can't be changed!\n",
    "- Created with parentheses (`()`).\n",
    "- Can't add, pop, remove, or otherwise change elements after creation.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "charged-investigation",
   "metadata": {},
   "outputs": [],
   "source": [
    "rainbow_colors_tuple = (\"red\", \"orange\", \"yellow\", \"green\", \"blue\", \"indigo\", \"violet\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "clinical-webmaster",
   "metadata": {},
   "source": [
    "\n",
    "---\n",
    "\n",
    "## Let's Review: Dictionaries\n",
    "\n",
    "- A collection of key-value pairs.\n",
    "- Created with curly braces (`{key: value, key: value}`).\n",
    "- Values can be anything!\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ordinary-portal",
   "metadata": {},
   "outputs": [],
   "source": [
    "my_puppy = {\n",
    "    \"name\": \"Fido\",\n",
    "    \"breed\": \"Corgi\",\n",
    "    \"age\": 3,\n",
    "    \"vaccinated\": True,\n",
    "    \"fave toy\": [\"chew sticks\", \"big sticks\", \"any sticks\"]\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "united-rwanda",
   "metadata": {},
   "source": [
    "\n",
    "> **Challenge:** Can you recall how to iterate (loop) over each key of `my_puppy` and print out both the key and the corresponding value?\n",
    "\n",
    "---\n",
    "\n",
    "## Answer: Dictionaries Challenge\n",
    "\n",
    "Iterating a dictionary is similar to a list:\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "written-layer",
   "metadata": {},
   "outputs": [],
   "source": [
    "for key in my_puppy:\n",
    "    print(key, \"-\", my_puppy[key])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "afraid-riding",
   "metadata": {},
   "source": [
    "\n",
    "---\n",
    "\n",
    "## Let's Review: Functions\n",
    "\n",
    "- Bits of code that can be used repeatedly.\n",
    "- Enable DRY — Don't Repeat Yourself.\n",
    "- Declared with `def`, `()`, and `:`.\n",
    "- Declare the function *above* the function call!\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "synthetic-classics",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Function definition:\n",
    "def say_hello():\n",
    "    print(\"hello!\")\n",
    "\n",
    "# Run the function three times.\n",
    "say_hello()\n",
    "say_hello()\n",
    "say_hello()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "noble-tolerance",
   "metadata": {},
   "source": [
    "\n",
    "---\n",
    "\n",
    "## Let's Review: Function Parameters\n",
    "\n",
    "Parameters are in the function definition.\n",
    "\n",
    "- Arguments are in the function call.\n",
    "- Useful for very similar code with only minor variations.\n",
    "\n",
    "**Challenge:** Rewrite the code below to use a single function with one parameter."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "younger-voluntary",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Function definitions:\n",
    "def say_hello_ada():\n",
    "    print(\"hello, Ada\")\n",
    "\n",
    "def say_hello_alan():\n",
    "    print(\"hello, Alan\")\n",
    "\n",
    "def say_hello_linus():\n",
    "    print(\"hello, Linus\")\n",
    "\n",
    "# Call the functions:\n",
    "say_hello_ada()\n",
    "say_hello_alan()\n",
    "say_hello_linus()\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fabulous-accounting",
   "metadata": {},
   "source": [
    "> **Challenge:** Could we do this with a single function that has a parameter called \"name\"?\n",
    "\n",
    "---\n",
    "\n",
    "## Function Parameters: Solution"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "lightweight-width",
   "metadata": {},
   "outputs": [],
   "source": [
    "def say_hello(name):\n",
    "    print(\"hello,\", name)\n",
    "    \n",
    "say_hello('Ada')\n",
    "say_hello('Alan')\n",
    "say_hello('Linus')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "annual-heart",
   "metadata": {},
   "source": [
    "---\n",
    "\n",
    "## Let's Review: Return Statements\n",
    "\n",
    "- Bring data out of a function.\n",
    "- Cause the function to exit.\n",
    "- Aren't a `print` statement!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "bulgarian-elimination",
   "metadata": {},
   "outputs": [],
   "source": [
    "def multiply(x, y):\n",
    "    return x * y\n",
    "\n",
    "result = multiply(3, 4) # Result is now equal to 12.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "tamil-begin",
   "metadata": {},
   "source": [
    "\n",
    "---\n",
    "\n",
    "## Let's Review: Classes\n",
    "\n",
    "- Templates (aka, blueprints) for objects.\n",
    "- Can contain methods and/or variables.\n",
    "- `self` is a reference to the created object.\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "negative-price",
   "metadata": {},
   "outputs": [],
   "source": [
    "class Animal():\n",
    "    def __init__(self):\n",
    "        self.energy = 50\n",
    "\n",
    "    def get_status(self):\n",
    "        if self.energy < 20:\n",
    "            print(\"I'm hungry!\")\n",
    "        elif self.energy > 100:\n",
    "            print(\"I'm stuffed!\")\n",
    "        else:\n",
    "            print(\"I'm doing well!\")\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "assigned-wound",
   "metadata": {},
   "source": [
    "\n",
    "> **Challenge:** How do you declare a new `Animal`?\n",
    "\n",
    "---\n",
    "\n",
    "## Answer: Classes\n",
    "\n",
    "Declaring a new `Animal` from the class:\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "raised-anderson",
   "metadata": {},
   "outputs": [],
   "source": [
    "my_animal = Animal() # Creates a new Animal instance.\n",
    "my_animal.get_status() # Prints \"I'm doing well!\"\n",
    "my_animal.energy += 100 # We can access properties!\n",
    "my_animal.get_status() # Prints \"I'm stuffed!\"\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "innocent-glass",
   "metadata": {},
   "source": [
    "\n",
    "---\n",
    "\n",
    "## Let's Review: Inheritance\n",
    "\n",
    "\n",
    "A class can inherit properties and methods from another class.\n",
    "\n",
    "Create a new class, `Dog`, which inherits from `Animal`.\n",
    "\n",
    "- `Dog` has an extra function, `bark()`, that prints `\"bark\"`.\n",
    "- `Dog` has an extra property, `breed`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "decent-disorder",
   "metadata": {},
   "outputs": [],
   "source": [
    "class Animal():\n",
    "    def __init__(self):\n",
    "        self.energy = 50\n",
    "\n",
    "    def get_status(self):\n",
    "        if self.energy < 20:\n",
    "            print(\"I'm hungry!\")\n",
    "        elif self.energy > 100:\n",
    "            print(\"I'm stuffed!\")\n",
    "        else:\n",
    "            print(\"I'm doing well!\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "reflected-baptist",
   "metadata": {},
   "outputs": [],
   "source": [
    "class Dog(Animal):\n",
    "    def __init__(self, breed):\n",
    "        super().__init__()\n",
    "        self.breed = breed\n",
    "        \n",
    "    def bark(self):\n",
    "        print(\"bark\")\n",
    "\n",
    "# Declare a new dog.\n",
    "fido = Dog('lab')\n",
    "# Call the `bark()` function.\n",
    "fido.bark()\n",
    "# Check the dog's breed and energy.\n",
    "print(fido.breed)\n",
    "print(fido.energy)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "responsible-calibration",
   "metadata": {},
   "source": [
    "\n",
    "---\n",
    "\n",
    "## Knowledge Check\n",
    "\n",
    "We're about to move on to the next unit: Intermediate Python.\n",
    "\n",
    "Any questions?\n",
    "\n",
    "> Don't be shy! If you have a question, so do others!\n",
    "\n",
    "---\n",
    "\n",
    "## Switching Gears: Preview\n",
    "\n",
    "The next unit covers many topics, including:\n",
    "\n",
    "- User input*\n",
    "- File I/O*\n",
    "- Modules and libraries\n",
    "- APIs*\n",
    "- Data analysis with Pandas\n",
    "\n",
    "*These topics will not be covered during class, but some material on them is available in the `unit-5-intermediate` folder.\n",
    "\n",
    "You don't need to memorize them now! This is just an overview.\n",
    "\n",
    "---\n",
    "\n",
    "## User Input and File I/O\n",
    "\n",
    "You've seen this a few times already with `input()`.\n",
    "\n",
    "We'll build real interactions between your Python programs and other files — or the person using your app!\n",
    "\n",
    "We'll use Pandas for this, but there are other packages you can use."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "independent-navigation",
   "metadata": {},
   "source": [
    "\n",
    "---\n",
    "\n",
    "## Modules and Libraries\n",
    "\n",
    "\n",
    "We mentioned these in the pre-work!\n",
    "\n",
    "Modules and libraries are:\n",
    "\n",
    "- Code that others have written.\n",
    "- Free to use!\n",
    "- Useful extensions of the Python language (e.g., a fancy date and time formatter).\n",
    "\n",
    "This one tells us when Mother's Day is for a given year:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "necessary-zimbabwe",
   "metadata": {},
   "outputs": [],
   "source": [
    "from pytime import pytime\n",
    "# Now we can use any function in the datetime module.\n",
    "\n",
    "print(pytime.mother(2013))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "satisfactory-parameter",
   "metadata": {},
   "source": [
    "</aside>\n",
    "\n",
    "---\n",
    "\n",
    "## What Is an API?\n",
    "\n",
    "Not only can we use code other people have written; we can also use data that they've made available to us.\n",
    "\n",
    "We can incorporate stocks, movie ratings, or GIFs from the internet into your program!\n",
    "\n",
    "This API lists *Star Wars* characters."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "perceived-composition",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Import requests module.\n",
    "import requests\n",
    "\n",
    "# Call the Star Wars API (swapi).\n",
    "res = requests.get('https://swapi.dev/api/people').json()\n",
    "\n",
    "# Print the result count.\n",
    "print(\"found\", res[\"count\"], \"results. Here are the first 10:\\n\")\n",
    "\n",
    "# Loop through characters: Append to file and print to screen\n",
    "for person in res[\"results\"]:\n",
    "    print(person[\"name\"])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "external-affairs",
   "metadata": {},
   "source": [
    "\n",
    "---\n",
    "\n",
    "## Summary and Q&A\n",
    "\n",
    "We reviewed topics from earlier lessons:\n",
    "\n",
    "* Lists, sets, tuples, and dictionaries.\n",
    "* Loops and iteration.\n",
    "* Functions, parameters, and return statements.\n",
    "* Classes and inheritance.\n",
    "\n",
    "We brushed the surface on some upcoming topics:\n",
    "\n",
    "* User input and file I/O.\n",
    "* Modules and libraries.\n",
    "* APIs.\n",
    "\n",
    "Let's jump in to it!\n",
    "\n",
    "---\n",
    "\n",
    "## Additional Reading and Resources\n",
    "\n",
    "Now that you have an understanding of basic programming, here are some cool people to read about:\n",
    "\n",
    "- **[Ada Lovelace](https://en.wikipedia.org/wiki/Ada_Lovelace):** Regarded as the first programmer.\n",
    "- **[Alan Turing](https://en.wikipedia.org/wiki/Alan_Turing):** Considered the father of theoretical computer and artificial intelligence; helped crack the enigma code during World War II.\n",
    "- **[Linus Torvalds](https://en.wikipedia.org/wiki/Linus_Torvalds):** Creator of Linux OS and Git.\n"
   ]
  }
 ],
 "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.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
