Skip to content

Instantly share code, notes, and snippets.

@page2me
Forked from kenjyco/01-Learning-Python3.md
Created February 21, 2020 09:29
Show Gist options
  • Save page2me/f3abab201a63a6a01827714dd3e61f81 to your computer and use it in GitHub Desktop.
Save page2me/f3abab201a63a6a01827714dd3e61f81 to your computer and use it in GitHub Desktop.

Revisions

  1. @kenjyco kenjyco renamed this gist Aug 6, 2019. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  2. @kenjyco kenjyco revised this gist Aug 6, 2019. 1 changed file with 0 additions and 2 deletions.
    2 changes: 0 additions & 2 deletions .gitignore
    Original file line number Diff line number Diff line change
    @@ -1,2 +0,0 @@
    *.swp
    .ipynb_checkpoints/
  3. @kenjyco kenjyco revised this gist Aug 6, 2019. 1 changed file with 13 additions and 0 deletions.
    13 changes: 13 additions & 0 deletions LICENSE.txt
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,13 @@
    The MIT License (MIT)

    Copyright (c) 2019 Ken

    Permission is hereby granted, free of charge, to any person obtaining a copy
    of this software and associated documentation files (the "Software"), to deal
    in the Software without restriction, including without limitation the rights
    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    copies of the Software, and to permit persons to whom the Software is
    furnished to do so, subject to the following conditions:

    The above copyright notice and this permission notice shall be included in all
    copies or substantial portions of the Software.
  4. @kenjyco kenjyco revised this gist Mar 22, 2017. 1 changed file with 1 addition and 5 deletions.
    6 changes: 1 addition & 5 deletions learning-python3.ipynb
    Original file line number Diff line number Diff line change
    @@ -8,12 +8,8 @@
    },
    "source": [
    "[learning-python3.ipynb]: https://gist.github.com/kenjyco/69eeb503125035f21a9d/raw/learning-python3.ipynb\n",
    "[learning-python3.pdf]: https://gist.github.com/kenjyco/69eeb503125035f21a9d/raw/learning-python3.pdf\n",
    "\n",
    "Right-click -> \"save link as\" \n",
    "\n",
    "- [https://gist.github.com/kenjyco/69eeb503125035f21a9d/raw/learning-python3.ipynb][learning-python3.ipynb] to get most up-to-date version of this notebook file\n",
    "- [https://gist.github.com/kenjyco/69eeb503125035f21a9d/raw/learning-python3.pdf][learning-python3.pdf] to get PDF version of this notebook (with output displayed for all \"code cells\")\n",
    "Right-click -> \"save link as\" [https://gist.github.com/kenjyco/69eeb503125035f21a9d/raw/learning-python3.ipynb][learning-python3.ipynb] to get most up-to-date version of this notebook file.\n",
    "\n",
    "## Quick note about Jupyter cells\n",
    "\n",
  5. @kenjyco kenjyco renamed this gist Mar 22, 2017. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  6. @kenjyco kenjyco revised this gist Mar 22, 2017. 1 changed file with 2 additions and 0 deletions.
    2 changes: 2 additions & 0 deletions .gitignore
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,2 @@
    *.swp
    .ipynb_checkpoints/
  7. @kenjyco kenjyco revised this gist Mar 22, 2017. 2 changed files with 2 additions and 8 deletions.
    10 changes: 2 additions & 8 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -1,17 +1,11 @@
    [Python 3]: https://www.python.org/about/
    [Jupyter Notebook]: https://jupyter.readthedocs.io/en/latest/running.html
    [learning-python3.ipynb]: https://gist.github.com/kenjyco/69eeb503125035f21a9d/raw/learning-python3.ipynb
    [learning-python3.pdf]: https://gist.github.com/kenjyco/69eeb503125035f21a9d/raw/learning-python3.pdf

    ## Learning Python 3

    This gist provides:

    - the [learning-python3.ipynb][] notebook file, which can be viewed and edited in a
    [Jupyter Notebook][] server to learn [Python 3][]
    - the [learning-python3.pdf][] PDF file, which is a non-interactive version of
    the notebook file for offline viewing (with output displayed for all "code
    cells")
    This gist provides the [learning-python3.ipynb][] notebook file, which can be
    viewed and edited in a [Jupyter Notebook][] server to learn [Python 3][].

    Once you load the notebook file to your local jupyter server, you can edit any
    of the cells, add new cells, or delete cells. The **code cells** will let you
    Binary file removed learning-python3.pdf
    Binary file not shown.
  8. @kenjyco kenjyco revised this gist Mar 22, 2017. 1 changed file with 4 additions and 33 deletions.
    37 changes: 4 additions & 33 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -1,5 +1,4 @@
    [Python 3]: https://www.python.org/about/
    [tryjupyter]: https://try.jupyter.org
    [Jupyter Notebook]: https://jupyter.readthedocs.io/en/latest/running.html
    [learning-python3.ipynb]: https://gist.github.com/kenjyco/69eeb503125035f21a9d/raw/learning-python3.ipynb
    [learning-python3.pdf]: https://gist.github.com/kenjyco/69eeb503125035f21a9d/raw/learning-python3.pdf
    @@ -14,35 +13,7 @@ This gist provides:
    the notebook file for offline viewing (with output displayed for all "code
    cells")

    Once you load the notebook file (to your local jupyter server, or
    [https://try.jupyter.org][tryjupyter]), you can edit any of the cells, add new cells,
    or delete cells. The **code cells** will let you type and execute Python code
    (since we are using the Python 3 **kernel**). The **markdown cells** will let
    you type notes with a simple syntax.

    The online server does not remember any changes you make, so be sure to download
    your file again before closing.

    ## Load a notebook file to https://try.jupyter.org

    Visit [https://try.jupyter.org][tryjupyter] in your web browser, then click on the **`Upload`**
    button near the upper right corner

    ![1](http://i.imgur.com/XDNKV6O.png)

    Navigate your filesystem to find your `*.ipynb` file, select it with your
    mouse, and click **`Open`**

    ![2](http://i.imgur.com/UQB0ZzE.png)

    Click the new **`Upload`** button that appears next to your file name

    ![3](http://i.imgur.com/m6fvGSL.png)

    Click on your uploaded notebook file

    ![4](http://i.imgur.com/XPry4JK.png)

    Interact with your notebook!

    ![5](http://i.imgur.com/dyeI55W.png)
    Once you load the notebook file to your local jupyter server, you can edit any
    of the cells, add new cells, or delete cells. The **code cells** will let you
    type and execute Python code (since we are using the Python 3 **kernel**). The
    **markdown cells** will let you type notes with a simple syntax.
  9. @kenjyco kenjyco revised this gist Mar 22, 2017. 1 changed file with 1327 additions and 278 deletions.
    1,605 changes: 1,327 additions & 278 deletions learning-python3.ipynb
    Original file line number Diff line number Diff line change
    @@ -2,7 +2,10 @@
    "cells": [
    {
    "cell_type": "markdown",
    "metadata": {},
    "metadata": {
    "deletable": true,
    "editable": true
    },
    "source": [
    "[learning-python3.ipynb]: https://gist.github.com/kenjyco/69eeb503125035f21a9d/raw/learning-python3.ipynb\n",
    "[learning-python3.pdf]: https://gist.github.com/kenjyco/69eeb503125035f21a9d/raw/learning-python3.pdf\n",
    @@ -68,7 +71,10 @@
    },
    {
    "cell_type": "markdown",
    "metadata": {},
    "metadata": {
    "deletable": true,
    "editable": true
    },
    "source": [
    "## References\n",
    "\n",
    @@ -82,7 +88,10 @@
    },
    {
    "cell_type": "markdown",
    "metadata": {},
    "metadata": {
    "deletable": true,
    "editable": true
    },
    "source": [
    "## Python objects, basic types, and variables\n",
    "\n",
    @@ -114,7 +123,10 @@
    },
    {
    "cell_type": "markdown",
    "metadata": {},
    "metadata": {
    "deletable": true,
    "editable": true
    },
    "source": [
    "## Basic operators\n",
    "\n",
    @@ -152,9 +164,11 @@
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "execution_count": 1,
    "metadata": {
    "collapsed": false
    "collapsed": false,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "source": [
    @@ -170,71 +184,149 @@
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "execution_count": 2,
    "metadata": {
    "collapsed": false
    "collapsed": false,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "outputs": [
    {
    "data": {
    "text/plain": [
    "7"
    ]
    },
    "execution_count": 2,
    "metadata": {},
    "output_type": "execute_result"
    }
    ],
    "source": [
    "# Addition\n",
    "num1 + num2"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "execution_count": 3,
    "metadata": {
    "collapsed": false
    "collapsed": false,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "outputs": [
    {
    "data": {
    "text/plain": [
    "-10.41"
    ]
    },
    "execution_count": 3,
    "metadata": {},
    "output_type": "execute_result"
    }
    ],
    "source": [
    "# Subtraction\n",
    "num2 - num3"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "execution_count": 4,
    "metadata": {
    "collapsed": false
    "collapsed": false,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "outputs": [
    {
    "data": {
    "text/plain": [
    "-4.446"
    ]
    },
    "execution_count": 4,
    "metadata": {},
    "output_type": "execute_result"
    }
    ],
    "source": [
    "# Multiplication\n",
    "num3 * num4"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "execution_count": 5,
    "metadata": {
    "collapsed": false
    "collapsed": false,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "outputs": [
    {
    "data": {
    "text/plain": [
    "-0.08571428571428572"
    ]
    },
    "execution_count": 5,
    "metadata": {},
    "output_type": "execute_result"
    }
    ],
    "source": [
    "# Division\n",
    "num4 / num5"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "execution_count": 6,
    "metadata": {
    "collapsed": false
    "collapsed": false,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "outputs": [
    {
    "data": {
    "text/plain": [
    "343"
    ]
    },
    "execution_count": 6,
    "metadata": {},
    "output_type": "execute_result"
    }
    ],
    "source": [
    "# Exponent\n",
    "num5 ** num6"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "execution_count": 7,
    "metadata": {
    "collapsed": false
    "collapsed": false,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "outputs": [
    {
    "data": {
    "text/plain": [
    "15.11"
    ]
    },
    "execution_count": 7,
    "metadata": {},
    "output_type": "execute_result"
    }
    ],
    "source": [
    "# Increment existing variable\n",
    "num7 += 4\n",
    @@ -243,11 +335,24 @@
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "execution_count": 8,
    "metadata": {
    "collapsed": false
    "collapsed": false,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "outputs": [
    {
    "data": {
    "text/plain": [
    "1"
    ]
    },
    "execution_count": 8,
    "metadata": {},
    "output_type": "execute_result"
    }
    ],
    "source": [
    "# Decrement existing variable\n",
    "num6 -= 2\n",
    @@ -256,11 +361,24 @@
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "execution_count": 9,
    "metadata": {
    "collapsed": false
    "collapsed": false,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "outputs": [
    {
    "data": {
    "text/plain": [
    "37.05"
    ]
    },
    "execution_count": 9,
    "metadata": {},
    "output_type": "execute_result"
    }
    ],
    "source": [
    "# Multiply & re-assign\n",
    "num3 *= 5\n",
    @@ -269,11 +387,24 @@
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "execution_count": 10,
    "metadata": {
    "collapsed": false
    "collapsed": false,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "outputs": [
    {
    "data": {
    "text/plain": [
    "-101.14999999999999"
    ]
    },
    "execution_count": 10,
    "metadata": {},
    "output_type": "execute_result"
    }
    ],
    "source": [
    "# Assign the value of an expression to a variable\n",
    "num8 = num1 + num2 * num3\n",
    @@ -282,69 +413,136 @@
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "execution_count": 11,
    "metadata": {
    "collapsed": false
    "collapsed": false,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "outputs": [
    {
    "data": {
    "text/plain": [
    "True"
    ]
    },
    "execution_count": 11,
    "metadata": {},
    "output_type": "execute_result"
    }
    ],
    "source": [
    "# Are these two expressions equal to each other?\n",
    "num1 + num2 == num5"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "execution_count": 12,
    "metadata": {
    "collapsed": false
    "collapsed": false,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "outputs": [
    {
    "data": {
    "text/plain": [
    "True"
    ]
    },
    "execution_count": 12,
    "metadata": {},
    "output_type": "execute_result"
    }
    ],
    "source": [
    "# Are these two expressions not equal to each other?\n",
    "num3 != num4"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "execution_count": 13,
    "metadata": {
    "collapsed": false
    "collapsed": false,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "outputs": [
    {
    "data": {
    "text/plain": [
    "False"
    ]
    },
    "execution_count": 13,
    "metadata": {},
    "output_type": "execute_result"
    }
    ],
    "source": [
    "# Is the first expression less than the second expression?\n",
    "num5 < num6"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "execution_count": 14,
    "metadata": {
    "collapsed": false
    "collapsed": false,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "outputs": [
    {
    "data": {
    "text/plain": [
    "True"
    ]
    },
    "execution_count": 14,
    "metadata": {},
    "output_type": "execute_result"
    }
    ],
    "source": [
    "# Is this expression True?\n",
    "5 > 3 > 1"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "execution_count": 15,
    "metadata": {
    "collapsed": false
    "collapsed": false,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "outputs": [
    {
    "data": {
    "text/plain": [
    "True"
    ]
    },
    "execution_count": 15,
    "metadata": {},
    "output_type": "execute_result"
    }
    ],
    "source": [
    "# Is this expression True?\n",
    "5 > 3 < 4 == 3 + 1"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "execution_count": 16,
    "metadata": {
    "collapsed": true
    "collapsed": true,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "source": [
    @@ -355,83 +553,174 @@
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "execution_count": 17,
    "metadata": {
    "collapsed": false
    "collapsed": false,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "outputs": [
    {
    "data": {
    "text/plain": [
    "'an example of using the + operator'"
    ]
    },
    "execution_count": 17,
    "metadata": {},
    "output_type": "execute_result"
    }
    ],
    "source": [
    "# Addition\n",
    "simple_string1 + ' of using the + operator'"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "execution_count": 18,
    "metadata": {
    "collapsed": false
    "collapsed": false,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "outputs": [
    {
    "data": {
    "text/plain": [
    "'an example'"
    ]
    },
    "execution_count": 18,
    "metadata": {},
    "output_type": "execute_result"
    }
    ],
    "source": [
    "# Notice that the string was not modified\n",
    "simple_string1"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "execution_count": 19,
    "metadata": {
    "collapsed": false
    "collapsed": false,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "outputs": [
    {
    "data": {
    "text/plain": [
    "'oranges oranges oranges oranges '"
    ]
    },
    "execution_count": 19,
    "metadata": {},
    "output_type": "execute_result"
    }
    ],
    "source": [
    "# Multiplication\n",
    "simple_string2 * 4"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "execution_count": 20,
    "metadata": {
    "collapsed": false
    "collapsed": false,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "outputs": [
    {
    "data": {
    "text/plain": [
    "'oranges '"
    ]
    },
    "execution_count": 20,
    "metadata": {},
    "output_type": "execute_result"
    }
    ],
    "source": [
    "# This string wasn't modified either\n",
    "simple_string2"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "execution_count": 21,
    "metadata": {
    "collapsed": false
    "collapsed": false,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "outputs": [
    {
    "data": {
    "text/plain": [
    "False"
    ]
    },
    "execution_count": 21,
    "metadata": {},
    "output_type": "execute_result"
    }
    ],
    "source": [
    "# Are these two expressions equal to each other?\n",
    "simple_string1 == simple_string2"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "execution_count": 22,
    "metadata": {
    "collapsed": false
    "collapsed": false,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "outputs": [
    {
    "data": {
    "text/plain": [
    "True"
    ]
    },
    "execution_count": 22,
    "metadata": {},
    "output_type": "execute_result"
    }
    ],
    "source": [
    "# Are these two expressions equal to each other?\n",
    "simple_string1 == 'an example'"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "execution_count": 23,
    "metadata": {
    "collapsed": false
    "collapsed": false,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "outputs": [
    {
    "data": {
    "text/plain": [
    "'an example that re-assigned the original string'"
    ]
    },
    "execution_count": 23,
    "metadata": {},
    "output_type": "execute_result"
    }
    ],
    "source": [
    "# Add and re-assign\n",
    "simple_string1 += ' that re-assigned the original string'\n",
    @@ -440,11 +729,24 @@
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "execution_count": 24,
    "metadata": {
    "collapsed": false
    "collapsed": false,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "outputs": [
    {
    "data": {
    "text/plain": [
    "'oranges oranges oranges '"
    ]
    },
    "execution_count": 24,
    "metadata": {},
    "output_type": "execute_result"
    }
    ],
    "source": [
    "# Multiply and re-assign\n",
    "simple_string2 *= 3\n",
    @@ -453,9 +755,11 @@
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "execution_count": 25,
    "metadata": {
    "collapsed": true
    "collapsed": true,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "source": [
    @@ -464,7 +768,10 @@
    },
    {
    "cell_type": "markdown",
    "metadata": {},
    "metadata": {
    "deletable": true,
    "editable": true
    },
    "source": [
    "## Basic containers\n",
    "\n",
    @@ -489,9 +796,11 @@
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "execution_count": 26,
    "metadata": {
    "collapsed": true
    "collapsed": true,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "source": [
    @@ -504,35 +813,74 @@
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "execution_count": 27,
    "metadata": {
    "collapsed": false
    "collapsed": false,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "outputs": [
    {
    "data": {
    "text/plain": [
    "[3, 5, 6, 3, 'dog', 'cat', False]"
    ]
    },
    "execution_count": 27,
    "metadata": {},
    "output_type": "execute_result"
    }
    ],
    "source": [
    "# Items in the list object are stored in the order they were added\n",
    "list1"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "execution_count": 28,
    "metadata": {
    "collapsed": false
    "collapsed": false,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "outputs": [
    {
    "data": {
    "text/plain": [
    "(3, 5, 6, 3, 'dog', 'cat', False)"
    ]
    },
    "execution_count": 28,
    "metadata": {},
    "output_type": "execute_result"
    }
    ],
    "source": [
    "# Items in the tuple object are stored in the order they were added\n",
    "tuple1"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "execution_count": 29,
    "metadata": {
    "collapsed": false
    "collapsed": false,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "outputs": [
    {
    "data": {
    "text/plain": [
    "{False, 3, 5, 6, 'dog', 'cat'}"
    ]
    },
    "execution_count": 29,
    "metadata": {},
    "output_type": "execute_result"
    }
    ],
    "source": [
    "# Items in the set object are not stored in the order they were added\n",
    "# Also, notice that the value 3 only appears once in this set object\n",
    @@ -541,23 +889,49 @@
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "execution_count": 30,
    "metadata": {
    "collapsed": false
    "collapsed": false,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "outputs": [
    {
    "data": {
    "text/plain": [
    "{'age': 23, 'fav_foods': ['pizza', 'fruit', 'fish'], 'name': 'Jane'}"
    ]
    },
    "execution_count": 30,
    "metadata": {},
    "output_type": "execute_result"
    }
    ],
    "source": [
    "# Items in the dict object are not stored in the order they were added\n",
    "dict1"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "execution_count": 31,
    "metadata": {
    "collapsed": false
    "collapsed": false,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "outputs": [
    {
    "data": {
    "text/plain": [
    "[3, 5, 6, 3, 'dog', 'cat', False, 5, 'grapes']"
    ]
    },
    "execution_count": 31,
    "metadata": {},
    "output_type": "execute_result"
    }
    ],
    "source": [
    "# Add and re-assign\n",
    "list1 += [5, 'grapes']\n",
    @@ -566,11 +940,24 @@
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "execution_count": 32,
    "metadata": {
    "collapsed": false
    "collapsed": false,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "outputs": [
    {
    "data": {
    "text/plain": [
    "(3, 5, 6, 3, 'dog', 'cat', False, 5, 'grapes')"
    ]
    },
    "execution_count": 32,
    "metadata": {},
    "output_type": "execute_result"
    }
    ],
    "source": [
    "# Add and re-assign\n",
    "tuple1 += (5, 'grapes')\n",
    @@ -579,31 +966,60 @@
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "execution_count": 33,
    "metadata": {
    "collapsed": false
    "collapsed": false,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "outputs": [
    {
    "data": {
    "text/plain": [
    "[1, 2, 3, 4, 1, 2, 3, 4]"
    ]
    },
    "execution_count": 33,
    "metadata": {},
    "output_type": "execute_result"
    }
    ],
    "source": [
    "# Multiply\n",
    "[1, 2, 3, 4] * 2"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "execution_count": 34,
    "metadata": {
    "collapsed": false
    "collapsed": false,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "outputs": [
    {
    "data": {
    "text/plain": [
    "(1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4)"
    ]
    },
    "execution_count": 34,
    "metadata": {},
    "output_type": "execute_result"
    }
    ],
    "source": [
    "# Multiply\n",
    "(1, 2, 3, 4) * 3"
    ]
    },
    {
    "cell_type": "markdown",
    "metadata": {},
    "metadata": {
    "deletable": true,
    "editable": true
    },
    "source": [
    "## Accessing data in containers\n",
    "\n",
    @@ -619,91 +1035,185 @@
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "execution_count": 35,
    "metadata": {
    "collapsed": false
    "collapsed": false,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "outputs": [
    {
    "data": {
    "text/plain": [
    "3"
    ]
    },
    "execution_count": 35,
    "metadata": {},
    "output_type": "execute_result"
    }
    ],
    "source": [
    "# Access the first item in a sequence\n",
    "list1[0]"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "execution_count": 36,
    "metadata": {
    "collapsed": false
    "collapsed": false,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "outputs": [
    {
    "data": {
    "text/plain": [
    "'grapes'"
    ]
    },
    "execution_count": 36,
    "metadata": {},
    "output_type": "execute_result"
    }
    ],
    "source": [
    "# Access the last item in a sequence\n",
    "tuple1[-1]"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "execution_count": 37,
    "metadata": {
    "collapsed": false
    "collapsed": false,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "outputs": [
    {
    "data": {
    "text/plain": [
    "'examp'"
    ]
    },
    "execution_count": 37,
    "metadata": {},
    "output_type": "execute_result"
    }
    ],
    "source": [
    "# Access a range of items in a sequence\n",
    "simple_string1[3:8]"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "execution_count": 38,
    "metadata": {
    "collapsed": false
    "collapsed": false,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "outputs": [
    {
    "data": {
    "text/plain": [
    "(3, 5, 6, 3, 'dog', 'cat')"
    ]
    },
    "execution_count": 38,
    "metadata": {},
    "output_type": "execute_result"
    }
    ],
    "source": [
    "# Access a range of items in a sequence\n",
    "tuple1[:-3]"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "execution_count": 39,
    "metadata": {
    "collapsed": false
    "collapsed": false,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "outputs": [
    {
    "data": {
    "text/plain": [
    "['dog', 'cat', False, 5, 'grapes']"
    ]
    },
    "execution_count": 39,
    "metadata": {},
    "output_type": "execute_result"
    }
    ],
    "source": [
    "# Access a range of items in a sequence\n",
    "list1[4:]"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "execution_count": 40,
    "metadata": {
    "collapsed": false
    "collapsed": false,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "outputs": [
    {
    "data": {
    "text/plain": [
    "'Jane'"
    ]
    },
    "execution_count": 40,
    "metadata": {},
    "output_type": "execute_result"
    }
    ],
    "source": [
    "# Access an item in a dictionary\n",
    "dict1['name']"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "execution_count": 41,
    "metadata": {
    "collapsed": false
    "collapsed": false,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "outputs": [
    {
    "data": {
    "text/plain": [
    "'fish'"
    ]
    },
    "execution_count": 41,
    "metadata": {},
    "output_type": "execute_result"
    }
    ],
    "source": [
    "# Access an element of a sequence in a dictionary\n",
    "dict1['fav_foods'][2]"
    ]
    },
    {
    "cell_type": "markdown",
    "metadata": {},
    "metadata": {
    "deletable": true,
    "editable": true
    },
    "source": [
    "## Python built-in functions and callables\n",
    "\n",
    @@ -728,83 +1238,174 @@
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "execution_count": 42,
    "metadata": {
    "collapsed": false
    "collapsed": false,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "outputs": [
    {
    "data": {
    "text/plain": [
    "str"
    ]
    },
    "execution_count": 42,
    "metadata": {},
    "output_type": "execute_result"
    }
    ],
    "source": [
    "# Use the type() function to determine the type of an object\n",
    "type(simple_string1)"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "execution_count": 43,
    "metadata": {
    "collapsed": false
    "collapsed": false,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "outputs": [
    {
    "data": {
    "text/plain": [
    "3"
    ]
    },
    "execution_count": 43,
    "metadata": {},
    "output_type": "execute_result"
    }
    ],
    "source": [
    "# Use the len() function to determine how many items are in a container\n",
    "len(dict1)"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "execution_count": 44,
    "metadata": {
    "collapsed": false
    "collapsed": false,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "outputs": [
    {
    "data": {
    "text/plain": [
    "24"
    ]
    },
    "execution_count": 44,
    "metadata": {},
    "output_type": "execute_result"
    }
    ],
    "source": [
    "# Use the len() function to determine how many items are in a container\n",
    "len(simple_string2)"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "execution_count": 45,
    "metadata": {
    "collapsed": false
    "collapsed": false,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "outputs": [
    {
    "data": {
    "text/plain": [
    "True"
    ]
    },
    "execution_count": 45,
    "metadata": {},
    "output_type": "execute_result"
    }
    ],
    "source": [
    "# Use the callable() function to determine if an object is callable\n",
    "callable(len)"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "execution_count": 46,
    "metadata": {
    "collapsed": false
    "collapsed": false,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "outputs": [
    {
    "data": {
    "text/plain": [
    "False"
    ]
    },
    "execution_count": 46,
    "metadata": {},
    "output_type": "execute_result"
    }
    ],
    "source": [
    "# Use the callable() function to determine if an object is callable\n",
    "callable(dict1)"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "execution_count": 47,
    "metadata": {
    "collapsed": false
    "collapsed": false,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "outputs": [
    {
    "data": {
    "text/plain": [
    "[-3, 1, 2, 3.6, 5, 7, 10]"
    ]
    },
    "execution_count": 47,
    "metadata": {},
    "output_type": "execute_result"
    }
    ],
    "source": [
    "# Use the sorted() function to return a new list from a container, with the items sorted\n",
    "sorted([10, 1, 3.6, 7, 5, 2, -3])"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "execution_count": 48,
    "metadata": {
    "collapsed": false
    "collapsed": false,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "outputs": [
    {
    "data": {
    "text/plain": [
    "['California', 'Chicago', 'ants', 'cats', 'dogs', 'mice', 'zebras']"
    ]
    },
    "execution_count": 48,
    "metadata": {},
    "output_type": "execute_result"
    }
    ],
    "source": [
    "# Use the sorted() function to return a new list from a container, with the items sorted\n",
    "# - notice that capitalized strings come first\n",
    @@ -813,103 +1414,210 @@
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "execution_count": 49,
    "metadata": {
    "collapsed": false
    "collapsed": false,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "outputs": [
    {
    "data": {
    "text/plain": [
    "25.6"
    ]
    },
    "execution_count": 49,
    "metadata": {},
    "output_type": "execute_result"
    }
    ],
    "source": [
    "# Use the sum() function to compute the sum of a container of numbers\n",
    "sum([10, 1, 3.6, 7, 5, 2, -3])"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "execution_count": 50,
    "metadata": {
    "collapsed": false
    "collapsed": false,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "outputs": [
    {
    "data": {
    "text/plain": [
    "-3"
    ]
    },
    "execution_count": 50,
    "metadata": {},
    "output_type": "execute_result"
    }
    ],
    "source": [
    "# Use the min() function to determine the smallest item in a container\n",
    "min([10, 1, 3.6, 7, 5, 2, -3])"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "execution_count": 51,
    "metadata": {
    "collapsed": false
    "collapsed": false,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "outputs": [
    {
    "data": {
    "text/plain": [
    "'a'"
    ]
    },
    "execution_count": 51,
    "metadata": {},
    "output_type": "execute_result"
    }
    ],
    "source": [
    "# Use the min() function to determine the smallest item in a container\n",
    "min(['g', 'z', 'a', 'y'])"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "execution_count": 52,
    "metadata": {
    "collapsed": false
    "collapsed": false,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "outputs": [
    {
    "data": {
    "text/plain": [
    "10"
    ]
    },
    "execution_count": 52,
    "metadata": {},
    "output_type": "execute_result"
    }
    ],
    "source": [
    "# Use the max() function to determine the largest item in a container\n",
    "max([10, 1, 3.6, 7, 5, 2, -3])"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "execution_count": 53,
    "metadata": {
    "collapsed": false
    "collapsed": false,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "outputs": [
    {
    "data": {
    "text/plain": [
    "'s'"
    ]
    },
    "execution_count": 53,
    "metadata": {},
    "output_type": "execute_result"
    }
    ],
    "source": [
    "# Use the max() function to determine the largest item in a container\n",
    "max('gibberish')"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "execution_count": 54,
    "metadata": {
    "collapsed": false
    "collapsed": false,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "outputs": [
    {
    "data": {
    "text/plain": [
    "10"
    ]
    },
    "execution_count": 54,
    "metadata": {},
    "output_type": "execute_result"
    }
    ],
    "source": [
    "# Use the abs() function to determine the absolute value of a number\n",
    "abs(10)"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "execution_count": 55,
    "metadata": {
    "collapsed": false
    "collapsed": false,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "outputs": [
    {
    "data": {
    "text/plain": [
    "12"
    ]
    },
    "execution_count": 55,
    "metadata": {},
    "output_type": "execute_result"
    }
    ],
    "source": [
    "# Use the abs() function to determine the absolute value of a number\n",
    "abs(-12)"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "execution_count": 56,
    "metadata": {
    "collapsed": false
    "collapsed": false,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "outputs": [
    {
    "data": {
    "text/plain": [
    "\"{False, 3, 5, 6, 'dog', 'cat'}\""
    ]
    },
    "execution_count": 56,
    "metadata": {},
    "output_type": "execute_result"
    }
    ],
    "source": [
    "# Use the repr() function to return a string representation of an object\n",
    "repr(set1)"
    ]
    },
    {
    "cell_type": "markdown",
    "metadata": {},
    "metadata": {
    "deletable": true,
    "editable": true
    },
    "source": [
    "## Python object attributes (methods and properties)\n",
    "\n",
    @@ -926,7 +1634,10 @@
    },
    {
    "cell_type": "markdown",
    "metadata": {},
    "metadata": {
    "deletable": true,
    "editable": true
    },
    "source": [
    "## Some methods on string objects\n",
    "\n",
    @@ -941,9 +1652,11 @@
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "execution_count": 57,
    "metadata": {
    "collapsed": false
    "collapsed": false,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "source": [
    @@ -953,155 +1666,324 @@
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "execution_count": 58,
    "metadata": {
    "collapsed": false
    "collapsed": false,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "outputs": [
    {
    "data": {
    "text/plain": [
    "'This is a string'"
    ]
    },
    "execution_count": 58,
    "metadata": {},
    "output_type": "execute_result"
    }
    ],
    "source": [
    "# Return a capitalized version of the string\n",
    "a_string.capitalize()"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "execution_count": 59,
    "metadata": {
    "collapsed": false
    "collapsed": false,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "outputs": [
    {
    "data": {
    "text/plain": [
    "'THIS IS A STRING'"
    ]
    },
    "execution_count": 59,
    "metadata": {},
    "output_type": "execute_result"
    }
    ],
    "source": [
    "# Return an uppercase version of the string\n",
    "a_string.upper()"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "execution_count": 60,
    "metadata": {
    "collapsed": false
    "collapsed": false,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "outputs": [
    {
    "data": {
    "text/plain": [
    "'this is a string'"
    ]
    },
    "execution_count": 60,
    "metadata": {},
    "output_type": "execute_result"
    }
    ],
    "source": [
    "# Return a lowercase version of the string\n",
    "a_string.lower()"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "execution_count": 61,
    "metadata": {
    "collapsed": false
    "collapsed": false,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "outputs": [
    {
    "data": {
    "text/plain": [
    "'tHis is a sTriNg'"
    ]
    },
    "execution_count": 61,
    "metadata": {},
    "output_type": "execute_result"
    }
    ],
    "source": [
    "# Notice that the methods called have not actually modified the string\n",
    "a_string"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "execution_count": 62,
    "metadata": {
    "collapsed": false
    "collapsed": false,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "outputs": [
    {
    "data": {
    "text/plain": [
    "3"
    ]
    },
    "execution_count": 62,
    "metadata": {},
    "output_type": "execute_result"
    }
    ],
    "source": [
    "# Count number of occurences of a substring in the string\n",
    "a_string.count('i')"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "execution_count": 63,
    "metadata": {
    "collapsed": false
    "collapsed": false,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "outputs": [
    {
    "data": {
    "text/plain": [
    "1"
    ]
    },
    "execution_count": 63,
    "metadata": {},
    "output_type": "execute_result"
    }
    ],
    "source": [
    "# Count number of occurences of a substring in the string after a certain position\n",
    "a_string.count('i', 7)"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "execution_count": 64,
    "metadata": {
    "collapsed": false
    "collapsed": false,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "outputs": [
    {
    "data": {
    "text/plain": [
    "2"
    ]
    },
    "execution_count": 64,
    "metadata": {},
    "output_type": "execute_result"
    }
    ],
    "source": [
    "# Count number of occurences of a substring in the string\n",
    "a_string.count('is')"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "execution_count": 65,
    "metadata": {
    "collapsed": false
    "collapsed": false,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "outputs": [
    {
    "data": {
    "text/plain": [
    "False"
    ]
    },
    "execution_count": 65,
    "metadata": {},
    "output_type": "execute_result"
    }
    ],
    "source": [
    "# Does the string start with 'this'?\n",
    "a_string.startswith('this')"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "execution_count": 66,
    "metadata": {
    "collapsed": false
    "collapsed": false,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "outputs": [
    {
    "data": {
    "text/plain": [
    "True"
    ]
    },
    "execution_count": 66,
    "metadata": {},
    "output_type": "execute_result"
    }
    ],
    "source": [
    "# Does the lowercase string start with 'this'?\n",
    "a_string.lower().startswith('this')"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "execution_count": 67,
    "metadata": {
    "collapsed": false
    "collapsed": false,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "outputs": [
    {
    "data": {
    "text/plain": [
    "True"
    ]
    },
    "execution_count": 67,
    "metadata": {},
    "output_type": "execute_result"
    }
    ],
    "source": [
    "# Does the string end with 'Ng'?\n",
    "a_string.endswith('Ng')"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "execution_count": 68,
    "metadata": {
    "collapsed": false
    "collapsed": false,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "outputs": [
    {
    "data": {
    "text/plain": [
    "'tHXYZ XYZ a sTriNg'"
    ]
    },
    "execution_count": 68,
    "metadata": {},
    "output_type": "execute_result"
    }
    ],
    "source": [
    "# Return a version of the string with a substring replaced with something else\n",
    "a_string.replace('is', 'XYZ')"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "execution_count": 69,
    "metadata": {
    "collapsed": false
    "collapsed": false,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "outputs": [
    {
    "data": {
    "text/plain": [
    "'tH!s !s a sTr!Ng'"
    ]
    },
    "execution_count": 69,
    "metadata": {},
    "output_type": "execute_result"
    }
    ],
    "source": [
    "# Return a version of the string with a substring replaced with something else\n",
    "a_string.replace('i', '!')"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "execution_count": 70,
    "metadata": {
    "collapsed": false
    "collapsed": false,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "outputs": [
    {
    "data": {
    "text/plain": [
    "'tH!s !s a sTriNg'"
    ]
    },
    "execution_count": 70,
    "metadata": {},
    "output_type": "execute_result"
    }
    ],
    "source": [
    "# Return a version of the string with the first 2 occurences a substring replaced with something else\n",
    "a_string.replace('i', '!', 2)"
    @@ -1110,7 +1992,9 @@
    {
    "cell_type": "markdown",
    "metadata": {
    "collapsed": true
    "collapsed": true,
    "deletable": true,
    "editable": true
    },
    "source": [
    "## Some methods on list objects\n",
    @@ -1126,7 +2010,9 @@
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": true
    "collapsed": true,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "source": []
    @@ -1135,14 +2021,19 @@
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": true
    "collapsed": true,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "source": []
    },
    {
    "cell_type": "markdown",
    "metadata": {},
    "metadata": {
    "deletable": true,
    "editable": true
    },
    "source": [
    "## Some methods on set objects\n",
    "\n",
    @@ -1163,7 +2054,9 @@
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": true
    "collapsed": true,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "source": []
    @@ -1172,14 +2065,19 @@
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": true
    "collapsed": true,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "source": []
    },
    {
    "cell_type": "markdown",
    "metadata": {},
    "metadata": {
    "deletable": true,
    "editable": true
    },
    "source": [
    "## Some methods on dict objects\n",
    "\n",
    @@ -1198,7 +2096,9 @@
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": true
    "collapsed": true,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "source": []
    @@ -1207,14 +2107,19 @@
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    "collapsed": false,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "source": []
    },
    {
    "cell_type": "markdown",
    "metadata": {},
    "metadata": {
    "deletable": true,
    "editable": true
    },
    "source": [
    "## Positional arguments and keyword arguments to callables\n",
    "\n",
    @@ -1241,7 +2146,9 @@
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": true
    "collapsed": true,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "source": []
    @@ -1250,14 +2157,19 @@
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": true
    "collapsed": true,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "source": []
    },
    {
    "cell_type": "markdown",
    "metadata": {},
    "metadata": {
    "deletable": true,
    "editable": true
    },
    "source": [
    "## Formatting strings and using placeholders"
    ]
    @@ -1266,7 +2178,9 @@
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": true
    "collapsed": true,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "source": []
    @@ -1275,14 +2189,19 @@
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": true
    "collapsed": true,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "source": []
    },
    {
    "cell_type": "markdown",
    "metadata": {},
    "metadata": {
    "deletable": true,
    "editable": true
    },
    "source": [
    "## Python \"for loops\"\n",
    "\n",
    @@ -1295,7 +2214,9 @@
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": true
    "collapsed": true,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "source": []
    @@ -1304,14 +2225,19 @@
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": true
    "collapsed": true,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "source": []
    },
    {
    "cell_type": "markdown",
    "metadata": {},
    "metadata": {
    "deletable": true,
    "editable": true
    },
    "source": [
    "## Python \"if statements\" and \"while loops\"\n",
    "\n",
    @@ -1330,7 +2256,9 @@
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": true
    "collapsed": true,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "source": []
    @@ -1339,14 +2267,19 @@
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": true
    "collapsed": true,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "source": []
    },
    {
    "cell_type": "markdown",
    "metadata": {},
    "metadata": {
    "deletable": true,
    "editable": true
    },
    "source": [
    "## List, set, and dict comprehensions"
    ]
    @@ -1355,7 +2288,9 @@
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": true
    "collapsed": true,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "source": []
    @@ -1364,14 +2299,19 @@
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": true
    "collapsed": true,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "source": []
    },
    {
    "cell_type": "markdown",
    "metadata": {},
    "metadata": {
    "deletable": true,
    "editable": true
    },
    "source": [
    "## Creating objects from arguments or other objects\n",
    "\n",
    @@ -1394,7 +2334,9 @@
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": true
    "collapsed": true,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "source": []
    @@ -1403,14 +2345,19 @@
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": true
    "collapsed": true,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "source": []
    },
    {
    "cell_type": "markdown",
    "metadata": {},
    "metadata": {
    "deletable": true,
    "editable": true
    },
    "source": [
    "## Importing modules"
    ]
    @@ -1419,7 +2366,9 @@
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": true
    "collapsed": true,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "source": []
    @@ -1428,14 +2377,19 @@
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": true
    "collapsed": true,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "source": []
    },
    {
    "cell_type": "markdown",
    "metadata": {},
    "metadata": {
    "deletable": true,
    "editable": true
    },
    "source": [
    "## Exceptions"
    ]
    @@ -1444,7 +2398,9 @@
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": true
    "collapsed": true,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "source": []
    @@ -1453,23 +2409,30 @@
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": true
    "collapsed": true,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "source": []
    },
    {
    "cell_type": "markdown",
    "metadata": {},
    "metadata": {
    "deletable": true,
    "editable": true
    },
    "source": [
    "## Classes: Creating your own objects"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "execution_count": 71,
    "metadata": {
    "collapsed": true
    "collapsed": true,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "source": [
    @@ -1485,11 +2448,26 @@
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "execution_count": 72,
    "metadata": {
    "collapsed": false
    "collapsed": false,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "outputs": [
    {
    "name": "stdout",
    "output_type": "stream",
    "text": [
    "<class '__main__.Thing'>\n",
    "<class 'type'>\n",
    "<class '__main__.DictThing'>\n",
    "<class 'type'>\n",
    "True\n",
    "True\n"
    ]
    }
    ],
    "source": [
    "print(Thing)\n",
    "print(type(Thing))\n",
    @@ -1501,11 +2479,24 @@
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "execution_count": 73,
    "metadata": {
    "collapsed": false
    "collapsed": false,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "outputs": [
    {
    "name": "stdout",
    "output_type": "stream",
    "text": [
    "<__main__.Thing object at 0x7f2170f3d240>\n",
    "<class '__main__.Thing'>\n",
    "{}\n",
    "<class '__main__.DictThing'>\n"
    ]
    }
    ],
    "source": [
    "# Create \"instances\" of our new classes\n",
    "t = Thing()\n",
    @@ -1518,11 +2509,21 @@
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "execution_count": 74,
    "metadata": {
    "collapsed": false
    "collapsed": false,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "outputs": [
    {
    "name": "stdout",
    "output_type": "stream",
    "text": [
    "{'name': 'Sally'}\n"
    ]
    }
    ],
    "source": [
    "# Interact with a DictThing instance just as you would a normal dictionary\n",
    "d['name'] = 'Sally'\n",
    @@ -1531,11 +2532,21 @@
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "execution_count": 75,
    "metadata": {
    "collapsed": false
    "collapsed": false,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "outputs": [
    {
    "name": "stdout",
    "output_type": "stream",
    "text": [
    "{'fav_color': 'green', 'name': 'Sally', 'fav_foods': ['pizza', 'sushi', 'pad thai', 'waffles'], 'age': 13}\n"
    ]
    }
    ],
    "source": [
    "d.update({\n",
    " 'age': 13,\n",
    @@ -1547,18 +2558,31 @@
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "execution_count": 76,
    "metadata": {
    "collapsed": false
    "collapsed": false,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "outputs": [
    {
    "name": "stdout",
    "output_type": "stream",
    "text": [
    "I am a \"DictThing\"\n"
    ]
    }
    ],
    "source": [
    "print(d.my_property)"
    ]
    },
    {
    "cell_type": "markdown",
    "metadata": {},
    "metadata": {
    "deletable": true,
    "editable": true
    },
    "source": [
    "## Defining functions and methods"
    ]
    @@ -1567,7 +2591,9 @@
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": true
    "collapsed": true,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "source": []
    @@ -1576,14 +2602,19 @@
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": true
    "collapsed": true,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "source": []
    },
    {
    "cell_type": "markdown",
    "metadata": {},
    "metadata": {
    "deletable": true,
    "editable": true
    },
    "source": [
    "## Creating an initializer method for your classes"
    ]
    @@ -1592,7 +2623,9 @@
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": true
    "collapsed": true,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "source": []
    @@ -1601,14 +2634,19 @@
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": true
    "collapsed": true,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "source": []
    },
    {
    "cell_type": "markdown",
    "metadata": {},
    "metadata": {
    "deletable": true,
    "editable": true
    },
    "source": [
    "## Other \"magic methods\""
    ]
    @@ -1617,7 +2655,9 @@
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": true
    "collapsed": true,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "source": []
    @@ -1626,14 +2666,19 @@
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": true
    "collapsed": true,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "source": []
    },
    {
    "cell_type": "markdown",
    "metadata": {},
    "metadata": {
    "deletable": true,
    "editable": true
    },
    "source": [
    "## Context managers and the \"with statement\""
    ]
    @@ -1642,7 +2687,9 @@
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": true
    "collapsed": true,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "source": []
    @@ -1651,7 +2698,9 @@
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": true
    "collapsed": true,
    "deletable": true,
    "editable": true
    },
    "outputs": [],
    "source": []
    @@ -1673,7 +2722,7 @@
    "name": "python",
    "nbconvert_exporter": "python",
    "pygments_lexer": "ipython3",
    "version": "3.5.1+"
    "version": "3.5.2"
    }
    },
    "nbformat": 4,
  10. @kenjyco kenjyco revised this gist Feb 6, 2017. 1 changed file with 13 additions and 5 deletions.
    18 changes: 13 additions & 5 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -1,13 +1,21 @@
    [python3]: https://www.python.org/about/
    [Python 3]: https://www.python.org/about/
    [tryjupyter]: https://try.jupyter.org
    [raw]: https://gist.github.com/kenjyco/69eeb503125035f21a9d/raw/learning-python3.ipynb
    [Jupyter Notebook]: https://jupyter.readthedocs.io/en/latest/running.html
    [learning-python3.ipynb]: https://gist.github.com/kenjyco/69eeb503125035f21a9d/raw/learning-python3.ipynb
    [learning-python3.pdf]: https://gist.github.com/kenjyco/69eeb503125035f21a9d/raw/learning-python3.pdf

    ## Learning Python 3

    This gist provides [learning-python3.ipynb][raw] (a notebook file) that can be loaded
    in [Jupyter Notebook][tryjupyter] to learn [Python 3][python3].
    This gist provides:

    Once you load the notebook file, you can edit any of the cells, add new cells,
    - the [learning-python3.ipynb][] notebook file, which can be viewed and edited in a
    [Jupyter Notebook][] server to learn [Python 3][]
    - the [learning-python3.pdf][] PDF file, which is a non-interactive version of
    the notebook file for offline viewing (with output displayed for all "code
    cells")

    Once you load the notebook file (to your local jupyter server, or
    [https://try.jupyter.org][tryjupyter]), you can edit any of the cells, add new cells,
    or delete cells. The **code cells** will let you type and execute Python code
    (since we are using the Python 3 **kernel**). The **markdown cells** will let
    you type notes with a simple syntax.
  11. @kenjyco kenjyco revised this gist Feb 6, 2017. 1 changed file with 0 additions and 0 deletions.
    Binary file modified learning-python3.pdf
    Binary file not shown.
  12. @kenjyco kenjyco revised this gist Feb 6, 2017. 3 changed files with 14 additions and 7 deletions.
    4 changes: 2 additions & 2 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -15,9 +15,9 @@ you type notes with a simple syntax.
    The online server does not remember any changes you make, so be sure to download
    your file again before closing.

    ## Load a notebook file to try.jupyter.org
    ## Load a notebook file to https://try.jupyter.org

    Visit [try.jupyter.org][tryjupyter] in your web browser, then click on the **`Upload`**
    Visit [https://try.jupyter.org][tryjupyter] in your web browser, then click on the **`Upload`**
    button near the upper right corner

    ![1](http://i.imgur.com/XDNKV6O.png)
    17 changes: 12 additions & 5 deletions learning-python3.ipynb
    Original file line number Diff line number Diff line change
    @@ -4,9 +4,13 @@
    "cell_type": "markdown",
    "metadata": {},
    "source": [
    "[raw]: https://gist.github.com/kenjyco/69eeb503125035f21a9d/raw/learning-python3.ipynb\n",
    "[learning-python3.ipynb]: https://gist.github.com/kenjyco/69eeb503125035f21a9d/raw/learning-python3.ipynb\n",
    "[learning-python3.pdf]: https://gist.github.com/kenjyco/69eeb503125035f21a9d/raw/learning-python3.pdf\n",
    "\n",
    "> Right-click -> \"save link as\" [this link][raw] to get most up-to-date version of this notebook file.\n",
    "Right-click -> \"save link as\" \n",
    "\n",
    "- [https://gist.github.com/kenjyco/69eeb503125035f21a9d/raw/learning-python3.ipynb][learning-python3.ipynb] to get most up-to-date version of this notebook file\n",
    "- [https://gist.github.com/kenjyco/69eeb503125035f21a9d/raw/learning-python3.pdf][learning-python3.pdf] to get PDF version of this notebook (with output displayed for all \"code cells\")\n",
    "\n",
    "## Quick note about Jupyter cells\n",
    "\n",
    @@ -27,11 +31,14 @@
    },
    {
    "cell_type": "markdown",
    "metadata": {},
    "metadata": {
    "deletable": true,
    "editable": true
    },
    "source": [
    "## Common Jupyter operations\n",
    "\n",
    "> Near the top of the page, Jupyter provides a row of menu options (`File`, `Edit`, `View`, `Insert`, ...) and a row of tool bar icons (disk, plus sign, scissors, 2 files, clipboard and file, up arrow, ...).\n",
    "Near the top of the https://try.jupyter.org page, Jupyter provides a row of menu options (`File`, `Edit`, `View`, `Insert`, ...) and a row of tool bar icons (disk, plus sign, scissors, 2 files, clipboard and file, up arrow, ...).\n",
    "\n",
    "#### Inserting and removing cells\n",
    "\n",
    @@ -46,7 +53,7 @@
    "#### Save your notebook file locally\n",
    "\n",
    "- Clear the output of all cells\n",
    "- Use \"File\" -> \"Download as\" -> \"IPython Notebook (.ipynb)\" to download a notebook file representing your try.jupyter.org session\n",
    "- Use \"File\" -> \"Download as\" -> \"IPython Notebook (.ipynb)\" to download a notebook file representing your https://try.jupyter.org session\n",
    "\n",
    "#### Load your notebook file in try.jupyter.org\n",
    "\n",
    Binary file added learning-python3.pdf
    Binary file not shown.
  13. @kenjyco kenjyco revised this gist Jan 24, 2017. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion learning-python3.ipynb
    Original file line number Diff line number Diff line change
    @@ -928,7 +928,7 @@
    "- **`.lower()`** to return an lowercase version of the string (all chars lowercase)\n",
    "- **`.count(substring)`** to return the number of occurences of the substring in the string\n",
    "- **`.startswith(substring)`** to determine if the string starts with the substring\n",
    "- **`.endswith(x)`** to determine if the string ends with the substring\n",
    "- **`.endswith(substring)`** to determine if the string ends with the substring\n",
    "- **`.replace(old, new)`** to return a copy of the string with occurences of the \"old\" replaced by \"new\""
    ]
    },
  14. @kenjyco kenjyco revised this gist Dec 31, 2016. 1 changed file with 3 additions and 3 deletions.
    6 changes: 3 additions & 3 deletions learning-python3.ipynb
    Original file line number Diff line number Diff line change
    @@ -924,8 +924,8 @@
    "## Some methods on string objects\n",
    "\n",
    "- **`.capitalize()`** to return a capitalized version of the string (only first char uppercase)\n",
    "- **`.upper()`** to return an uppercase verion of the string (all chars uppercase)\n",
    "- **`.lower()`** to return an lowercase verion of the string (all chars lowercase)\n",
    "- **`.upper()`** to return an uppercase version of the string (all chars uppercase)\n",
    "- **`.lower()`** to return an lowercase version of the string (all chars lowercase)\n",
    "- **`.count(substring)`** to return the number of occurences of the substring in the string\n",
    "- **`.startswith(substring)`** to determine if the string starts with the substring\n",
    "- **`.endswith(x)`** to determine if the string ends with the substring\n",
    @@ -1225,7 +1225,7 @@
    "\n",
    "When using **positional arguments**, you must provide them in the order that the function defined them (the function's **signature**).\n",
    "\n",
    "When using **keyword arguments**, you can provide the arguments you want, as long as you specify each argument's name.\n",
    "When using **keyword arguments**, you can provide the arguments you want, in any order you want, as long as you specify each argument's name.\n",
    "\n",
    "When using positional and keyword arguments, positional arguments must come first."
    ]
  15. @kenjyco kenjyco revised this gist Nov 16, 2016. 1 changed file with 325 additions and 27 deletions.
    352 changes: 325 additions & 27 deletions learning-python3.ipynb
    Original file line number Diff line number Diff line change
    @@ -467,13 +467,13 @@
    "\n",
    "- **`str`** (string: immutable; indexed by integers; items are stored in the order they were added)\n",
    "- **`list`** (list: mutable; indexed by integers; items are stored in the order they were added)\n",
    " - `[3, 5, 6, 'dog', 'cat', False]`\n",
    " - `[3, 5, 6, 3, 'dog', 'cat', False]`\n",
    "- **`tuple`** (tuple: immutable; indexed by integers; items are stored in the order they were added)\n",
    " - `(3, 5, 6, 'dog', 'cat', False)`\n",
    " - `(3, 5, 6, 3, 'dog', 'cat', False)`\n",
    "- **`set`** (set: mutable; not indexed at all; items are NOT stored in the order they were added; can only contain immutable objects; does NOT contain duplicate objects)\n",
    " - `{3, 5, 6, 'dog', 'cat', False}`\n",
    " - `{3, 5, 6, 3, 'dog', 'cat', False}`\n",
    "- **`dict`** (dictionary: mutable; key-value pairs are indexed by immutable keys; items are NOT stored in the order they were added)\n",
    " - `{'name': 'Jane', 'age': 23, 'knows_python': True}`\n",
    " - `{'name': 'Jane', 'age': 23, 'fav_foods': ['pizza', 'fruit', 'fish']}`\n",
    "\n",
    "When defining lists, tuples, or sets, use commas (,) to separate the individual items. When defining dicts, use a colon (:) to separate keys from values and commas (,) to separate the key-value pairs.\n",
    "\n",
    @@ -602,9 +602,9 @@
    "\n",
    "For strings, lists, tuples, and dicts, we can use **subscript notation** (square brackets) to access data at an index.\n",
    "\n",
    "- strings, lists, and tuples are indexed by integers, **starting at 0**\n",
    "- strings, lists, and tuples are indexed by integers, **starting at 0** for first item\n",
    " - these sequence types also support accesing a range of items, known as **slicing**\n",
    " - negative indexing \n",
    " - use **negative indexing** to start at the back of the sequence\n",
    "- dicts are indexed by their keys\n",
    "\n",
    "> Note: sets are not indexed, so we cannot use subscript notation to access data elements."
    @@ -700,21 +700,19 @@
    "source": [
    "## Python built-in functions and callables\n",
    "\n",
    "A function is a Python object that you can \"call\" to **perform an action**, by placing parentheses to the right of the function name. Some functions allow you to pass **arguments** inside the parentheses (separating multiple arguments with a comma). Internal to the function, these arguments are treated like variables.\n",
    "\n",
    "A Python object is a **function** if it is **callable**. You can check this by using the built-in function `callable()`, and passing in the object as an argument.\n",
    "A **function** is a Python object that you can \"call\" to **perform an action** or compute and **return another object**. You call a function by placing parentheses to the right of the function name. Some functions allow you to pass **arguments** inside the parentheses (separating multiple arguments with a comma). Internal to the function, these arguments are treated like variables.\n",
    "\n",
    "Python has several useful built-in functions to help you work with different objects and/or your environment. Here is a small sample of them:\n",
    "\n",
    "- `type()`\n",
    "- `len()`\n",
    "- `callable()`\n",
    "- `sorted()`\n",
    "- `sum()`\n",
    "- `min()`\n",
    "- `max()`\n",
    "- `abs()`\n",
    "- `repr()`\n",
    "- **`type(obj)`** to determine the type of an object\n",
    "- **`len(container)`** to determine how many items are in a container\n",
    "- **`callable(obj)`** to determine if an object is callable\n",
    "- **`sorted(container)`** to return a new list from a container, with the items sorted\n",
    "- **`sum(container)`** to compute the sum of a container of numbers\n",
    "- **`min(container)`** to determine the smallest item in a container\n",
    "- **`max(container)`** to determine the largest item in a container\n",
    "- **`abs(number)`** to determine the absolute value of a number\n",
    "- **`repr(obj)`** to return a string representation of an object\n",
    "\n",
    "> Complete list of built-in functions: https://docs.python.org/3/library/functions.html\n",
    "\n",
    @@ -790,7 +788,20 @@
    "outputs": [],
    "source": [
    "# Use the sorted() function to return a new list from a container, with the items sorted\n",
    "sorted([10, 1, 3, 7, 5, 2, -3])"
    "sorted([10, 1, 3.6, 7, 5, 2, -3])"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Use the sorted() function to return a new list from a container, with the items sorted\n",
    "# - notice that capitalized strings come first\n",
    "sorted(['dogs', 'cats', 'zebras', 'Chicago', 'California', 'ants', 'mice'])"
    ]
    },
    {
    @@ -802,7 +813,31 @@
    "outputs": [],
    "source": [
    "# Use the sum() function to compute the sum of a container of numbers\n",
    "sum([10, 1, 3, 7, 5, 2, -3])"
    "sum([10, 1, 3.6, 7, 5, 2, -3])"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Use the min() function to determine the smallest item in a container\n",
    "min([10, 1, 3.6, 7, 5, 2, -3])"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Use the min() function to determine the smallest item in a container\n",
    "min(['g', 'z', 'a', 'y'])"
    ]
    },
    {
    @@ -813,8 +848,8 @@
    },
    "outputs": [],
    "source": [
    "# Use the min() function to determine the item with the smallest value\n",
    "min([10, 1, 3, 7, 5, 2, -3])"
    "# Use the max() function to determine the largest item in a container\n",
    "max([10, 1, 3.6, 7, 5, 2, -3])"
    ]
    },
    {
    @@ -825,8 +860,8 @@
    },
    "outputs": [],
    "source": [
    "# Use the max() function to determine the item with the largest value\n",
    "max([10, 1, 3, 7, 5, 2, -3])"
    "# Use the max() function to determine the largest item in a container\n",
    "max('gibberish')"
    ]
    },
    {
    @@ -877,7 +912,207 @@
    "\n",
    "When an attribute of an object is not a callable, that attribute is called a **property**. It is just a piece of data about the object, that is itself another object.\n",
    "\n",
    "The built-in `dir()` function can be used to return a list of an object's attributes."
    "The built-in `dir()` function can be used to return a list of an object's attributes.\n",
    "\n",
    "<hr>"
    ]
    },
    {
    "cell_type": "markdown",
    "metadata": {},
    "source": [
    "## Some methods on string objects\n",
    "\n",
    "- **`.capitalize()`** to return a capitalized version of the string (only first char uppercase)\n",
    "- **`.upper()`** to return an uppercase verion of the string (all chars uppercase)\n",
    "- **`.lower()`** to return an lowercase verion of the string (all chars lowercase)\n",
    "- **`.count(substring)`** to return the number of occurences of the substring in the string\n",
    "- **`.startswith(substring)`** to determine if the string starts with the substring\n",
    "- **`.endswith(x)`** to determine if the string ends with the substring\n",
    "- **`.replace(old, new)`** to return a copy of the string with occurences of the \"old\" replaced by \"new\""
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Assign a string to a variable\n",
    "a_string = 'tHis is a sTriNg'"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Return a capitalized version of the string\n",
    "a_string.capitalize()"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Return an uppercase version of the string\n",
    "a_string.upper()"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Return a lowercase version of the string\n",
    "a_string.lower()"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Notice that the methods called have not actually modified the string\n",
    "a_string"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Count number of occurences of a substring in the string\n",
    "a_string.count('i')"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Count number of occurences of a substring in the string after a certain position\n",
    "a_string.count('i', 7)"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Count number of occurences of a substring in the string\n",
    "a_string.count('is')"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Does the string start with 'this'?\n",
    "a_string.startswith('this')"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Does the lowercase string start with 'this'?\n",
    "a_string.lower().startswith('this')"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Does the string end with 'Ng'?\n",
    "a_string.endswith('Ng')"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Return a version of the string with a substring replaced with something else\n",
    "a_string.replace('is', 'XYZ')"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Return a version of the string with a substring replaced with something else\n",
    "a_string.replace('i', '!')"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Return a version of the string with the first 2 occurences a substring replaced with something else\n",
    "a_string.replace('i', '!', 2)"
    ]
    },
    {
    "cell_type": "markdown",
    "metadata": {
    "collapsed": true
    },
    "source": [
    "## Some methods on list objects\n",
    "\n",
    "- **`.append(item)`** to add a single item to the list\n",
    "- **`.extend([item1, item2, ...])`** to add multiple items to the list\n",
    "- **`.remove(item)`** to remove a single item from the list\n",
    "- **`.pop()`** to remove and return the item at the end of the list\n",
    "- **`.pop(index)`** to remove and return an item at an index"
    ]
    },
    {
    @@ -898,6 +1133,25 @@
    "outputs": [],
    "source": []
    },
    {
    "cell_type": "markdown",
    "metadata": {},
    "source": [
    "## Some methods on set objects\n",
    "\n",
    "- **`.add(item)`** to add a single item to the set\n",
    "- **`.update([item1, item2, ...])`** to add multiple items to the set\n",
    "- **`.update(set2, set3, ...)`** to add items from all provided sets to the set\n",
    "- **`.remove(item)`** to remove a single item from the set\n",
    "- **`.pop()`** to remove and return a random item from the set\n",
    "- **`.difference(set2)`** to return items in the set that are not in another set\n",
    "- **`.intersection(set2)`** to return items in both sets\n",
    "- **`.union(set2)`** to return items that are in either set\n",
    "- **`.symmetric_difference(set2)`** to return items that are only in one set (not both)\n",
    "- **`.issuperset(set2)`** does the set contain everything in the other set?\n",
    "- **`.issubset(set2)`** is the set contained in the other set?"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    @@ -907,6 +1161,50 @@
    "outputs": [],
    "source": []
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": true
    },
    "outputs": [],
    "source": []
    },
    {
    "cell_type": "markdown",
    "metadata": {},
    "source": [
    "## Some methods on dict objects\n",
    "\n",
    "- **`.update([(key1, val1), (key2, val2), ...])`** to add multiple key-value pairs to the dict\n",
    "- **`.update(dict2)`** to add all keys and values from another dict to the dict\n",
    "- **`.pop(key)`** to remove key and return its value from the dict (error if key not found)\n",
    "- **`.pop(key, default_val)`** to remove key and return its value from the dict (or return default_val if key not found)\n",
    "- **`.get(key)`** to return the value at a specified key in the dict (or None if key not found)\n",
    "- **`.get(key, default_val)`** to return the value at a specified key in the dict (or default_val if key not found)\n",
    "- **`.keys()`** to return a list of keys in the dict\n",
    "- **`.values()`** to return a list of values in the dict\n",
    "- **`.items()`** to return a list of key-value pairs (tuples) in the dict"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": true
    },
    "outputs": [],
    "source": []
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": []
    },
    {
    "cell_type": "markdown",
    "metadata": {},
    @@ -954,7 +1252,7 @@
    "cell_type": "markdown",
    "metadata": {},
    "source": [
    "## Formatting strings"
    "## Formatting strings and using placeholders"
    ]
    },
    {
    @@ -1368,7 +1666,7 @@
    "name": "python",
    "nbconvert_exporter": "python",
    "pygments_lexer": "ipython3",
    "version": "3.5.2"
    "version": "3.5.1+"
    }
    },
    "nbformat": 4,
  16. @kenjyco kenjyco revised this gist Nov 9, 2016. 1 changed file with 367 additions and 927 deletions.
    1,294 changes: 367 additions & 927 deletions learning-python3.ipynb
    Original file line number Diff line number Diff line change
    @@ -22,6 +22,13 @@
    "\n",
    "Re-running will render the markdown text. To edit an existing markdown cell, double-click on it.\n",
    "\n",
    "<hr>"
    ]
    },
    {
    "cell_type": "markdown",
    "metadata": {},
    "source": [
    "## Common Jupyter operations\n",
    "\n",
    "> Near the top of the page, Jupyter provides a row of menu options (`File`, `Edit`, `View`, `Insert`, ...) and a row of tool bar icons (disk, plus sign, scissors, 2 files, clipboard and file, up arrow, ...).\n",
    @@ -70,129 +77,70 @@
    "cell_type": "markdown",
    "metadata": {},
    "source": [
    "## Python objects and variables\n",
    "## Python objects, basic types, and variables\n",
    "\n",
    "In Python, a **varible** is a name you specify in your code that maps to a particular **object**, object **instance**, or value. Every object in Python has a **type**.\n",
    "Everything in Python is an **object** and every object in Python has a **type**. Some of the basic types include:\n",
    "\n",
    "By defining variables, we can refer to things by names that make sense to us. Names for variables must start with a letter and can only contain other letters, underscores (`_`), or numbers (no spaces, dashes, or other characters).\n",
    "- **`int`** (integer; a whole number with no decimal place)\n",
    " - `10`\n",
    " - `-3`\n",
    "- **`float`** (float; a number that has a decimal place)\n",
    " - `7.41`\n",
    " - `-0.006`\n",
    "- **`str`** (string; a sequence of characters enclosed in single quotes, double quotes, or triple quotes)\n",
    " - `'this is a string using single quotes'`\n",
    " - `\"this is a string using double quotes\"`\n",
    " - `'''this is a triple quoted string using single quotes'''`\n",
    " - `\"\"\"this is a triple quoted string using double quotes\"\"\"`\n",
    "- **`bool`** (boolean; a binary value that is either true or false)\n",
    " - `True`\n",
    " - `False`\n",
    "- **`NoneType`** (a special type representing the absence of a value)\n",
    " - `None`\n",
    "\n",
    "> Here, we define some variables that we can use later in other cells.\n",
    ">\n",
    "> Remember to **`<Shift> + <Enter>`** on the cell defining the variables before trying to run other cells (or after changing a variable's definition). If you don't, a `NameError` exception will be raised saying that a variable \"is not defined\" when you try to access it, or the variable will have its old value."
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Some simple variables\n",
    "num_1 = 55\n",
    "num_2 = -23\n",
    "num_3 = 10.11\n",
    "string_1 = 'this is a string'\n",
    "string_2 = \"this is also a string\"\n",
    "string_3 = \"\"\"this is a string \n",
    "\n",
    "that contains some new-line characters\"\"\"\n",
    "string_4 = '''this is also a string \n",
    "\n",
    "that contains some new-line characters'''\n",
    "string_5 = 'My name is {}'\n",
    "string_6 = 'My name is {name} and I like {thing}'\n",
    "string_7 = 'Three things are {}, {}, and {}'\n",
    "list_1 = [8, 7.1, -3, num_1, num_2, num_3, -99]\n",
    "list_2 = ['dog', 'cat', 'mouse', 55, string_2]\n",
    "list_3 = [8, 7.1, -3, -3, -8, num_1, num_2, num_3, -99]\n",
    "tuple_1 = (8, 7.1, -3, num_1, num_2, num_3, -99)\n",
    "tuple_2 = ('dog', 'cat', 'mouse', 55, string_2)\n",
    "tuple_3 = (8, 7.1, -3, -3, -8, num_1, num_2, num_3, -99)\n",
    "set_1 = {8, 7.1, -3, num_1, num_2, num_3, -99}\n",
    "set_2 = {'dog', 'cat', 'mouse', 55, string_2}\n",
    "set_3 = {8, 7.1, -3, -3, -8, num_1, num_2, num_3, -99}\n",
    "set_4 = {8, 7.1, -3, -3, -8, 15, 3}\n",
    "\n",
    "# Some more complex variables\n",
    "dict_1 = {'a': 1, 'b': 22, 'c': list_1, 'd': string_3}\n",
    "dict_2 = {\n",
    " 'a': 539.11,\n",
    " 'b': tuple_2,\n",
    " 'c': [set_1, set_2],\n",
    " ('dog', 'cat'): 'a tuple can be a \"key\" in a dictionary'\n",
    "}\n",
    "list_of_dicts_1 = [\n",
    " {\n",
    " 'a': 1,\n",
    " 'b': 2,\n",
    " 'c': -3.99,\n",
    " },\n",
    " {\n",
    " 'a': 4,\n",
    " 'b': -5.1,\n",
    " 'c': 6,\n",
    " },\n",
    " {\n",
    " 'a': 14.3,\n",
    " 'b': 25,\n",
    " 'c': -36,\n",
    " }\n",
    "]\n",
    "list_of_tuples_1 = [\n",
    " ('cat', 'mouse'),\n",
    " ('cheese', 'stick'),\n",
    " ('shoe', 'sock'),\n",
    " ('bear', 'cactus'),\n",
    " ('ring', 'rose'),\n",
    "]\n",
    "list_of_tuples_2 = [\n",
    " (3.2, -2, 2.9, 3),\n",
    " (5, 2.5, 2.4, 8.6),\n",
    " (4.7, -24, 2.9, 3),\n",
    " (12, 22, -0.9, 7),\n",
    " (2.76, 8, 9, -1),\n",
    " (-2, 12, 2.4, 13),\n",
    " (6, 1.5, 2.9, -7.3),\n",
    " (2.1, -2.2, 2.9, 3.8),\n",
    "]\n",
    "my_vars_list = [\n",
    " num_1, num_2, num_3, string_1, string_2, string_3, string_4, string_5,\n",
    " string_6, string_7, list_1, list_2, list_3, tuple_1, tuple_2, tuple_3,\n",
    " set_1, set_2, set_3, set_4, dict_1, dict_2, list_of_dicts_1,\n",
    "]"
    "In Python, a **variable** is a name you specify in your code that maps to a particular **object**, object **instance**, or value.\n",
    "\n",
    "By defining variables, we can refer to things by names that make sense to us. Names for variables can only contain letters, underscores (`_`), or numbers (no spaces, dashes, or other characters). Variable names must start with a letter or underscore.\n",
    "\n",
    "<hr>"
    ]
    },
    {
    "cell_type": "markdown",
    "metadata": {},
    "source": [
    "## Python built-in functions\n",
    "## Basic operators\n",
    "\n",
    "A function is a Python object that you can \"call\" to **perform an action**, by placing parentheses to the right of the function name. Some functions allow you to pass **arguments** inside the parentheses (separating multiple arguments with a comma). Internal to the function, these arguments are treated like variables.\n",
    "In Python, there are different types of **operators** (special symbols) that operate on different values. Some of the basic operators include:\n",
    "\n",
    "A Python object is a **function** if it is **callable**. You can check this by using the built-in function `callable()`, and passing in the object as an argument.\n",
    "- arithmetic operators\n",
    " - **`+`** (addition)\n",
    " - **`-`** (subtraction)\n",
    " - **`*`** (multiplication)\n",
    " - **`/`** (division)\n",
    " - __`**`__ (exponent)\n",
    "- assignment operators\n",
    " - **`=`** (assign a value)\n",
    " - **`+=`** (add and re-assign; increment)\n",
    " - **`-=`** (subtract and re-assign; decrement)\n",
    " - **`*=`** (multiply and re-assign)\n",
    "- comparison operators (return either `True` or `False`)\n",
    " - **`==`** (equal to)\n",
    " - **`!=`** (not equal to)\n",
    " - **`<`** (less than)\n",
    " - **`<=`** (less than or equal to)\n",
    " - **`>`** (greater than)\n",
    " - **`>=`** (greater than or equal to)\n",
    "\n",
    "Python has several useful built-in functions to help you work with different objects and/or your environment.\n",
    "When multiple operators are used in a single expression, **operator precedence** determines which parts of the expression are evaluated in which order. Operators with higher precedence are evaluated first (like PEMDAS in math). Operators with the same precedence are evaluated from left to right.\n",
    "\n",
    "- `help()`\n",
    "- `print()`\n",
    "- `repr()`\n",
    "- `dir()`\n",
    "- `callable()`\n",
    "- `type()`\n",
    "- `len()`\n",
    "- `range()`\n",
    "- `sorted()`\n",
    "- `input()`\n",
    "- `locals()`\n",
    "- `sum()`\n",
    "- `min()`\n",
    "- `max()`\n",
    "- `abs()`\n",
    "- `()` parentheses, for grouping\n",
    "- `**` exponent\n",
    "- `*`, `/` multiplication and division\n",
    "- `+`, `-` addition and subtraction\n",
    "- `==`, `!=`, `<`, `<=`, `>`, `>=` comparisons\n",
    "\n",
    "> Complete list of built-in functions: https://docs.python.org/3/library/functions.html"
    "> See https://docs.python.org/3/reference/expressions.html#operator-precedence"
    ]
    },
    {
    @@ -203,10 +151,14 @@
    },
    "outputs": [],
    "source": [
    "# Using the `help` function to get information about the `print`, `repr`, and `dir` functions\n",
    "help(print)\n",
    "help(repr)\n",
    "help(dir)"
    "# Assigning some numbers to different variables\n",
    "num1 = 10\n",
    "num2 = -3\n",
    "num3 = 7.41\n",
    "num4 = -.6\n",
    "num5 = 7\n",
    "num6 = 3\n",
    "num7 = 11.11"
    ]
    },
    {
    @@ -217,14 +169,8 @@
    },
    "outputs": [],
    "source": [
    "# Print some string variables\n",
    "print(string_1)\n",
    "print(string_2)\n",
    "print(string_3)\n",
    "print(string_4)\n",
    "print(string_5)\n",
    "print(string_6)\n",
    "print(string_7)"
    "# Addition\n",
    "num1 + num2"
    ]
    },
    {
    @@ -235,39 +181,8 @@
    },
    "outputs": [],
    "source": [
    "# Print string representations of some string variables\n",
    "print(repr(string_1))\n",
    "print(repr(string_2))\n",
    "print(repr(string_3))\n",
    "print(repr(string_4))\n",
    "print(repr(string_5))\n",
    "print(repr(string_6))\n",
    "print(repr(string_7))"
    ]
    },
    {
    "cell_type": "markdown",
    "metadata": {},
    "source": [
    "## Python object attributes (methods and properties)\n",
    "\n",
    "Different types of objects in Python have different **attributes** that can be referred to by name (similar to a variable). To access an attribute of an object, use a dot (`.`) after the object, then specify the attribute (i.e. `obj.attribute`)\n",
    "\n",
    "When an attribute of an object is a callable, that attribute is called a **method**. It is the same as a function, only this function is bound to a particular object.\n",
    "\n",
    "When an attribute of an object is not a callable, that attribute is called a **property**. It is just a piece of data about the object, that is itself another object."
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Is the `format` attribute on the `string_5` object a callable?\n",
    "callable(string_5.format)"
    "# Subtraction\n",
    "num2 - num3"
    ]
    },
    {
    @@ -278,12 +193,8 @@
    },
    "outputs": [],
    "source": [
    "# Call the `format` method on a couple string variables\n",
    "# - in the first example we pass the string 'Jeff' as a POSITIONAL ARGUMENT to the format method on string_5\n",
    "# - in the other two examples, we pass KEYWORD ARGUMENTS to the format method on string_6\n",
    "print(string_5.format('Jeff'))\n",
    "print(string_6.format(name='Mary', thing='to dance'))\n",
    "print(string_6.format(name='Todd', thing='dogs'))"
    "# Multiplication\n",
    "num3 * num4"
    ]
    },
    {
    @@ -294,16 +205,8 @@
    },
    "outputs": [],
    "source": [
    "# Call some other methods that exist on string objects\n",
    "print(string_1.capitalize())\n",
    "print(string_1.upper())\n",
    "print(string_1.replace('i', '!')) # two positional arguments\n",
    "print(string_1.replace('is', 'XX'))\n",
    "print(len(string_1))\n",
    "print(string_1.count(' '))\n",
    "print(string_1.startswith('this'))\n",
    "print(string_1.startswith('This'))\n",
    "print(string_1.endswith('ing'))"
    "# Division\n",
    "num4 / num5"
    ]
    },
    {
    @@ -314,25 +217,8 @@
    },
    "outputs": [],
    "source": [
    "# Show help on the `replace` method of string_1\n",
    "help(string_1.replace)"
    ]
    },
    {
    "cell_type": "markdown",
    "metadata": {},
    "source": [
    "## Python lists, tuples, and sets\n",
    "\n",
    "These three are basic types of containers that can hold any other type of object (actually, sets can't contains **mutable objects** that can be changed). It is common for a collection of objects to be of the same type, but they don't have to be.\n",
    "\n",
    "For all three container types, **use a comma to separate the individual items** as you are defining them.\n",
    "\n",
    "When you define a list or a tuple with some items, those items are stored in the order that they were defined. \n",
    "\n",
    "A **set does NOT store items in the order they were defined**. A set **also does not contain duplicates** and can only contain imutable objects (objects that can't be changed). Set objects provide **set operations** (like `difference`, `intersection`, and `union`) as methods.\n",
    "\n",
    "When you have a defined list or set, you can add/remove items as you want to. A **tuple cannot be modified once it is defined**."
    "# Exponent\n",
    "num5 ** num6"
    ]
    },
    {
    @@ -343,11 +229,9 @@
    },
    "outputs": [],
    "source": [
    "# Print some collections of numbers\n",
    "# - remember, a set does not store items in the order they were defined in\n",
    "print(list_3)\n",
    "print(tuple_3)\n",
    "print(set_3)"
    "# Increment existing variable\n",
    "num7 += 4\n",
    "num7"
    ]
    },
    {
    @@ -358,11 +242,9 @@
    },
    "outputs": [],
    "source": [
    "# Print the lengths of each container (number of items)\n",
    "# - remember, a set does not store duplicate items\n",
    "print(len(list_3))\n",
    "print(len(tuple_3))\n",
    "print(len(set_3))"
    "# Decrement existing variable\n",
    "num6 -= 2\n",
    "num6"
    ]
    },
    {
    @@ -373,10 +255,9 @@
    },
    "outputs": [],
    "source": [
    "# Print the type of each container\n",
    "print(type(list_3))\n",
    "print(type(tuple_3))\n",
    "print(type(set_3))"
    "# Multiply & re-assign\n",
    "num3 *= 5\n",
    "num3"
    ]
    },
    {
    @@ -387,10 +268,9 @@
    },
    "outputs": [],
    "source": [
    "# Print the sum of numbers in each container\n",
    "print(sum(list_3))\n",
    "print(sum(tuple_3))\n",
    "print(sum(set_3))"
    "# Assign the value of an expression to a variable\n",
    "num8 = num1 + num2 * num3\n",
    "num8"
    ]
    },
    {
    @@ -401,10 +281,8 @@
    },
    "outputs": [],
    "source": [
    "# Print the largest number in each container\n",
    "print(max(list_3))\n",
    "print(max(tuple_3))\n",
    "print(max(set_3))"
    "# Are these two expressions equal to each other?\n",
    "num1 + num2 == num5"
    ]
    },
    {
    @@ -415,10 +293,8 @@
    },
    "outputs": [],
    "source": [
    "# Print the smallest number in each container\n",
    "print(min(list_3))\n",
    "print(min(tuple_3))\n",
    "print(min(set_3))"
    "# Are these two expressions not equal to each other?\n",
    "num3 != num4"
    ]
    },
    {
    @@ -429,10 +305,8 @@
    },
    "outputs": [],
    "source": [
    "# Print each container in sorted order\n",
    "print(sorted(list_3))\n",
    "print(sorted(tuple_3))\n",
    "print(sorted(set_3))"
    "# Is the first expression less than the second expression?\n",
    "num5 < num6"
    ]
    },
    {
    @@ -443,10 +317,8 @@
    },
    "outputs": [],
    "source": [
    "# Print each container in reverse sorted order\n",
    "print(sorted(list_3, reverse=True))\n",
    "print(sorted(tuple_3, reverse=True))\n",
    "print(sorted(set_3, reverse=True))"
    "# Is this expression True?\n",
    "5 > 3 > 1"
    ]
    },
    {
    @@ -457,28 +329,21 @@
    },
    "outputs": [],
    "source": [
    "# Add a single item to `list_3` and `set_3`\n",
    "# - remember, cannot modify a tuple\n",
    "# - also, notice that the method name is different between a list object and a set object\n",
    "list_3.append(50)\n",
    "set_3.add(50)\n",
    "print(list_3)\n",
    "print(set_3)"
    "# Is this expression True?\n",
    "5 > 3 < 4 == 3 + 1"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    "collapsed": true
    },
    "outputs": [],
    "source": [
    "# Remove an item from `list_3` and `set_3`\n",
    "list_3.remove(50)\n",
    "set_3.remove(50)\n",
    "print(list_3)\n",
    "print(set_3)"
    "# Assign some strings to different variables\n",
    "simple_string1 = 'an example'\n",
    "simple_string2 = \"oranges \""
    ]
    },
    {
    @@ -489,11 +354,8 @@
    },
    "outputs": [],
    "source": [
    "# Add multiple items to `list_3` and `set_3`\n",
    "list_3.extend([6, 4, 0])\n",
    "set_3.update([6, 4, 0])\n",
    "print(list_3)\n",
    "print(set_3)"
    "# Addition\n",
    "simple_string1 + ' of using the + operator'"
    ]
    },
    {
    @@ -504,7 +366,8 @@
    },
    "outputs": [],
    "source": [
    "[x for x in dir(set_3) if not x.startswith('_') and callable(getattr(set_3, x))]"
    "# Notice that the string was not modified\n",
    "simple_string1"
    ]
    },
    {
    @@ -515,8 +378,8 @@
    },
    "outputs": [],
    "source": [
    "print(sorted(set_3))\n",
    "print(sorted(set_4))"
    "# Multiplication\n",
    "simple_string2 * 4"
    ]
    },
    {
    @@ -527,11 +390,8 @@
    },
    "outputs": [],
    "source": [
    "# Items in 'set_3' but not 'set_4'\n",
    "print(sorted(set_3.difference(set_4)))\n",
    "\n",
    "# Items in 'set_4' but not 'set_3'\n",
    "print(sorted(set_4.difference(set_3)))"
    "# This string wasn't modified either\n",
    "simple_string2"
    ]
    },
    {
    @@ -542,11 +402,8 @@
    },
    "outputs": [],
    "source": [
    "# Items that are in both 'set_3' and 'set_4'\n",
    "print(sorted(set_3.intersection(set_4)))\n",
    "\n",
    "# Items that are in both 'set_4' and 'set_3'\n",
    "print(sorted(set_4.intersection(set_3)))"
    "# Are these two expressions equal to each other?\n",
    "simple_string1 == simple_string2"
    ]
    },
    {
    @@ -557,11 +414,8 @@
    },
    "outputs": [],
    "source": [
    "# Items that are in either 'set_3' or 'set_4'\n",
    "print(sorted(set_3.union(set_4)))\n",
    "\n",
    "# Items that are in either 'set_4' or 'set_3'\n",
    "print(sorted(set_4.union(set_3)))"
    "# Are these two expressions equal to each other?\n",
    "simple_string1 == 'an example'"
    ]
    },
    {
    @@ -572,9 +426,9 @@
    },
    "outputs": [],
    "source": [
    "# Items that are in exactly one of the sets (if it's in both, it's not in the results)\n",
    "print(sorted(set_3.symmetric_difference(set_4)))\n",
    "print(sorted(set_4.symmetric_difference(set_3)))"
    "# Add and re-assign\n",
    "simple_string1 += ' that re-assigned the original string'\n",
    "simple_string1"
    ]
    },
    {
    @@ -585,47 +439,60 @@
    },
    "outputs": [],
    "source": [
    "# Does 'set_4' contain everything in the given set?\n",
    "print(set_4.issuperset({-8, 8, -3, 3}))\n",
    "print(set_4.issuperset({-8, 8, -3, 0}))"
    "# Multiply and re-assign\n",
    "simple_string2 *= 3\n",
    "simple_string2"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    "collapsed": true
    },
    "outputs": [],
    "source": [
    "# Is 'set_4' contained in the given set?\n",
    "print(set_4.issubset({-9, -8, -5, -3, 0, 1, 3, 6, 7.1, 8, 9, 15, 15.5}))\n",
    "print(set_4.issubset({-9, -5, -3, 0, 1, 3, 6, 7.1, 8, 9, 15, 15.5}))"
    "# Note: Subtraction, division, and decrement operators do not apply to strings."
    ]
    },
    {
    "cell_type": "markdown",
    "metadata": {},
    "source": [
    "## Python dictionaries\n",
    "## Basic containers\n",
    "\n",
    "A dictionary is another type of container that can hold objects. Unlike the list, tuple, and set containers that just hold objects, you must specify a **key** for every object in the dictionary.\n",
    "> Note: **mutable** objects can be modified after creation and **immutable** objects cannot.\n",
    "\n",
    "- the key is usually a string, but it may also be a tuple or other **immutable type** (an object that cannot be modified after it's created) \n",
    "Containers are objects that can be used to group other objects together. The basic container types include:\n",
    "\n",
    "Like a set, a dictionary has no concept of order. Also like a set you may not have duplicate keys."
    "- **`str`** (string: immutable; indexed by integers; items are stored in the order they were added)\n",
    "- **`list`** (list: mutable; indexed by integers; items are stored in the order they were added)\n",
    " - `[3, 5, 6, 'dog', 'cat', False]`\n",
    "- **`tuple`** (tuple: immutable; indexed by integers; items are stored in the order they were added)\n",
    " - `(3, 5, 6, 'dog', 'cat', False)`\n",
    "- **`set`** (set: mutable; not indexed at all; items are NOT stored in the order they were added; can only contain immutable objects; does NOT contain duplicate objects)\n",
    " - `{3, 5, 6, 'dog', 'cat', False}`\n",
    "- **`dict`** (dictionary: mutable; key-value pairs are indexed by immutable keys; items are NOT stored in the order they were added)\n",
    " - `{'name': 'Jane', 'age': 23, 'knows_python': True}`\n",
    "\n",
    "When defining lists, tuples, or sets, use commas (,) to separate the individual items. When defining dicts, use a colon (:) to separate keys from values and commas (,) to separate the key-value pairs.\n",
    "\n",
    "Strings, lists, and tuples are all **sequence types** that can use the `+`, `*`, `+=`, and `*=` operators."
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    "collapsed": true
    },
    "outputs": [],
    "source": [
    "# Print `dict_1`\n",
    "print(dict_1)"
    "# Assign some containers to different variables\n",
    "list1 = [3, 5, 6, 3, 'dog', 'cat', False]\n",
    "tuple1 = (3, 5, 6, 3, 'dog', 'cat', False)\n",
    "set1 = {3, 5, 6, 3, 'dog', 'cat', False}\n",
    "dict1 = {'name': 'Jane', 'age': 23, 'fav_foods': ['pizza', 'fruit', 'fish']}"
    ]
    },
    {
    @@ -636,8 +503,8 @@
    },
    "outputs": [],
    "source": [
    "# Print the keys of `dict_1`\n",
    "print(dict_1.keys())"
    "# Items in the list object are stored in the order they were added\n",
    "list1"
    ]
    },
    {
    @@ -648,8 +515,8 @@
    },
    "outputs": [],
    "source": [
    "# Print the values of `dict_1`\n",
    "print(dict_1.values())"
    "# Items in the tuple object are stored in the order they were added\n",
    "tuple1"
    ]
    },
    {
    @@ -660,8 +527,9 @@
    },
    "outputs": [],
    "source": [
    "# Print the items (key/value pairs) of `dict_1`\n",
    "print(dict_1.items())"
    "# Items in the set object are not stored in the order they were added\n",
    "# Also, notice that the value 3 only appears once in this set object\n",
    "set1"
    ]
    },
    {
    @@ -672,15 +540,8 @@
    },
    "outputs": [],
    "source": [
    "# Create an empty dictionary, add a single key, then add multiple keys\n",
    "d = {}\n",
    "d['name'] = 'Sally'\n",
    "d.update({\n",
    " 'age': 13,\n",
    " 'fav_foods': ['pizza', 'sushi', 'pad thai', 'waffles'],\n",
    " 'fav_color': 'green',\n",
    " })\n",
    "print(d)"
    "# Items in the dict object are not stored in the order they were added\n",
    "dict1"
    ]
    },
    {
    @@ -691,14 +552,9 @@
    },
    "outputs": [],
    "source": [
    "# Update a dictionary\n",
    "d.update({\n",
    " 'age': 14,\n",
    " 'fav_foods': ['sushi', 'pad thai', 'waffles'],\n",
    " 'fav_color': 'emerald',\n",
    " 'num_computers': 2,\n",
    " })\n",
    "print(d)"
    "# Add and re-assign\n",
    "list1 += [5, 'grapes']\n",
    "list1"
    ]
    },
    {
    @@ -709,12 +565,9 @@
    },
    "outputs": [],
    "source": [
    "# Update a dictionary again\n",
    "d.update({\n",
    " 'fav_color': 'black',\n",
    " 'num_computers': 3,\n",
    " })\n",
    "print(d)"
    "# Add and re-assign\n",
    "tuple1 += (5, 'grapes')\n",
    "tuple1"
    ]
    },
    {
    @@ -725,9 +578,8 @@
    },
    "outputs": [],
    "source": [
    "# Remove a key from a dictionary\n",
    "del(d['fav_color'])\n",
    "print(d)"
    "# Multiply\n",
    "[1, 2, 3, 4] * 2"
    ]
    },
    {
    @@ -738,26 +590,24 @@
    },
    "outputs": [],
    "source": [
    "# Update dictionary again, by modifying the value of a specific key\n",
    "d['fav_foods'].append('crepes')\n",
    "print(d)"
    "# Multiply\n",
    "(1, 2, 3, 4) * 3"
    ]
    },
    {
    "cell_type": "markdown",
    "metadata": {},
    "source": [
    "## Accessing data in Python containers\n",
    "## Accessing data in containers\n",
    "\n",
    "Since containers are meant to hold many different objects, we need a way to select the items we are interested in from our containers.\n",
    "For strings, lists, tuples, and dicts, we can use **subscript notation** (square brackets) to access data at an index.\n",
    "\n",
    "For items in lists, tuples, and dictionaries, use the **subscript operator** (square bracket notation) to access them.\n",
    "- strings, lists, and tuples are indexed by integers, **starting at 0**\n",
    " - these sequence types also support accesing a range of items, known as **slicing**\n",
    " - negative indexing \n",
    "- dicts are indexed by their keys\n",
    "\n",
    "- lists and tuples use a **numerical index**\n",
    " - indexing starts at 0\n",
    " - negative index can be used to select an item closer to the end of the container\n",
    "- dictionaries use a **key** index (which is typically a string or a tuple)\n",
    "- sets do not support indexing, so you cannot use the subscript operator"
    "> Note: sets are not indexed, so we cannot use subscript notation to access data elements."
    ]
    },
    {
    @@ -768,8 +618,8 @@
    },
    "outputs": [],
    "source": [
    "print(list_3)\n",
    "print(tuple_3)"
    "# Access the first item in a sequence\n",
    "list1[0]"
    ]
    },
    {
    @@ -780,9 +630,8 @@
    },
    "outputs": [],
    "source": [
    "# Access FIRST item of a list or tuple (remember, sets have no concept of order)\n",
    "print(list_3[0])\n",
    "print(tuple_3[0])"
    "# Access the last item in a sequence\n",
    "tuple1[-1]"
    ]
    },
    {
    @@ -793,9 +642,8 @@
    },
    "outputs": [],
    "source": [
    "# Access second item of a list or tuple\n",
    "print(list_3[1])\n",
    "print(tuple_3[1])"
    "# Access a range of items in a sequence\n",
    "simple_string1[3:8]"
    ]
    },
    {
    @@ -806,9 +654,8 @@
    },
    "outputs": [],
    "source": [
    "# Access LAST item of a list or tuple\n",
    "print(list_3[-1])\n",
    "print(tuple_3[-1])"
    "# Access a range of items in a sequence\n",
    "tuple1[:-3]"
    ]
    },
    {
    @@ -819,9 +666,8 @@
    },
    "outputs": [],
    "source": [
    "# Access a range of items from a list or tuple using \"slicing\"\n",
    "print(list_3[2:-2])\n",
    "print(tuple_3[2:-2])"
    "# Access a range of items in a sequence\n",
    "list1[4:]"
    ]
    },
    {
    @@ -832,9 +678,8 @@
    },
    "outputs": [],
    "source": [
    "# Access a different range of items from a list or tuple using \"slicing\"\n",
    "print(list_3[:3])\n",
    "print(tuple_3[:3])"
    "# Access an item in a dictionary\n",
    "dict1['name']"
    ]
    },
    {
    @@ -845,7 +690,35 @@
    },
    "outputs": [],
    "source": [
    "print(dict_1)"
    "# Access an element of a sequence in a dictionary\n",
    "dict1['fav_foods'][2]"
    ]
    },
    {
    "cell_type": "markdown",
    "metadata": {},
    "source": [
    "## Python built-in functions and callables\n",
    "\n",
    "A function is a Python object that you can \"call\" to **perform an action**, by placing parentheses to the right of the function name. Some functions allow you to pass **arguments** inside the parentheses (separating multiple arguments with a comma). Internal to the function, these arguments are treated like variables.\n",
    "\n",
    "A Python object is a **function** if it is **callable**. You can check this by using the built-in function `callable()`, and passing in the object as an argument.\n",
    "\n",
    "Python has several useful built-in functions to help you work with different objects and/or your environment. Here is a small sample of them:\n",
    "\n",
    "- `type()`\n",
    "- `len()`\n",
    "- `callable()`\n",
    "- `sorted()`\n",
    "- `sum()`\n",
    "- `min()`\n",
    "- `max()`\n",
    "- `abs()`\n",
    "- `repr()`\n",
    "\n",
    "> Complete list of built-in functions: https://docs.python.org/3/library/functions.html\n",
    "\n",
    "There are also different ways of defining your own functions and callable objects that we will explore later."
    ]
    },
    {
    @@ -856,9 +729,8 @@
    },
    "outputs": [],
    "source": [
    "# Access item with key 'c' in `dict_1` \n",
    "# - cannot select \"slices\" of a dictionary since the keys are not ordered\n",
    "print(dict_1['c'])"
    "# Use the type() function to determine the type of an object\n",
    "type(simple_string1)"
    ]
    },
    {
    @@ -869,23 +741,8 @@
    },
    "outputs": [],
    "source": [
    "# Access the first item of the list at key 'c' in `dict_1`\n",
    "print(dict_1['c'][0])"
    ]
    },
    {
    "cell_type": "markdown",
    "metadata": {},
    "source": [
    "## Popping items from lists, sets, and dictionaries\n",
    "\n",
    "Each of these objects has a `pop` method that will remove an item from itself and return the item's value.\n",
    "\n",
    "For a list, calling `pop` with no arguments will remove the last item and return it. If you pass an index to `pop`, the item at that position is removed and returned.\n",
    "\n",
    "For a set, calling `pop` with no arguments will remove an arbitrary item and return it. You cannot pass arguments to `pop` on a set object.\n",
    "\n",
    "For a dict, calling `pop` with an argument will remove the item at that key and return it. You cannot call `pop` with no arguments on a dict object."
    "# Use the len() function to determine how many items are in a container\n",
    "len(dict1)"
    ]
    },
    {
    @@ -896,15 +753,8 @@
    },
    "outputs": [],
    "source": [
    "print(list_1)\n",
    "\n",
    "# Pop last item from 'list_1'\n",
    "print(list_1.pop())\n",
    "print(list_1)\n",
    "\n",
    "# Pop item at index position 3 from 'list_1' \n",
    "print(list_1.pop(3))\n",
    "print(list_1)"
    "# Use the len() function to determine how many items are in a container\n",
    "len(simple_string2)"
    ]
    },
    {
    @@ -915,10 +765,8 @@
    },
    "outputs": [],
    "source": [
    "# Remove arbitrary item from 'set_1'\n",
    "print(sorted(set_1))\n",
    "print(set_1.pop())\n",
    "print(sorted(set_1))"
    "# Use the callable() function to determine if an object is callable\n",
    "callable(len)"
    ]
    },
    {
    @@ -929,35 +777,8 @@
    },
    "outputs": [],
    "source": [
    "# Remove item at key 'c' in 'dict_1'\n",
    "print(dict_1)\n",
    "print(dict_1.pop('c'))\n",
    "print(dict_1)"
    ]
    },
    {
    "cell_type": "markdown",
    "metadata": {},
    "source": [
    "## Arguments and keyword arguments to Python callables\n",
    "\n",
    "You can call a function/method in a number of different ways:\n",
    "\n",
    "- `func()`: Call `func` with no arguments\n",
    "- `func(arg)`: Call `func` with one positional argument\n",
    "- `func(arg1, arg2)`: Call `func` with two positional arguments\n",
    "- `func(arg1, arg2, ..., argn)`: Call `func` with many positional arguments\n",
    "- `func(kwarg=value)`: Call `func` with one keyword argument \n",
    "- `func(kwarg1=value1, kwarg2=value2)`: Call `func` with two keyword arguments\n",
    "- `func(kwarg1=value1, kwarg2=value2, ..., kwargn=valuen)`: Call `func` with many keyword arguments\n",
    "- `func(arg1, arg2, kwarg1=value1, kwarg2=value2)`: Call `func` with positonal arguments and keyword arguments\n",
    "- `obj.method()`: Same for `func`.. and every other `func` example\n",
    "\n",
    "When using **positional arguments**, you must provide them in the order that the function defined them (the function's **signature**).\n",
    "\n",
    "When using **keyword arguments**, you can provide the arguments you want, as long as you specify each argument's name.\n",
    "\n",
    "When using positional and keyword arguments, positional arguments must come first."
    "# Use the callable() function to determine if an object is callable\n",
    "callable(dict1)"
    ]
    },
    {
    @@ -968,8 +789,8 @@
    },
    "outputs": [],
    "source": [
    "# Function call with no arguments\n",
    "dict_1.keys()"
    "# Use the sorted() function to return a new list from a container, with the items sorted\n",
    "sorted([10, 1, 3, 7, 5, 2, -3])"
    ]
    },
    {
    @@ -980,8 +801,8 @@
    },
    "outputs": [],
    "source": [
    "# Function call with one positional argument\n",
    "string_1.endswith('ing')"
    "# Use the sum() function to compute the sum of a container of numbers\n",
    "sum([10, 1, 3, 7, 5, 2, -3])"
    ]
    },
    {
    @@ -992,8 +813,8 @@
    },
    "outputs": [],
    "source": [
    "# Function call with two positional arguments\n",
    "string_1.replace('is', 'XX')"
    "# Use the min() function to determine the item with the smallest value\n",
    "min([10, 1, 3, 7, 5, 2, -3])"
    ]
    },
    {
    @@ -1004,8 +825,8 @@
    },
    "outputs": [],
    "source": [
    "# Function call with two keyword arguments\n",
    "string_6.format(name='Mary', thing='to dance')"
    "# Use the max() function to determine the item with the largest value\n",
    "max([10, 1, 3, 7, 5, 2, -3])"
    ]
    },
    {
    @@ -1016,19 +837,8 @@
    },
    "outputs": [],
    "source": [
    "# Function call with a positional argument and a keyword argument\n",
    "sorted(list_3, reverse=True)"
    ]
    },
    {
    "cell_type": "markdown",
    "metadata": {},
    "source": [
    "## Simple on-the-fly callable objects (lambda function)\n",
    "\n",
    "A lambda function can be used wherever a function object is required.\n",
    "\n",
    "A lambda function can only contain a single expression."
    "# Use the abs() function to determine the absolute value of a number\n",
    "abs(10)"
    ]
    },
    {
    @@ -1039,9 +849,8 @@
    },
    "outputs": [],
    "source": [
    "# Use a lambda function to specify the \"sort key\" function argument to `sorted`\n",
    "# - this will cause the `sorted` function to sort `list_of_dict_1` by the value at key `b`\n",
    "sorted(list_of_dicts_1, key=lambda x: x['b'])"
    "# Use the abs() function to determine the absolute value of a number\n",
    "abs(-12)"
    ]
    },
    {
    @@ -1052,468 +861,272 @@
    },
    "outputs": [],
    "source": [
    "# Define three callable objects\n",
    "say_hi = lambda: print('Hi!')\n",
    "make_it_upper = lambda x: x.upper()\n",
    "do_number_stuff = lambda x, y: 2 * x + 3 * y\n",
    "\n",
    "print(callable(say_hi))\n",
    "print(type(say_hi))\n",
    "say_hi()\n",
    "print(make_it_upper('this is a string'))\n",
    "\n",
    "# Remember, the order of positional arguments matters (but not keyword arguments)\n",
    "print(do_number_stuff(1, 2))\n",
    "print(do_number_stuff(2, 1))\n",
    "print(do_number_stuff(x=0.15, y=20))\n",
    "print(do_number_stuff(y=20, x=0.15))"
    "# Use the repr() function to return a string representation of an object\n",
    "repr(set1)"
    ]
    },
    {
    "cell_type": "markdown",
    "metadata": {},
    "source": [
    "## Tuple assignment\n",
    "## Python object attributes (methods and properties)\n",
    "\n",
    "Different types of objects in Python have different **attributes** that can be referred to by name (similar to a variable). To access an attribute of an object, use a dot (`.`) after the object, then specify the attribute (i.e. `obj.attribute`)\n",
    "\n",
    "When an attribute of an object is a callable, that attribute is called a **method**. It is the same as a function, only this function is bound to a particular object.\n",
    "\n",
    "If you have a tuple of items, you can assign each one to a separate variable using tuple assignment (in a single statement).\n",
    "When an attribute of an object is not a callable, that attribute is called a **property**. It is just a piece of data about the object, that is itself another object.\n",
    "\n",
    "You can also use tuples to swap the values of multiple variables."
    "The built-in `dir()` function can be used to return a list of an object's attributes."
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    "collapsed": true
    },
    "outputs": [],
    "source": [
    "a, b, c = (2, 4, 6)\n",
    "print(a)\n",
    "print(b)\n",
    "print(c)"
    ]
    "source": []
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    "collapsed": true
    },
    "outputs": [],
    "source": [
    "# Swap the values of multiple variables\n",
    "# - `a` becomes what `b` originally was\n",
    "# - `c` becomes what `a` originally was\n",
    "# - `b` becomes what `c` originally was\n",
    "a, c, b = b, a, c\n",
    "print(a)\n",
    "print(b)\n",
    "print(c)"
    ]
    "source": []
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": true
    },
    "outputs": [],
    "source": []
    },
    {
    "cell_type": "markdown",
    "metadata": {},
    "source": [
    "## Python \"for\" loops\n",
    "## Positional arguments and keyword arguments to callables\n",
    "\n",
    "It is easy to **iterate** over a collection of items using a **for loop**. The lists, tuples, sets, and dictionaries we defined are all built-in **containers** that you can iterate over. (Actually, the strings are containers of characters that we can iterate over as well).\n",
    "You can call a function/method in a number of different ways:\n",
    "\n",
    "The for loop will go through the specified container, one item at a time, and provide a temporary variable for the current item. You can use this temporary variable like a normal variable."
    "- `func()`: Call `func` with no arguments\n",
    "- `func(arg)`: Call `func` with one positional argument\n",
    "- `func(arg1, arg2)`: Call `func` with two positional arguments\n",
    "- `func(arg1, arg2, ..., argn)`: Call `func` with many positional arguments\n",
    "- `func(kwarg=value)`: Call `func` with one keyword argument \n",
    "- `func(kwarg1=value1, kwarg2=value2)`: Call `func` with two keyword arguments\n",
    "- `func(kwarg1=value1, kwarg2=value2, ..., kwargn=valuen)`: Call `func` with many keyword arguments\n",
    "- `func(arg1, arg2, kwarg1=value1, kwarg2=value2)`: Call `func` with positonal arguments and keyword arguments\n",
    "- `obj.method()`: Same for `func`.. and every other `func` example\n",
    "\n",
    "When using **positional arguments**, you must provide them in the order that the function defined them (the function's **signature**).\n",
    "\n",
    "When using **keyword arguments**, you can provide the arguments you want, as long as you specify each argument's name.\n",
    "\n",
    "When using positional and keyword arguments, positional arguments must come first."
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    "collapsed": true
    },
    "outputs": [],
    "source": [
    "# Iterate through `list_1` and display each item on a new line\n",
    "for item in list_1:\n",
    " print(item)"
    ]
    "source": []
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    "collapsed": true
    },
    "outputs": [],
    "source": [
    "# Iterate through `list_1` and display the absolute value of each item on a new line\n",
    "for item in list_1:\n",
    " print(abs(item))"
    ]
    "source": []
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "cell_type": "markdown",
    "metadata": {},
    "source": [
    "# Iterate through `list_1` and print a string for each item\n",
    "for num in list_1:\n",
    " print('Absolute value of {} is {}'.format(num, abs(num)))"
    "## Formatting strings"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    "collapsed": true
    },
    "outputs": [],
    "source": [
    "# Iterate through `string_1` and print each character on a new line\n",
    "for character in string_1:\n",
    " print(character)"
    ]
    "source": []
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    "collapsed": true
    },
    "outputs": [],
    "source": [
    "# Iterate through `dict_1` and display each key on a new line\n",
    "for key in dict_1:\n",
    " print(key)"
    ]
    "source": []
    },
    {
    "cell_type": "markdown",
    "metadata": {},
    "source": [
    "## Using for loops with tuple assignment\n",
    "## Python \"for loops\"\n",
    "\n",
    "You may have noticed that when you call the `.items()` method on a dictionary object, you receive a list of 2-item tuples.\n",
    "It is easy to **iterate** over a collection of items using a **for loop**. The strings, lists, tuples, sets, and dictionaries we defined are all **iterable** containers.\n",
    "\n",
    "It is possible to iterate over this data and use tuple assignment to store the intermediate values of each key/value pair."
    "The for loop will go through the specified container, one item at a time, and provide a temporary variable for the current item. You can use this temporary variable like a normal variable."
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    "collapsed": true
    },
    "outputs": [],
    "source": [
    "# Iterate through `dict_1.items()` and display each key and value in a formatted string\n",
    "for key, value in dict_1.items():\n",
    " print('{} -> {}'.format(key, value))"
    ]
    "source": []
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    "collapsed": true
    },
    "outputs": [],
    "source": [
    "# Iterate through `dict_1.items()` and display each item (no tuple assignment)\n",
    "for item in dict_1.items():\n",
    " print(item)"
    ]
    "source": []
    },
    {
    "cell_type": "markdown",
    "metadata": {},
    "source": [
    "## Python booleans and \"conditional expressions\"\n",
    "## Python \"if statements\" and \"while loops\"\n",
    "\n",
    "Conditional expressions can be used with these two **conditional statements**.\n",
    "\n",
    "The **if statement** allows you to test a condition and perform some actions if the condition evaluates to `True`. You can also provide `elif` and/or `else` clauses to an if statement to take alternative actions if the condition evaluates to `False`.\n",
    "\n",
    "A boolean object has a value of `True` or `False`. A conditional expression is one that evaluates to a boolean value. This allows you to ask questions about your data so you can make a decision to \"do something\" or \"do something else\" next."
    "The **while loop** will keep looping until its conditional expression evaluates to `False`.\n",
    "\n",
    "> Note: It is possible to \"loop forever\" when using a while loop with a conditional expression that never evaluates to `False`.\n",
    ">\n",
    "> Note: Since the **for loop** will iterate over a container of items until there are no more, there is no need to specify a \"stop looping\" condition."
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    "collapsed": true
    },
    "outputs": [],
    "source": [
    "# Does the key 'a' exist in the dictionary `dict_1`?\n",
    "'a' in dict_1"
    ]
    "source": []
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    "collapsed": true
    },
    "outputs": [],
    "source": [
    "# Are there more than 5 keys in `dict_1`?\n",
    "len(dict_1.keys()) > 5"
    ]
    "source": []
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Does `string_1` start with 'this'?\n",
    "string_1.startswith('this')"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Does `string_1` start with 'This'?\n",
    "string_1.startswith('This')"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Is the smallest item in `list_1` less than 0?\n",
    "min(list_1) < 0"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Is the string 'dogs' a sub-string of a longer string?\n",
    "'dogs' in 'there are some dogs and cats'"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Is 5 times 5 equal to 25?\n",
    "5 * 5 == 25"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "print(num_1, num_2, num_3)"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "cell_type": "markdown",
    "metadata": {},
    "source": [
    "# Is `num_1` larger than `num_2` and `num_3`?\n",
    "num_1 > num_2 and num_1 > num_3"
    "## List, set, and dict comprehensions"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    "collapsed": true
    },
    "outputs": [],
    "source": [
    "# Is `num_1` less than `num_2` OR is `num_1` greater than `num_3`?\n",
    "num_1 < num_2 or num_1 > num_3"
    ]
    "source": []
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    "collapsed": true
    },
    "outputs": [],
    "source": [
    "# Is `num_3` between `num_1` and `num_2`?\n",
    "num_1 > num_3 > num_2"
    ]
    "source": []
    },
    {
    "cell_type": "markdown",
    "metadata": {},
    "source": [
    "## Python \"if statements\" and \"while loops\"\n",
    "## Creating objects from arguments or other objects\n",
    "\n",
    "Conditional expressions can be used with these two **conditional statements**.\n",
    "The basic types and containers we have used so far all provide **type constructors**:\n",
    "\n",
    "The **if statement** allows you to test a condition and perform some actions if the condition evaluates to `True`.\n",
    "- `int()`\n",
    "- `float()`\n",
    "- `str()`\n",
    "- `list()`\n",
    "- `tuple()`\n",
    "- `set()`\n",
    "- `dict()`\n",
    "\n",
    "The **while loop** will keep looping until its conditional expression evaluates to `False`. The **for loop** will iterate over a container of items until there are no more (no need to specify a \"stop looping\" condition).\n",
    "Up to this point, we have been defining objects of these built-in types using some syntactic shortcuts, since they are so common.\n",
    "\n",
    "It is possible to \"loop forever\" when using a while loop with a conditional expression that never evaluates to `False` (i.e. `while True:`)."
    "Sometimes, you will have an object of one type that you need to convert to another type. Use the **type constructor** for the type of object you want to have, and pass in the object you currently have."
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "if num_1 > num_3 > num_2:\n",
    " print('num_3 is between num_1 and num_2')"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "if string_1.startswith('This'):\n",
    " print('string_1 starts with \"This\"')\n",
    "else:\n",
    " print('string_1 does not start with \"This\"')"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "if num_1 < 0:\n",
    " print('num_1 is less than 0')\n",
    "elif num_1 == 0:\n",
    " print('num_1 is equal to 0')\n",
    "else:\n",
    " print('num_1 is greater than 0')"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    "collapsed": true
    },
    "outputs": [],
    "source": [
    "thing = ''\n",
    "while not thing:\n",
    " thing = input('please type stuff and hit <ENTER>: ')"
    ]
    "source": []
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    "collapsed": true
    },
    "outputs": [],
    "source": [
    "thing"
    ]
    "source": []
    },
    {
    "cell_type": "markdown",
    "metadata": {},
    "source": [
    "## Creating objects from other objects\n",
    "\n",
    "Sometimes, you will have an object of one type that you need to make into another type. Use the **type constructor** for the type of object you want to have, and pass in the object you currently have."
    "## Importing modules"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "print(int)\n",
    "print(float)\n",
    "print(str)\n",
    "print(list)\n",
    "print(tuple)\n",
    "print(set)\n",
    "print(dict)"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "print(type(int))\n",
    "print(type(float))\n",
    "print(type(str))\n",
    "print(type(list))\n",
    "print(type(tuple))\n",
    "print(type(set))\n",
    "print(type(dict))"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    "collapsed": true
    },
    "outputs": [],
    "source": [
    "print(float(123))\n",
    "print(int(1.23))\n",
    "print(list(string_1))\n",
    "print(dict(list_of_tuples_1))"
    ]
    "source": []
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    "collapsed": true
    },
    "outputs": [],
    "source": [
    "# Sometimes, the type of object you have may have a method to return an object of the type you want\n",
    "print(', '.join(['jump', 'run', 'play']))"
    ]
    "source": []
    },
    {
    "cell_type": "markdown",
    @@ -1526,146 +1139,25 @@
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Create an int from string 'stuff'\n",
    "int('stuff')"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# If creating an int raises a `ValueError` print a message instead\n",
    "try:\n",
    " int('stuff')\n",
    "except ValueError:\n",
    " print('You cannot make an int out of that')"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Catch the exception, do something, then re-raise the exception\n",
    "try:\n",
    " int('stuff')\n",
    "except ValueError:\n",
    " print('You cannot make an int out of that')\n",
    " raise"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Can't divide by zero\n",
    "1/0"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Can't reference a dictionary key that doesn't exist\n",
    "dict_1['not-a-real-key'] + 10"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Use the `get` method on the dictionary to fetch my key\n",
    "# - will return a `NoneType`, instead of raising a `KeyError`\n",
    "# - but a `NoneType` can't be added to an `int`, so a `TypeError` gets raised\n",
    "dict_1.get('not-a-real-key') + 10"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    "collapsed": true
    },
    "outputs": [],
    "source": [
    "# Specify a default value to return if the key doesn't exist in the dictionary\n",
    "dict_1.get('not-a-real-key', 0) + 10"
    ]
    "source": []
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    "collapsed": true
    },
    "outputs": [],
    "source": [
    "# There is no such variable defined called `not_a_dict`, so a `NameError` is raised\n",
    "not_a_dict['not-a-key']"
    ]
    "source": []
    },
    {
    "cell_type": "markdown",
    "metadata": {},
    "source": [
    "## Creating your own objects\n",
    "\n",
    "> TODO: Super brief intro to classes"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "print(object)\n",
    "print(type(object))\n",
    "print(dict)\n",
    "print(type(dict))"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# `dict` is a sub-class of `object`\n",
    "# `set` is a sub-class of `object`\n",
    "# `int` is a sub-class of `object`\n",
    "# `set` is not a sub-class of `dict`\n",
    "print(issubclass(dict, object))\n",
    "print(issubclass(set, object))\n",
    "print(issubclass(int, object))\n",
    "print(issubclass(set, dict))"
    "## Classes: Creating your own objects"
    ]
    },
    {
    @@ -1681,7 +1173,7 @@
    " my_property = 'I am a \"Thing\"'\n",
    "\n",
    "\n",
    "# Define a new class called `DictThing` that is derived from the `dict` type (which is a class)\n",
    "# Define a new class called `DictThing` that is derived from the `dict` type\n",
    "class DictThing(dict):\n",
    " my_property = 'I am a \"DictThing\"'"
    ]
    @@ -1763,144 +1255,92 @@
    "cell_type": "markdown",
    "metadata": {},
    "source": [
    "## TODO\n",
    "\n",
    "Add the following sections before \"putting things together\"\n",
    "\n",
    "- importing modules\n",
    "- defining functions\n",
    "- `__name__`\n",
    "- list comprehension\n",
    "- conditional assignment\n",
    "- unpacking argument lists and keywoard argument dicts\n",
    "- getattr"
    ]
    },
    {
    "cell_type": "markdown",
    "metadata": {
    "collapsed": true
    },
    "source": [
    "<hr>\n",
    "# Putting things together (complex examples)\n",
    "<hr>"
    "## Defining functions and methods"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    "collapsed": true
    },
    "outputs": [],
    "source": [
    "import sys\n",
    "\n",
    "def module_objects(module=__name__):\n",
    " \"\"\"Return a list of dicts with info about objects in the given module (or module name)\n",
    " \n",
    " - attr_name: name of the object\n",
    " - module_name: name of the module containing the object\n",
    " - type: type of the object\n",
    " - is_callable: True if the object is a function\n",
    " - simple_value: None, or value of the object if it is a simple type (str, int, float)\n",
    " \"\"\"\n",
    " if type(module) == str:\n",
    " module = sys.modules.get(module)\n",
    " \n",
    " data = []\n",
    " for attr_name in sorted(dir(module)):\n",
    " obj = getattr(module, attr_name)\n",
    " obj_info = {\n",
    " 'attr_name': attr_name,\n",
    " 'module_name': module.__name__,\n",
    " 'type': type(obj),\n",
    " 'is_callable': True if callable(obj) else False,\n",
    " 'simple_value': obj if type(obj) in (str, int, float) else None,\n",
    " }\n",
    " data.append(obj_info)\n",
    " \n",
    " return data"
    ]
    "source": []
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    "collapsed": true
    },
    "outputs": [],
    "source": []
    },
    {
    "cell_type": "markdown",
    "metadata": {},
    "source": [
    "sorted(sys.modules.keys())"
    "## Creating an initializer method for your classes"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    "collapsed": true
    },
    "outputs": [],
    "source": [
    "module_objects('random')"
    ]
    "source": []
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    "collapsed": true
    },
    "outputs": [],
    "source": []
    },
    {
    "cell_type": "markdown",
    "metadata": {},
    "source": [
    "module_objects('concurrent.futures.thread')"
    "## Other \"magic methods\""
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    "collapsed": true
    },
    "outputs": [],
    "source": [
    "[\n",
    " '{attr_name} from {module_name} is a {type}'.format(**thing)\n",
    " for thing in module_objects()\n",
    " if thing['is_callable']\n",
    "]"
    ]
    "source": []
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    "collapsed": true
    },
    "outputs": [],
    "source": []
    },
    {
    "cell_type": "markdown",
    "metadata": {},
    "source": [
    "[\n",
    " '{attr_name} from {module_name} is a {type}'.format(**thing)\n",
    " for thing in module_objects(sys)\n",
    " if thing['is_callable']\n",
    "]"
    "## Context managers and the \"with statement\""
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    "collapsed": true
    },
    "outputs": [],
    "source": [
    "[\n",
    " '{attr_name} from {module_name} is a {type}'.format(**thing)\n",
    " for thing in module_objects('re')\n",
    " if thing['is_callable']\n",
    "]"
    ]
    "source": []
    },
    {
    "cell_type": "code",
    @@ -1928,7 +1368,7 @@
    "name": "python",
    "nbconvert_exporter": "python",
    "pygments_lexer": "ipython3",
    "version": "3.4.3"
    "version": "3.5.2"
    }
    },
    "nbformat": 4,
  17. @kenjyco kenjyco revised this gist Apr 4, 2016. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -1,6 +1,6 @@
    [python3]: https://www.python.org/about/
    [tryjupyter]: https://try.jupyter.org
    [raw]: https://gist.github.com/kenjyco/69eeb503125035f21a9d/raw/36e260079fecbc1365e759f7c57ad09a7a398c8c/learning-python3.ipynb
    [raw]: https://gist.github.com/kenjyco/69eeb503125035f21a9d/raw/learning-python3.ipynb

    ## Learning Python 3

    @@ -37,4 +37,4 @@ Click on your uploaded notebook file

    Interact with your notebook!

    ![5](http://i.imgur.com/dyeI55W.png)
    ![5](http://i.imgur.com/dyeI55W.png)
  18. @kenjyco kenjyco revised this gist Apr 4, 2016. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion learning-python3.ipynb
    Original file line number Diff line number Diff line change
    @@ -4,7 +4,7 @@
    "cell_type": "markdown",
    "metadata": {},
    "source": [
    "[raw]: https://gist.github.com/kenjyco/69eeb503125035f21a9d/raw/36e260079fecbc1365e759f7c57ad09a7a398c8c/learning-python3.ipynb\n",
    "[raw]: https://gist.github.com/kenjyco/69eeb503125035f21a9d/raw/learning-python3.ipynb\n",
    "\n",
    "> Right-click -> \"save link as\" [this link][raw] to get most up-to-date version of this notebook file.\n",
    "\n",
  19. @kenjyco kenjyco revised this gist Mar 31, 2016. 1 changed file with 176 additions and 2 deletions.
    178 changes: 176 additions & 2 deletions learning-python3.ipynb
    Original file line number Diff line number Diff line change
    @@ -4,6 +4,10 @@
    "cell_type": "markdown",
    "metadata": {},
    "source": [
    "[raw]: https://gist.github.com/kenjyco/69eeb503125035f21a9d/raw/36e260079fecbc1365e759f7c57ad09a7a398c8c/learning-python3.ipynb\n",
    "\n",
    "> Right-click -> \"save link as\" [this link][raw] to get most up-to-date version of this notebook file.\n",
    "\n",
    "## Quick note about Jupyter cells\n",
    "\n",
    "When you are editing a cell in Jupyter notebook, you need to re-run the cell by pressing **`<Shift> + <Enter>`**. This will allow changes you made to be available to other cells.\n",
    @@ -72,7 +76,7 @@
    "\n",
    "By defining variables, we can refer to things by names that make sense to us. Names for variables must start with a letter and can only contain other letters, underscores (`_`), or numbers (no spaces, dashes, or other characters).\n",
    "\n",
    "> Here, we define some variables that we can use in other cells.\n",
    "> Here, we define some variables that we can use later in other cells.\n",
    ">\n",
    "> Remember to **`<Shift> + <Enter>`** on the cell defining the variables before trying to run other cells (or after changing a variable's definition). If you don't, a `NameError` exception will be raised saying that a variable \"is not defined\" when you try to access it, or the variable will have its old value."
    ]
    @@ -109,6 +113,7 @@
    "set_1 = {8, 7.1, -3, num_1, num_2, num_3, -99}\n",
    "set_2 = {'dog', 'cat', 'mouse', 55, string_2}\n",
    "set_3 = {8, 7.1, -3, -3, -8, num_1, num_2, num_3, -99}\n",
    "set_4 = {8, 7.1, -3, -3, -8, 15, 3}\n",
    "\n",
    "# Some more complex variables\n",
    "dict_1 = {'a': 1, 'b': 22, 'c': list_1, 'd': string_3}\n",
    @@ -155,7 +160,7 @@
    "my_vars_list = [\n",
    " num_1, num_2, num_3, string_1, string_2, string_3, string_4, string_5,\n",
    " string_6, string_7, list_1, list_2, list_3, tuple_1, tuple_2, tuple_3,\n",
    " set_1, set_2, set_3, dict_1, dict_2, list_of_dicts_1,\n",
    " set_1, set_2, set_3, set_4, dict_1, dict_2, list_of_dicts_1,\n",
    "]"
    ]
    },
    @@ -491,6 +496,113 @@
    "print(set_3)"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "[x for x in dir(set_3) if not x.startswith('_') and callable(getattr(set_3, x))]"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "print(sorted(set_3))\n",
    "print(sorted(set_4))"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Items in 'set_3' but not 'set_4'\n",
    "print(sorted(set_3.difference(set_4)))\n",
    "\n",
    "# Items in 'set_4' but not 'set_3'\n",
    "print(sorted(set_4.difference(set_3)))"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Items that are in both 'set_3' and 'set_4'\n",
    "print(sorted(set_3.intersection(set_4)))\n",
    "\n",
    "# Items that are in both 'set_4' and 'set_3'\n",
    "print(sorted(set_4.intersection(set_3)))"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Items that are in either 'set_3' or 'set_4'\n",
    "print(sorted(set_3.union(set_4)))\n",
    "\n",
    "# Items that are in either 'set_4' or 'set_3'\n",
    "print(sorted(set_4.union(set_3)))"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Items that are in exactly one of the sets (if it's in both, it's not in the results)\n",
    "print(sorted(set_3.symmetric_difference(set_4)))\n",
    "print(sorted(set_4.symmetric_difference(set_3)))"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Does 'set_4' contain everything in the given set?\n",
    "print(set_4.issuperset({-8, 8, -3, 3}))\n",
    "print(set_4.issuperset({-8, 8, -3, 0}))"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Is 'set_4' contained in the given set?\n",
    "print(set_4.issubset({-9, -8, -5, -3, 0, 1, 3, 6, 7.1, 8, 9, 15, 15.5}))\n",
    "print(set_4.issubset({-9, -5, -3, 0, 1, 3, 6, 7.1, 8, 9, 15, 15.5}))"
    ]
    },
    {
    "cell_type": "markdown",
    "metadata": {},
    @@ -761,6 +873,68 @@
    "print(dict_1['c'][0])"
    ]
    },
    {
    "cell_type": "markdown",
    "metadata": {},
    "source": [
    "## Popping items from lists, sets, and dictionaries\n",
    "\n",
    "Each of these objects has a `pop` method that will remove an item from itself and return the item's value.\n",
    "\n",
    "For a list, calling `pop` with no arguments will remove the last item and return it. If you pass an index to `pop`, the item at that position is removed and returned.\n",
    "\n",
    "For a set, calling `pop` with no arguments will remove an arbitrary item and return it. You cannot pass arguments to `pop` on a set object.\n",
    "\n",
    "For a dict, calling `pop` with an argument will remove the item at that key and return it. You cannot call `pop` with no arguments on a dict object."
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "print(list_1)\n",
    "\n",
    "# Pop last item from 'list_1'\n",
    "print(list_1.pop())\n",
    "print(list_1)\n",
    "\n",
    "# Pop item at index position 3 from 'list_1' \n",
    "print(list_1.pop(3))\n",
    "print(list_1)"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Remove arbitrary item from 'set_1'\n",
    "print(sorted(set_1))\n",
    "print(set_1.pop())\n",
    "print(sorted(set_1))"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Remove item at key 'c' in 'dict_1'\n",
    "print(dict_1)\n",
    "print(dict_1.pop('c'))\n",
    "print(dict_1)"
    ]
    },
    {
    "cell_type": "markdown",
    "metadata": {},
  20. @kenjyco kenjyco revised this gist Mar 28, 2016. 1 changed file with 2 additions and 1 deletion.
    3 changes: 2 additions & 1 deletion README.md
    Original file line number Diff line number Diff line change
    @@ -1,9 +1,10 @@
    [python3]: https://www.python.org/about/
    [tryjupyter]: https://try.jupyter.org
    [raw]: https://gist.github.com/kenjyco/69eeb503125035f21a9d/raw/36e260079fecbc1365e759f7c57ad09a7a398c8c/learning-python3.ipynb

    ## Learning Python 3

    This gist provides `learning-python3.ipynb` (a notebook file) that can be loaded
    This gist provides [learning-python3.ipynb][raw] (a notebook file) that can be loaded
    in [Jupyter Notebook][tryjupyter] to learn [Python 3][python3].

    Once you load the notebook file, you can edit any of the cells, add new cells,
  21. @kenjyco kenjyco created this gist Mar 28, 2016.
    39 changes: 39 additions & 0 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,39 @@
    [python3]: https://www.python.org/about/
    [tryjupyter]: https://try.jupyter.org

    ## Learning Python 3

    This gist provides `learning-python3.ipynb` (a notebook file) that can be loaded
    in [Jupyter Notebook][tryjupyter] to learn [Python 3][python3].

    Once you load the notebook file, you can edit any of the cells, add new cells,
    or delete cells. The **code cells** will let you type and execute Python code
    (since we are using the Python 3 **kernel**). The **markdown cells** will let
    you type notes with a simple syntax.

    The online server does not remember any changes you make, so be sure to download
    your file again before closing.

    ## Load a notebook file to try.jupyter.org

    Visit [try.jupyter.org][tryjupyter] in your web browser, then click on the **`Upload`**
    button near the upper right corner

    ![1](http://i.imgur.com/XDNKV6O.png)

    Navigate your filesystem to find your `*.ipynb` file, select it with your
    mouse, and click **`Open`**

    ![2](http://i.imgur.com/UQB0ZzE.png)

    Click the new **`Upload`** button that appears next to your file name

    ![3](http://i.imgur.com/m6fvGSL.png)

    Click on your uploaded notebook file

    ![4](http://i.imgur.com/XPry4JK.png)

    Interact with your notebook!

    ![5](http://i.imgur.com/dyeI55W.png)
    1,762 changes: 1,762 additions & 0 deletions learning-python3.ipynb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,1762 @@
    {
    "cells": [
    {
    "cell_type": "markdown",
    "metadata": {},
    "source": [
    "## Quick note about Jupyter cells\n",
    "\n",
    "When you are editing a cell in Jupyter notebook, you need to re-run the cell by pressing **`<Shift> + <Enter>`**. This will allow changes you made to be available to other cells.\n",
    "\n",
    "Use **`<Enter>`** to make new lines inside a cell you are editing.\n",
    "\n",
    "#### Code cells\n",
    "\n",
    "Re-running will execute any statements you have written. To edit an existing code cell, click on it.\n",
    "\n",
    "#### Markdown cells\n",
    "\n",
    "Re-running will render the markdown text. To edit an existing markdown cell, double-click on it.\n",
    "\n",
    "## Common Jupyter operations\n",
    "\n",
    "> Near the top of the page, Jupyter provides a row of menu options (`File`, `Edit`, `View`, `Insert`, ...) and a row of tool bar icons (disk, plus sign, scissors, 2 files, clipboard and file, up arrow, ...).\n",
    "\n",
    "#### Inserting and removing cells\n",
    "\n",
    "- Use the \"plus sign\" icon to insert a cell below the currently selected cell\n",
    "- Use \"Insert\" -> \"Insert Cell Above\" from the menu to insert above\n",
    "\n",
    "#### Clear the output of all cells\n",
    "\n",
    "- Use \"Kernel\" -> \"Restart\" from the menu to restart the kernel\n",
    " - click on \"clear all outputs & restart\" to have all the output cleared\n",
    "\n",
    "#### Save your notebook file locally\n",
    "\n",
    "- Clear the output of all cells\n",
    "- Use \"File\" -> \"Download as\" -> \"IPython Notebook (.ipynb)\" to download a notebook file representing your try.jupyter.org session\n",
    "\n",
    "#### Load your notebook file in try.jupyter.org\n",
    "\n",
    "1. Visit https://try.jupyter.org\n",
    "2. Click the \"Upload\" button near the upper right corner\n",
    "3. Navigate your filesystem to find your `*.ipynb` file and click \"open\"\n",
    "4. Click the new \"upload\" button that appears next to your file name\n",
    "5. Click on your uploaded notebook file\n",
    "\n",
    "<hr>"
    ]
    },
    {
    "cell_type": "markdown",
    "metadata": {},
    "source": [
    "## References\n",
    "\n",
    "- https://try.jupyter.org\n",
    "- https://docs.python.org/3/tutorial/index.html\n",
    "- https://docs.python.org/3/tutorial/introduction.html\n",
    "- https://daringfireball.net/projects/markdown/syntax\n",
    "\n",
    "<hr>"
    ]
    },
    {
    "cell_type": "markdown",
    "metadata": {},
    "source": [
    "## Python objects and variables\n",
    "\n",
    "In Python, a **varible** is a name you specify in your code that maps to a particular **object**, object **instance**, or value. Every object in Python has a **type**.\n",
    "\n",
    "By defining variables, we can refer to things by names that make sense to us. Names for variables must start with a letter and can only contain other letters, underscores (`_`), or numbers (no spaces, dashes, or other characters).\n",
    "\n",
    "> Here, we define some variables that we can use in other cells.\n",
    ">\n",
    "> Remember to **`<Shift> + <Enter>`** on the cell defining the variables before trying to run other cells (or after changing a variable's definition). If you don't, a `NameError` exception will be raised saying that a variable \"is not defined\" when you try to access it, or the variable will have its old value."
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Some simple variables\n",
    "num_1 = 55\n",
    "num_2 = -23\n",
    "num_3 = 10.11\n",
    "string_1 = 'this is a string'\n",
    "string_2 = \"this is also a string\"\n",
    "string_3 = \"\"\"this is a string \n",
    "\n",
    "that contains some new-line characters\"\"\"\n",
    "string_4 = '''this is also a string \n",
    "\n",
    "that contains some new-line characters'''\n",
    "string_5 = 'My name is {}'\n",
    "string_6 = 'My name is {name} and I like {thing}'\n",
    "string_7 = 'Three things are {}, {}, and {}'\n",
    "list_1 = [8, 7.1, -3, num_1, num_2, num_3, -99]\n",
    "list_2 = ['dog', 'cat', 'mouse', 55, string_2]\n",
    "list_3 = [8, 7.1, -3, -3, -8, num_1, num_2, num_3, -99]\n",
    "tuple_1 = (8, 7.1, -3, num_1, num_2, num_3, -99)\n",
    "tuple_2 = ('dog', 'cat', 'mouse', 55, string_2)\n",
    "tuple_3 = (8, 7.1, -3, -3, -8, num_1, num_2, num_3, -99)\n",
    "set_1 = {8, 7.1, -3, num_1, num_2, num_3, -99}\n",
    "set_2 = {'dog', 'cat', 'mouse', 55, string_2}\n",
    "set_3 = {8, 7.1, -3, -3, -8, num_1, num_2, num_3, -99}\n",
    "\n",
    "# Some more complex variables\n",
    "dict_1 = {'a': 1, 'b': 22, 'c': list_1, 'd': string_3}\n",
    "dict_2 = {\n",
    " 'a': 539.11,\n",
    " 'b': tuple_2,\n",
    " 'c': [set_1, set_2],\n",
    " ('dog', 'cat'): 'a tuple can be a \"key\" in a dictionary'\n",
    "}\n",
    "list_of_dicts_1 = [\n",
    " {\n",
    " 'a': 1,\n",
    " 'b': 2,\n",
    " 'c': -3.99,\n",
    " },\n",
    " {\n",
    " 'a': 4,\n",
    " 'b': -5.1,\n",
    " 'c': 6,\n",
    " },\n",
    " {\n",
    " 'a': 14.3,\n",
    " 'b': 25,\n",
    " 'c': -36,\n",
    " }\n",
    "]\n",
    "list_of_tuples_1 = [\n",
    " ('cat', 'mouse'),\n",
    " ('cheese', 'stick'),\n",
    " ('shoe', 'sock'),\n",
    " ('bear', 'cactus'),\n",
    " ('ring', 'rose'),\n",
    "]\n",
    "list_of_tuples_2 = [\n",
    " (3.2, -2, 2.9, 3),\n",
    " (5, 2.5, 2.4, 8.6),\n",
    " (4.7, -24, 2.9, 3),\n",
    " (12, 22, -0.9, 7),\n",
    " (2.76, 8, 9, -1),\n",
    " (-2, 12, 2.4, 13),\n",
    " (6, 1.5, 2.9, -7.3),\n",
    " (2.1, -2.2, 2.9, 3.8),\n",
    "]\n",
    "my_vars_list = [\n",
    " num_1, num_2, num_3, string_1, string_2, string_3, string_4, string_5,\n",
    " string_6, string_7, list_1, list_2, list_3, tuple_1, tuple_2, tuple_3,\n",
    " set_1, set_2, set_3, dict_1, dict_2, list_of_dicts_1,\n",
    "]"
    ]
    },
    {
    "cell_type": "markdown",
    "metadata": {},
    "source": [
    "## Python built-in functions\n",
    "\n",
    "A function is a Python object that you can \"call\" to **perform an action**, by placing parentheses to the right of the function name. Some functions allow you to pass **arguments** inside the parentheses (separating multiple arguments with a comma). Internal to the function, these arguments are treated like variables.\n",
    "\n",
    "A Python object is a **function** if it is **callable**. You can check this by using the built-in function `callable()`, and passing in the object as an argument.\n",
    "\n",
    "Python has several useful built-in functions to help you work with different objects and/or your environment.\n",
    "\n",
    "- `help()`\n",
    "- `print()`\n",
    "- `repr()`\n",
    "- `dir()`\n",
    "- `callable()`\n",
    "- `type()`\n",
    "- `len()`\n",
    "- `range()`\n",
    "- `sorted()`\n",
    "- `input()`\n",
    "- `locals()`\n",
    "- `sum()`\n",
    "- `min()`\n",
    "- `max()`\n",
    "- `abs()`\n",
    "\n",
    "> Complete list of built-in functions: https://docs.python.org/3/library/functions.html"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Using the `help` function to get information about the `print`, `repr`, and `dir` functions\n",
    "help(print)\n",
    "help(repr)\n",
    "help(dir)"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Print some string variables\n",
    "print(string_1)\n",
    "print(string_2)\n",
    "print(string_3)\n",
    "print(string_4)\n",
    "print(string_5)\n",
    "print(string_6)\n",
    "print(string_7)"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Print string representations of some string variables\n",
    "print(repr(string_1))\n",
    "print(repr(string_2))\n",
    "print(repr(string_3))\n",
    "print(repr(string_4))\n",
    "print(repr(string_5))\n",
    "print(repr(string_6))\n",
    "print(repr(string_7))"
    ]
    },
    {
    "cell_type": "markdown",
    "metadata": {},
    "source": [
    "## Python object attributes (methods and properties)\n",
    "\n",
    "Different types of objects in Python have different **attributes** that can be referred to by name (similar to a variable). To access an attribute of an object, use a dot (`.`) after the object, then specify the attribute (i.e. `obj.attribute`)\n",
    "\n",
    "When an attribute of an object is a callable, that attribute is called a **method**. It is the same as a function, only this function is bound to a particular object.\n",
    "\n",
    "When an attribute of an object is not a callable, that attribute is called a **property**. It is just a piece of data about the object, that is itself another object."
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Is the `format` attribute on the `string_5` object a callable?\n",
    "callable(string_5.format)"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Call the `format` method on a couple string variables\n",
    "# - in the first example we pass the string 'Jeff' as a POSITIONAL ARGUMENT to the format method on string_5\n",
    "# - in the other two examples, we pass KEYWORD ARGUMENTS to the format method on string_6\n",
    "print(string_5.format('Jeff'))\n",
    "print(string_6.format(name='Mary', thing='to dance'))\n",
    "print(string_6.format(name='Todd', thing='dogs'))"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Call some other methods that exist on string objects\n",
    "print(string_1.capitalize())\n",
    "print(string_1.upper())\n",
    "print(string_1.replace('i', '!')) # two positional arguments\n",
    "print(string_1.replace('is', 'XX'))\n",
    "print(len(string_1))\n",
    "print(string_1.count(' '))\n",
    "print(string_1.startswith('this'))\n",
    "print(string_1.startswith('This'))\n",
    "print(string_1.endswith('ing'))"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Show help on the `replace` method of string_1\n",
    "help(string_1.replace)"
    ]
    },
    {
    "cell_type": "markdown",
    "metadata": {},
    "source": [
    "## Python lists, tuples, and sets\n",
    "\n",
    "These three are basic types of containers that can hold any other type of object (actually, sets can't contains **mutable objects** that can be changed). It is common for a collection of objects to be of the same type, but they don't have to be.\n",
    "\n",
    "For all three container types, **use a comma to separate the individual items** as you are defining them.\n",
    "\n",
    "When you define a list or a tuple with some items, those items are stored in the order that they were defined. \n",
    "\n",
    "A **set does NOT store items in the order they were defined**. A set **also does not contain duplicates** and can only contain imutable objects (objects that can't be changed). Set objects provide **set operations** (like `difference`, `intersection`, and `union`) as methods.\n",
    "\n",
    "When you have a defined list or set, you can add/remove items as you want to. A **tuple cannot be modified once it is defined**."
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Print some collections of numbers\n",
    "# - remember, a set does not store items in the order they were defined in\n",
    "print(list_3)\n",
    "print(tuple_3)\n",
    "print(set_3)"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Print the lengths of each container (number of items)\n",
    "# - remember, a set does not store duplicate items\n",
    "print(len(list_3))\n",
    "print(len(tuple_3))\n",
    "print(len(set_3))"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Print the type of each container\n",
    "print(type(list_3))\n",
    "print(type(tuple_3))\n",
    "print(type(set_3))"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Print the sum of numbers in each container\n",
    "print(sum(list_3))\n",
    "print(sum(tuple_3))\n",
    "print(sum(set_3))"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Print the largest number in each container\n",
    "print(max(list_3))\n",
    "print(max(tuple_3))\n",
    "print(max(set_3))"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Print the smallest number in each container\n",
    "print(min(list_3))\n",
    "print(min(tuple_3))\n",
    "print(min(set_3))"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Print each container in sorted order\n",
    "print(sorted(list_3))\n",
    "print(sorted(tuple_3))\n",
    "print(sorted(set_3))"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Print each container in reverse sorted order\n",
    "print(sorted(list_3, reverse=True))\n",
    "print(sorted(tuple_3, reverse=True))\n",
    "print(sorted(set_3, reverse=True))"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Add a single item to `list_3` and `set_3`\n",
    "# - remember, cannot modify a tuple\n",
    "# - also, notice that the method name is different between a list object and a set object\n",
    "list_3.append(50)\n",
    "set_3.add(50)\n",
    "print(list_3)\n",
    "print(set_3)"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Remove an item from `list_3` and `set_3`\n",
    "list_3.remove(50)\n",
    "set_3.remove(50)\n",
    "print(list_3)\n",
    "print(set_3)"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Add multiple items to `list_3` and `set_3`\n",
    "list_3.extend([6, 4, 0])\n",
    "set_3.update([6, 4, 0])\n",
    "print(list_3)\n",
    "print(set_3)"
    ]
    },
    {
    "cell_type": "markdown",
    "metadata": {},
    "source": [
    "## Python dictionaries\n",
    "\n",
    "A dictionary is another type of container that can hold objects. Unlike the list, tuple, and set containers that just hold objects, you must specify a **key** for every object in the dictionary.\n",
    "\n",
    "- the key is usually a string, but it may also be a tuple or other **immutable type** (an object that cannot be modified after it's created) \n",
    "\n",
    "Like a set, a dictionary has no concept of order. Also like a set you may not have duplicate keys."
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Print `dict_1`\n",
    "print(dict_1)"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Print the keys of `dict_1`\n",
    "print(dict_1.keys())"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Print the values of `dict_1`\n",
    "print(dict_1.values())"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Print the items (key/value pairs) of `dict_1`\n",
    "print(dict_1.items())"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Create an empty dictionary, add a single key, then add multiple keys\n",
    "d = {}\n",
    "d['name'] = 'Sally'\n",
    "d.update({\n",
    " 'age': 13,\n",
    " 'fav_foods': ['pizza', 'sushi', 'pad thai', 'waffles'],\n",
    " 'fav_color': 'green',\n",
    " })\n",
    "print(d)"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Update a dictionary\n",
    "d.update({\n",
    " 'age': 14,\n",
    " 'fav_foods': ['sushi', 'pad thai', 'waffles'],\n",
    " 'fav_color': 'emerald',\n",
    " 'num_computers': 2,\n",
    " })\n",
    "print(d)"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Update a dictionary again\n",
    "d.update({\n",
    " 'fav_color': 'black',\n",
    " 'num_computers': 3,\n",
    " })\n",
    "print(d)"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Remove a key from a dictionary\n",
    "del(d['fav_color'])\n",
    "print(d)"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Update dictionary again, by modifying the value of a specific key\n",
    "d['fav_foods'].append('crepes')\n",
    "print(d)"
    ]
    },
    {
    "cell_type": "markdown",
    "metadata": {},
    "source": [
    "## Accessing data in Python containers\n",
    "\n",
    "Since containers are meant to hold many different objects, we need a way to select the items we are interested in from our containers.\n",
    "\n",
    "For items in lists, tuples, and dictionaries, use the **subscript operator** (square bracket notation) to access them.\n",
    "\n",
    "- lists and tuples use a **numerical index**\n",
    " - indexing starts at 0\n",
    " - negative index can be used to select an item closer to the end of the container\n",
    "- dictionaries use a **key** index (which is typically a string or a tuple)\n",
    "- sets do not support indexing, so you cannot use the subscript operator"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "print(list_3)\n",
    "print(tuple_3)"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Access FIRST item of a list or tuple (remember, sets have no concept of order)\n",
    "print(list_3[0])\n",
    "print(tuple_3[0])"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Access second item of a list or tuple\n",
    "print(list_3[1])\n",
    "print(tuple_3[1])"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Access LAST item of a list or tuple\n",
    "print(list_3[-1])\n",
    "print(tuple_3[-1])"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Access a range of items from a list or tuple using \"slicing\"\n",
    "print(list_3[2:-2])\n",
    "print(tuple_3[2:-2])"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Access a different range of items from a list or tuple using \"slicing\"\n",
    "print(list_3[:3])\n",
    "print(tuple_3[:3])"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "print(dict_1)"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Access item with key 'c' in `dict_1` \n",
    "# - cannot select \"slices\" of a dictionary since the keys are not ordered\n",
    "print(dict_1['c'])"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Access the first item of the list at key 'c' in `dict_1`\n",
    "print(dict_1['c'][0])"
    ]
    },
    {
    "cell_type": "markdown",
    "metadata": {},
    "source": [
    "## Arguments and keyword arguments to Python callables\n",
    "\n",
    "You can call a function/method in a number of different ways:\n",
    "\n",
    "- `func()`: Call `func` with no arguments\n",
    "- `func(arg)`: Call `func` with one positional argument\n",
    "- `func(arg1, arg2)`: Call `func` with two positional arguments\n",
    "- `func(arg1, arg2, ..., argn)`: Call `func` with many positional arguments\n",
    "- `func(kwarg=value)`: Call `func` with one keyword argument \n",
    "- `func(kwarg1=value1, kwarg2=value2)`: Call `func` with two keyword arguments\n",
    "- `func(kwarg1=value1, kwarg2=value2, ..., kwargn=valuen)`: Call `func` with many keyword arguments\n",
    "- `func(arg1, arg2, kwarg1=value1, kwarg2=value2)`: Call `func` with positonal arguments and keyword arguments\n",
    "- `obj.method()`: Same for `func`.. and every other `func` example\n",
    "\n",
    "When using **positional arguments**, you must provide them in the order that the function defined them (the function's **signature**).\n",
    "\n",
    "When using **keyword arguments**, you can provide the arguments you want, as long as you specify each argument's name.\n",
    "\n",
    "When using positional and keyword arguments, positional arguments must come first."
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Function call with no arguments\n",
    "dict_1.keys()"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Function call with one positional argument\n",
    "string_1.endswith('ing')"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Function call with two positional arguments\n",
    "string_1.replace('is', 'XX')"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Function call with two keyword arguments\n",
    "string_6.format(name='Mary', thing='to dance')"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Function call with a positional argument and a keyword argument\n",
    "sorted(list_3, reverse=True)"
    ]
    },
    {
    "cell_type": "markdown",
    "metadata": {},
    "source": [
    "## Simple on-the-fly callable objects (lambda function)\n",
    "\n",
    "A lambda function can be used wherever a function object is required.\n",
    "\n",
    "A lambda function can only contain a single expression."
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Use a lambda function to specify the \"sort key\" function argument to `sorted`\n",
    "# - this will cause the `sorted` function to sort `list_of_dict_1` by the value at key `b`\n",
    "sorted(list_of_dicts_1, key=lambda x: x['b'])"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Define three callable objects\n",
    "say_hi = lambda: print('Hi!')\n",
    "make_it_upper = lambda x: x.upper()\n",
    "do_number_stuff = lambda x, y: 2 * x + 3 * y\n",
    "\n",
    "print(callable(say_hi))\n",
    "print(type(say_hi))\n",
    "say_hi()\n",
    "print(make_it_upper('this is a string'))\n",
    "\n",
    "# Remember, the order of positional arguments matters (but not keyword arguments)\n",
    "print(do_number_stuff(1, 2))\n",
    "print(do_number_stuff(2, 1))\n",
    "print(do_number_stuff(x=0.15, y=20))\n",
    "print(do_number_stuff(y=20, x=0.15))"
    ]
    },
    {
    "cell_type": "markdown",
    "metadata": {},
    "source": [
    "## Tuple assignment\n",
    "\n",
    "If you have a tuple of items, you can assign each one to a separate variable using tuple assignment (in a single statement).\n",
    "\n",
    "You can also use tuples to swap the values of multiple variables."
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "a, b, c = (2, 4, 6)\n",
    "print(a)\n",
    "print(b)\n",
    "print(c)"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Swap the values of multiple variables\n",
    "# - `a` becomes what `b` originally was\n",
    "# - `c` becomes what `a` originally was\n",
    "# - `b` becomes what `c` originally was\n",
    "a, c, b = b, a, c\n",
    "print(a)\n",
    "print(b)\n",
    "print(c)"
    ]
    },
    {
    "cell_type": "markdown",
    "metadata": {},
    "source": [
    "## Python \"for\" loops\n",
    "\n",
    "It is easy to **iterate** over a collection of items using a **for loop**. The lists, tuples, sets, and dictionaries we defined are all built-in **containers** that you can iterate over. (Actually, the strings are containers of characters that we can iterate over as well).\n",
    "\n",
    "The for loop will go through the specified container, one item at a time, and provide a temporary variable for the current item. You can use this temporary variable like a normal variable."
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Iterate through `list_1` and display each item on a new line\n",
    "for item in list_1:\n",
    " print(item)"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Iterate through `list_1` and display the absolute value of each item on a new line\n",
    "for item in list_1:\n",
    " print(abs(item))"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Iterate through `list_1` and print a string for each item\n",
    "for num in list_1:\n",
    " print('Absolute value of {} is {}'.format(num, abs(num)))"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Iterate through `string_1` and print each character on a new line\n",
    "for character in string_1:\n",
    " print(character)"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Iterate through `dict_1` and display each key on a new line\n",
    "for key in dict_1:\n",
    " print(key)"
    ]
    },
    {
    "cell_type": "markdown",
    "metadata": {},
    "source": [
    "## Using for loops with tuple assignment\n",
    "\n",
    "You may have noticed that when you call the `.items()` method on a dictionary object, you receive a list of 2-item tuples.\n",
    "\n",
    "It is possible to iterate over this data and use tuple assignment to store the intermediate values of each key/value pair."
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Iterate through `dict_1.items()` and display each key and value in a formatted string\n",
    "for key, value in dict_1.items():\n",
    " print('{} -> {}'.format(key, value))"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Iterate through `dict_1.items()` and display each item (no tuple assignment)\n",
    "for item in dict_1.items():\n",
    " print(item)"
    ]
    },
    {
    "cell_type": "markdown",
    "metadata": {},
    "source": [
    "## Python booleans and \"conditional expressions\"\n",
    "\n",
    "A boolean object has a value of `True` or `False`. A conditional expression is one that evaluates to a boolean value. This allows you to ask questions about your data so you can make a decision to \"do something\" or \"do something else\" next."
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Does the key 'a' exist in the dictionary `dict_1`?\n",
    "'a' in dict_1"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Are there more than 5 keys in `dict_1`?\n",
    "len(dict_1.keys()) > 5"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Does `string_1` start with 'this'?\n",
    "string_1.startswith('this')"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Does `string_1` start with 'This'?\n",
    "string_1.startswith('This')"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Is the smallest item in `list_1` less than 0?\n",
    "min(list_1) < 0"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Is the string 'dogs' a sub-string of a longer string?\n",
    "'dogs' in 'there are some dogs and cats'"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Is 5 times 5 equal to 25?\n",
    "5 * 5 == 25"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "print(num_1, num_2, num_3)"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Is `num_1` larger than `num_2` and `num_3`?\n",
    "num_1 > num_2 and num_1 > num_3"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Is `num_1` less than `num_2` OR is `num_1` greater than `num_3`?\n",
    "num_1 < num_2 or num_1 > num_3"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Is `num_3` between `num_1` and `num_2`?\n",
    "num_1 > num_3 > num_2"
    ]
    },
    {
    "cell_type": "markdown",
    "metadata": {},
    "source": [
    "## Python \"if statements\" and \"while loops\"\n",
    "\n",
    "Conditional expressions can be used with these two **conditional statements**.\n",
    "\n",
    "The **if statement** allows you to test a condition and perform some actions if the condition evaluates to `True`.\n",
    "\n",
    "The **while loop** will keep looping until its conditional expression evaluates to `False`. The **for loop** will iterate over a container of items until there are no more (no need to specify a \"stop looping\" condition).\n",
    "\n",
    "It is possible to \"loop forever\" when using a while loop with a conditional expression that never evaluates to `False` (i.e. `while True:`)."
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "if num_1 > num_3 > num_2:\n",
    " print('num_3 is between num_1 and num_2')"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "if string_1.startswith('This'):\n",
    " print('string_1 starts with \"This\"')\n",
    "else:\n",
    " print('string_1 does not start with \"This\"')"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "if num_1 < 0:\n",
    " print('num_1 is less than 0')\n",
    "elif num_1 == 0:\n",
    " print('num_1 is equal to 0')\n",
    "else:\n",
    " print('num_1 is greater than 0')"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "thing = ''\n",
    "while not thing:\n",
    " thing = input('please type stuff and hit <ENTER>: ')"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "thing"
    ]
    },
    {
    "cell_type": "markdown",
    "metadata": {},
    "source": [
    "## Creating objects from other objects\n",
    "\n",
    "Sometimes, you will have an object of one type that you need to make into another type. Use the **type constructor** for the type of object you want to have, and pass in the object you currently have."
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "print(int)\n",
    "print(float)\n",
    "print(str)\n",
    "print(list)\n",
    "print(tuple)\n",
    "print(set)\n",
    "print(dict)"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "print(type(int))\n",
    "print(type(float))\n",
    "print(type(str))\n",
    "print(type(list))\n",
    "print(type(tuple))\n",
    "print(type(set))\n",
    "print(type(dict))"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "print(float(123))\n",
    "print(int(1.23))\n",
    "print(list(string_1))\n",
    "print(dict(list_of_tuples_1))"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Sometimes, the type of object you have may have a method to return an object of the type you want\n",
    "print(', '.join(['jump', 'run', 'play']))"
    ]
    },
    {
    "cell_type": "markdown",
    "metadata": {},
    "source": [
    "## Exceptions"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Create an int from string 'stuff'\n",
    "int('stuff')"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# If creating an int raises a `ValueError` print a message instead\n",
    "try:\n",
    " int('stuff')\n",
    "except ValueError:\n",
    " print('You cannot make an int out of that')"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Catch the exception, do something, then re-raise the exception\n",
    "try:\n",
    " int('stuff')\n",
    "except ValueError:\n",
    " print('You cannot make an int out of that')\n",
    " raise"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Can't divide by zero\n",
    "1/0"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Can't reference a dictionary key that doesn't exist\n",
    "dict_1['not-a-real-key'] + 10"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Use the `get` method on the dictionary to fetch my key\n",
    "# - will return a `NoneType`, instead of raising a `KeyError`\n",
    "# - but a `NoneType` can't be added to an `int`, so a `TypeError` gets raised\n",
    "dict_1.get('not-a-real-key') + 10"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Specify a default value to return if the key doesn't exist in the dictionary\n",
    "dict_1.get('not-a-real-key', 0) + 10"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# There is no such variable defined called `not_a_dict`, so a `NameError` is raised\n",
    "not_a_dict['not-a-key']"
    ]
    },
    {
    "cell_type": "markdown",
    "metadata": {},
    "source": [
    "## Creating your own objects\n",
    "\n",
    "> TODO: Super brief intro to classes"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "print(object)\n",
    "print(type(object))\n",
    "print(dict)\n",
    "print(type(dict))"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# `dict` is a sub-class of `object`\n",
    "# `set` is a sub-class of `object`\n",
    "# `int` is a sub-class of `object`\n",
    "# `set` is not a sub-class of `dict`\n",
    "print(issubclass(dict, object))\n",
    "print(issubclass(set, object))\n",
    "print(issubclass(int, object))\n",
    "print(issubclass(set, dict))"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": true
    },
    "outputs": [],
    "source": [
    "# Define a new class called `Thing` that is derived from the base Python object\n",
    "class Thing(object):\n",
    " my_property = 'I am a \"Thing\"'\n",
    "\n",
    "\n",
    "# Define a new class called `DictThing` that is derived from the `dict` type (which is a class)\n",
    "class DictThing(dict):\n",
    " my_property = 'I am a \"DictThing\"'"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "print(Thing)\n",
    "print(type(Thing))\n",
    "print(DictThing)\n",
    "print(type(DictThing))\n",
    "print(issubclass(DictThing, dict))\n",
    "print(issubclass(DictThing, object))"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Create \"instances\" of our new classes\n",
    "t = Thing()\n",
    "d = DictThing()\n",
    "print(t)\n",
    "print(type(t))\n",
    "print(d)\n",
    "print(type(d))"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "# Interact with a DictThing instance just as you would a normal dictionary\n",
    "d['name'] = 'Sally'\n",
    "print(d)"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "d.update({\n",
    " 'age': 13,\n",
    " 'fav_foods': ['pizza', 'sushi', 'pad thai', 'waffles'],\n",
    " 'fav_color': 'green',\n",
    " })\n",
    "print(d)"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "print(d.my_property)"
    ]
    },
    {
    "cell_type": "markdown",
    "metadata": {},
    "source": [
    "## TODO\n",
    "\n",
    "Add the following sections before \"putting things together\"\n",
    "\n",
    "- importing modules\n",
    "- defining functions\n",
    "- `__name__`\n",
    "- list comprehension\n",
    "- conditional assignment\n",
    "- unpacking argument lists and keywoard argument dicts\n",
    "- getattr"
    ]
    },
    {
    "cell_type": "markdown",
    "metadata": {
    "collapsed": true
    },
    "source": [
    "<hr>\n",
    "# Putting things together (complex examples)\n",
    "<hr>"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "import sys\n",
    "\n",
    "def module_objects(module=__name__):\n",
    " \"\"\"Return a list of dicts with info about objects in the given module (or module name)\n",
    " \n",
    " - attr_name: name of the object\n",
    " - module_name: name of the module containing the object\n",
    " - type: type of the object\n",
    " - is_callable: True if the object is a function\n",
    " - simple_value: None, or value of the object if it is a simple type (str, int, float)\n",
    " \"\"\"\n",
    " if type(module) == str:\n",
    " module = sys.modules.get(module)\n",
    " \n",
    " data = []\n",
    " for attr_name in sorted(dir(module)):\n",
    " obj = getattr(module, attr_name)\n",
    " obj_info = {\n",
    " 'attr_name': attr_name,\n",
    " 'module_name': module.__name__,\n",
    " 'type': type(obj),\n",
    " 'is_callable': True if callable(obj) else False,\n",
    " 'simple_value': obj if type(obj) in (str, int, float) else None,\n",
    " }\n",
    " data.append(obj_info)\n",
    " \n",
    " return data"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "sorted(sys.modules.keys())"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "module_objects('random')"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "module_objects('concurrent.futures.thread')"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "[\n",
    " '{attr_name} from {module_name} is a {type}'.format(**thing)\n",
    " for thing in module_objects()\n",
    " if thing['is_callable']\n",
    "]"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "[\n",
    " '{attr_name} from {module_name} is a {type}'.format(**thing)\n",
    " for thing in module_objects(sys)\n",
    " if thing['is_callable']\n",
    "]"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": false
    },
    "outputs": [],
    "source": [
    "[\n",
    " '{attr_name} from {module_name} is a {type}'.format(**thing)\n",
    " for thing in module_objects('re')\n",
    " if thing['is_callable']\n",
    "]"
    ]
    },
    {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
    "collapsed": true
    },
    "outputs": [],
    "source": []
    }
    ],
    "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.4.3"
    }
    },
    "nbformat": 4,
    "nbformat_minor": 0
    }