├── .gitignore ├── 00 Programming Environment.ipynb ├── 01 Hello World.ipynb ├── 01 Introducing the IPython Notebook.ipynb ├── 02 Variable Strings and Numbers.ipynb ├── 03 List and Tuples and Sets.ipynb ├── 04 If Statements.ipynb ├── 05 While Loops and User input.ipynb ├── 06 Dictionaries.ipynb ├── 07 Introduction to Functions.ipynb ├── 07 More Functions.ipynb ├── 08 Classes and OOP.ipynb ├── 09 Exceptions.ipynb ├── 10 External files.ipynb ├── 11 Persistence.ipynb ├── Coding Style (PEP8).ipynb ├── Importing Modules.ipynb ├── Index.ipynb ├── LICENSE ├── README.md ├── Resources and References.ipynb ├── The Zen of Python.ipynb ├── data ├── data.txt ├── data2.txt ├── dbase1 ├── elderlyHeightWeight.csv ├── male_data.tsv ├── new_data.csv ├── test.txt └── testdb ├── files ├── example.css ├── images │ ├── command_mode.png │ ├── edit_mode.png │ └── menubar_toolbar.png └── makedicts.py ├── multiplying.py └── rocket.py /.gitignore: -------------------------------------------------------------------------------- 1 | TOC.ipynb 2 | __pycache__ 3 | data/BODY_COMPOSITION_DATA_4_ASSIGNMENT.csv 4 | data/BODY_COMPOSITION_DATA_4_ASSIGNMENT.tsv 5 | data/elderly_bmi.csv 6 | data/elderlyPhenoData_small.csv 7 | data/energy.txt 8 | data/energy_intake.txt 9 | data/helium.txt 10 | data/marathon.csv 11 | data/module_grades.tsv 12 | data/nhanes.csv 13 | data/nhanes_bmi.csv 14 | data/obesity_stats.xlsx 15 | data/pparg_prot.fa 16 | data/run10.txt 17 | data/states.csv 18 | Untitled.ipynb 19 | -------------------------------------------------------------------------------- /00 Programming Environment.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Programming Environment\n", 8 | "\n", 9 | "Your \"programming environment\" is the computer you do your work on, and all the software that is installed on your computer that helps you write and run programs. Some systems are better for programming than others, but the best system to learn on is probably the one you are using right now. This section will help you get a system set up that will let you start writing programs quickly." 10 | ] 11 | }, 12 | { 13 | "cell_type": "markdown", 14 | "metadata": {}, 15 | "source": [ 16 | "Overview\n", 17 | "===\n", 18 | "Our goal is to help you get Python up and running on your computer, so that you can write and run your own programs. To do this, we want to:\n", 19 | "\n", 20 | "- Find out if Python is already installed on your computer.\n", 21 | "- Install Python, if it is not already installed.\n", 22 | "\n", 23 | "----\n" 24 | ] 25 | }, 26 | { 27 | "cell_type": "markdown", 28 | "metadata": {}, 29 | "source": [ 30 | "# Disclaimer\n", 31 | "\n", 32 | "If you already have a working Python installation, please feel free to skip this notebook." 33 | ] 34 | }, 35 | { 36 | "cell_type": "markdown", 37 | "metadata": {}, 38 | "source": [ 39 | "# Anaconda Python Distribution\n", 40 | "\n", 41 | "We use **Python 3.5** included in the [**Anaconda**](https://store.continuum.io/cshop/anaconda/) distribution by \n", 42 | "[**Continuum Analytics**](http://www.continuum.io/).\n", 43 | "\n", 44 | "Anaconda is a completely free enterprise-ready Python distribution for large-scale data processing, predictive analytics, and scientific computing. \n", 45 | "\n", 46 | "Apart from that, Anaconda ships with easy-to-use installers for almost every platform, that wuold drastically reduce the \n", 47 | "burden of setting up the environment (exp. on [Windows](http://continuum.io/downloads#34))" 48 | ] 49 | }, 50 | { 51 | "cell_type": "markdown", 52 | "metadata": {}, 53 | "source": [ 54 | "## Quick Start Guide\n", 55 | "\n", 56 | "If you've installed **Anaconda** but you don't know what do then, please take a look at the [Quick Start Guide](https://store.continuum.io/static/img/Anaconda-Quickstart.pdf)" 57 | ] 58 | }, 59 | { 60 | "cell_type": "markdown", 61 | "metadata": {}, 62 | "source": [ 63 | "## Standard or System Python Distributions\n", 64 | "\n", 65 | "If you would like to install more \"classical\" Python distributions (e.g., those available on the \n", 66 | "[`python.org`](https://www.python.org/downloads/) web site), please take a look at this notebook:\n", 67 | "\n", 68 | "\n", 69 | "[Programming Environment](http://nbviewer.ipython.org/urls/raw.github.com/ehmatthes/intro_programming/master/notebooks/programming_environment.ipynb)" 70 | ] 71 | } 72 | ], 73 | "metadata": { 74 | "kernelspec": { 75 | "display_name": "Python 3", 76 | "language": "python", 77 | "name": "python3" 78 | }, 79 | "language_info": { 80 | "codemirror_mode": { 81 | "name": "ipython", 82 | "version": 3 83 | }, 84 | "file_extension": ".py", 85 | "mimetype": "text/x-python", 86 | "name": "python", 87 | "nbconvert_exporter": "python", 88 | "pygments_lexer": "ipython3", 89 | "version": "3.5.1" 90 | } 91 | }, 92 | "nbformat": 4, 93 | "nbformat_minor": 0 94 | } 95 | -------------------------------------------------------------------------------- /01 Hello World.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "slideshow": { 7 | "slide_type": "slide" 8 | } 9 | }, 10 | "source": [ 11 | "# \"Hello world\" in Python!" 12 | ] 13 | }, 14 | { 15 | "cell_type": "markdown", 16 | "metadata": { 17 | "slideshow": { 18 | "slide_type": "subslide" 19 | } 20 | }, 21 | "source": [ 22 | "When programmers are learning a new language, we tend to write a one-line program that prints some version of the message \"Hello world!\" this is a simple program that shows whether your computer is properly set up to run Python programs." 23 | ] 24 | }, 25 | { 26 | "cell_type": "code", 27 | "execution_count": 3, 28 | "metadata": { 29 | "collapsed": false, 30 | "slideshow": { 31 | "slide_type": "fragment" 32 | } 33 | }, 34 | "outputs": [ 35 | { 36 | "name": "stdout", 37 | "output_type": "stream", 38 | "text": [ 39 | "Hello Python world!\n" 40 | ] 41 | } 42 | ], 43 | "source": [ 44 | "print('Hello Python world!')" 45 | ] 46 | }, 47 | { 48 | "cell_type": "markdown", 49 | "metadata": { 50 | "slideshow": { 51 | "slide_type": "fragment" 52 | } 53 | }, 54 | "source": [ 55 | "If it works, congratulations! You just ran your first Python program." 56 | ] 57 | } 58 | ], 59 | "metadata": { 60 | "kernelspec": { 61 | "display_name": "Python 3", 62 | "language": "python", 63 | "name": "python3" 64 | }, 65 | "language_info": { 66 | "codemirror_mode": { 67 | "name": "ipython", 68 | "version": 3 69 | }, 70 | "file_extension": ".py", 71 | "mimetype": "text/x-python", 72 | "name": "python", 73 | "nbconvert_exporter": "python", 74 | "pygments_lexer": "ipython3", 75 | "version": "3.5.1" 76 | } 77 | }, 78 | "nbformat": 4, 79 | "nbformat_minor": 0 80 | } 81 | -------------------------------------------------------------------------------- /01 Introducing the IPython Notebook.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "slideshow": { 7 | "slide_type": "slide" 8 | } 9 | }, 10 | "source": [ 11 | "# Introducing the IPython Notebook" 12 | ] 13 | }, 14 | { 15 | "cell_type": "markdown", 16 | "metadata": { 17 | "slideshow": { 18 | "slide_type": "skip" 19 | } 20 | }, 21 | "source": [ 22 | "### Aron Ahmadia (US Army ERDC) and David Ketcheson (KAUST)" 23 | ] 24 | }, 25 | { 26 | "cell_type": "markdown", 27 | "metadata": { 28 | "slideshow": { 29 | "slide_type": "skip" 30 | } 31 | }, 32 | "source": [ 33 | "### Teaching Numerical Methods with IPython Notebooks, SciPy 2014" 34 | ] 35 | }, 36 | { 37 | "cell_type": "markdown", 38 | "metadata": { 39 | "slideshow": { 40 | "slide_type": "notes" 41 | } 42 | }, 43 | "source": [ 44 | "\"Creative
This lecture by Aron Ahmadia and David Ketcheson is licensed under a Creative Commons Attribution 4.0 International License. All code examples are also licensed under the [MIT license](http://opensource.org/licenses/MIT).\n", 45 | "\n", 46 | "**NOTE**: Some changes have been applied to make this notebook compliant with **Python 3**" 47 | ] 48 | }, 49 | { 50 | "cell_type": "markdown", 51 | "metadata": { 52 | "slideshow": { 53 | "slide_type": "slide" 54 | } 55 | }, 56 | "source": [ 57 | "## What is this?" 58 | ] 59 | }, 60 | { 61 | "cell_type": "markdown", 62 | "metadata": { 63 | "slideshow": { 64 | "slide_type": "fragment" 65 | } 66 | }, 67 | "source": [ 68 | "This is a gentle introduction to the IPython Notebook aimed at lecturers who wish to incorporate it in their teaching, written in an IPython Notebook. This presentation adapts material from the [IPython official documentation](http://nbviewer.ipython.org/github/ipython/ipython/blob/2.x/examples/Notebook)." 69 | ] 70 | }, 71 | { 72 | "cell_type": "markdown", 73 | "metadata": { 74 | "slideshow": { 75 | "slide_type": "slide" 76 | } 77 | }, 78 | "source": [ 79 | "## What is an IPython Notebook?" 80 | ] 81 | }, 82 | { 83 | "cell_type": "markdown", 84 | "metadata": { 85 | "slideshow": { 86 | "slide_type": "fragment" 87 | } 88 | }, 89 | "source": [ 90 | "An IPython Notebook is a:\n", 91 | "\n", 92 | "**[A]** Interactive environment for writing and running code \n", 93 | "**[B]** Weave of code, data, prose, equations, analysis, and visualization \n", 94 | "**[C]** Tool for prototyping new code and analysis \n", 95 | "**[D]** Reproducible workflow for scientific research \n" 96 | ] 97 | }, 98 | { 99 | "cell_type": "markdown", 100 | "metadata": { 101 | "slideshow": { 102 | "slide_type": "fragment" 103 | } 104 | }, 105 | "source": [ 106 | "**[E]** **All of the above**" 107 | ] 108 | }, 109 | { 110 | "cell_type": "markdown", 111 | "metadata": { 112 | "slideshow": { 113 | "slide_type": "slide" 114 | } 115 | }, 116 | "source": [ 117 | "### Writing and Running Code" 118 | ] 119 | }, 120 | { 121 | "cell_type": "markdown", 122 | "metadata": { 123 | "slideshow": { 124 | "slide_type": "fragment" 125 | } 126 | }, 127 | "source": [ 128 | "The IPython Notebook consists of an ordered list of cells. \n", 129 | "\n", 130 | "There are four important cell types:\n", 131 | "\n", 132 | "* **Code**\n", 133 | "* **Markdown**\n", 134 | "* **Heading**\n", 135 | "* **Raw**" 136 | ] 137 | }, 138 | { 139 | "cell_type": "markdown", 140 | "metadata": { 141 | "slideshow": { 142 | "slide_type": "fragment" 143 | } 144 | }, 145 | "source": [ 146 | "We briefly introduce how Code Cells work here. We will return to the other three cell types later." 147 | ] 148 | }, 149 | { 150 | "cell_type": "markdown", 151 | "metadata": { 152 | "slideshow": { 153 | "slide_type": "slide" 154 | } 155 | }, 156 | "source": [ 157 | "### Code Cells" 158 | ] 159 | }, 160 | { 161 | "cell_type": "code", 162 | "execution_count": 1, 163 | "metadata": { 164 | "collapsed": false, 165 | "slideshow": { 166 | "slide_type": "fragment" 167 | } 168 | }, 169 | "outputs": [], 170 | "source": [ 171 | "# This is a code cell made up of Python comments\n", 172 | "# We can execute it by clicking on it with the mouse\n", 173 | "# then clicking the \"Run Cell\" button" 174 | ] 175 | }, 176 | { 177 | "cell_type": "code", 178 | "execution_count": 2, 179 | "metadata": { 180 | "collapsed": false, 181 | "slideshow": { 182 | "slide_type": "fragment" 183 | } 184 | }, 185 | "outputs": [ 186 | { 187 | "name": "stdout", 188 | "output_type": "stream", 189 | "text": [ 190 | "Hello, World\n" 191 | ] 192 | } 193 | ], 194 | "source": [ 195 | "# A comment is a pretty boring piece of code\n", 196 | "# This code cell generates \"Hello, World\" when executed\n", 197 | "\n", 198 | "print(\"Hello, World\")" 199 | ] 200 | }, 201 | { 202 | "cell_type": "code", 203 | "execution_count": 3, 204 | "metadata": { 205 | "collapsed": false, 206 | "slideshow": { 207 | "slide_type": "subslide" 208 | } 209 | }, 210 | "outputs": [ 211 | { 212 | "data": { 213 | "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXcAAAEACAYAAABI5zaHAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAADu1JREFUeJzt3H+s3fVdx/Hni1ZwSlpdzYprR6sIU5ZgxQSKxHCWaUYx\nUv9Y3OYSFP8hyyZEErNJlrR/6h/GDOeCjYysy+bYyLKhA8WF3ZD5RzeBhjrajWULlDKuIaxBfsSU\n+faP86XcXW57zr0993xPP/f5SL7p98f7fr/vnJ7zOp/zOfd7U1VIktpyTt8NSJImz3CXpAYZ7pLU\nIMNdkhpkuEtSgwx3SWrQyHBPcl6SA0keTXIoyZ5T1N2e5IkkB5PsmHyrkqRxrR9VUFX/m+SdVfVy\nknXAfyS5v6q++VpNkl3ARVV1cZIrgTuAnavXtiTpdMaalqmql7vV8xi+ISy+82k3sL+rPQBsTLJ5\nUk1KkpZnrHBPck6SR4FngX+vqm8tKtkCHF2wfazbJ0nqwbgj9/+rqt8AtgJXJrl0dduSJJ2JkXPu\nC1XVC0m+DlwLPL7g0DHgbQu2t3b7fkIS/5CNJK1AVWU59eP8tswvJNnYrb8J+F3gyKKye4Ebupqd\nwPGqmj9Fgy5V7Nmzp/ceXv+jcdXzMgs91Ew8P2fleTELi4/F68tKjDNy/0Xg00nOYfhmcHdV3Zfk\npuFrofZ129cl+R7wEnDjirqRJE3EOL8KeQi4fIn9/7Bo+8MT7EuSdAa8Q7Ung8Gg7xY0g3xevM7H\n4sxkpfM5K7pYUtO8nkZLwhtvW5h6FzPQA0BWPL8praYk1KS/UJUknX0Md0lqkOEuSQ0y3CWpQYa7\nJDXIcJekBhnuktQgw12SGmS4S1KDDHdJapDhLkkNMtwlqUGGuyQ1yHCXpAYZ7pLUIMNdkhpkuEtS\ngwx3SWqQ4S5JDTLcJalBhrskNchwl6QGGe6S1CDDXZIaZLhLUoMMd0lq0MhwT7I1yYNJvp3kUJKb\nl6i5JsnxJI90y8dWp11J0jjWj1HzKnBrVR1Mcj7wcJIHqurIorqHqur6ybcoSVqukSP3qnq2qg52\n6y8Ch4EtS5Rmwr1JklZoWXPuSbYDO4ADSxy+KsnBJF9NcukEepMkrdA40zIAdFMy9wC3dCP4hR4G\nLqyql5PsAr4MXDK5NiVJyzFWuCdZzzDYP1NVX1l8fGHYV9X9ST6Z5M1V9fzi2r17955cHwwGDAaD\nFbQtSe2am5tjbm7ujM6RqhpdlOwHnquqW09xfHNVzXfrVwBfqKrtS9TVONfT9CQB+v4/mYUeAILP\nT82iJFTVsr7XHDlyT3I18AHgUJJHGb4KbwO2AVVV+4D3JPkgcAJ4BXjvcpuXJE3OWCP3iV3MkfvM\nceS+kCN3zaaVjNy9Q1WSGmS4S1KDDHdJapDhLkkNMtwlqUGGuyQ1yHCXpAYZ7pLUIMNdkhpkuEtS\ngwx3SWqQ4S5JDTLcJalBhrskNchwl6QGGe6S1CDDXZIaZLhLUoMMd0lqkOEuSQ0y3CWpQYa7JDXI\ncJekBhnuktQgw12SGmS4S1KDDHdJapDhLkkNMtwlqUEjwz3J1iQPJvl2kkNJbj5F3e1JnkhyMMmO\nybcqSRrX+jFqXgVuraqDSc4HHk7yQFUdea0gyS7goqq6OMmVwB3AztVpWZI0ysiRe1U9W1UHu/UX\ngcPAlkVlu4H9Xc0BYGOSzRPuVZI0pmXNuSfZDuwADiw6tAU4umD7GG98A5AkTck40zIAdFMy9wC3\ndCP4Fdm7d+/J9cFgwGAwWOmpzmoXXLCd+fkn+25D0gyam5tjbm7ujM6RqhpdlKwH/gW4v6o+vsTx\nO4CvV9Xd3fYR4Jqqml9UV+Ncby1IAszCYzELfcxCDwDB56dmURKqKsv5mXGnZT4FPL5UsHfuBW7o\nmtgJHF8c7JKk6Rk5ck9yNfAQcIjh8KqA24BtQFXVvq7uE8C1wEvAjVX1yBLncuTeceQ+az2AI3fN\nqpWM3MealpkUw/11hvus9QCGu2bVak7LSJLOIoa7JDXIcJekBhnuktQgw12SGmS4S1KDDHdJapDh\nLkkNMtwlqUGGuyQ1yHCXpAYZ7pLUIMNdkhpkuEtSgwx3SWqQ4S5JDTLcJalBhrskNchwl6QGGe6S\n1CDDXZIaZLhLUoMMd0lqkOEuSQ0y3CWpQYa7JDXIcJekBhnuktSgkeGe5M4k80keO8Xxa5IcT/JI\nt3xs8m1KkpZj/Rg1dwF/B+w/Tc1DVXX9ZFqSJJ2pkSP3qvoG8KMRZZlMO5KkSZjUnPtVSQ4m+WqS\nSyd0TknSCo0zLTPKw8CFVfVykl3Al4FLTlW8d+/ek+uDwYDBYDCBFiSpHXNzc8zNzZ3ROVJVo4uS\nbcA/V9VlY9T+APjNqnp+iWM1zvXWgiTALDwWs9DHLPQAEHx+ahYloaqWNf097rRMOMW8epLNC9av\nYPiG8YZglyRNz8hpmSSfAwbApiRPAXuAc4Gqqn3Ae5J8EDgBvAK8d/XalSSNY6xpmYldzGmZk5yW\nmbUewGkZzarVnJaRJJ1FDHdJapDhLkkNMtwlqUGGuyQ1yHCXpAYZ7pLUIMNdkhpkuEtSgwx3SWqQ\n4S5JDTLcJalBhrskNchwl6QGGe6S1CDDXZIaZLhLUoMMd0lqkOEuSQ0y3CWpQYa7JDXIcJekBhnu\nktQgw12SGmS4S1KDDHdJapDhLkkNMtwlqUEjwz3JnUnmkzx2mprbkzyR5GCSHZNtUZK0XOOM3O8C\n3n2qg0l2ARdV1cXATcAdE+pNkrRCI8O9qr4B/Og0JbuB/V3tAWBjks2TaU+StBLrJ3COLcDRBdvH\nun3zSxU/88wzE7jkyp133nls2rSp1x4kabVNItyXZdu2t59cX7fuXNatO2+q1z9x4jgbN27iueee\nnup1JZ2dLrhgO/PzT/bdxrJNItyPAW9bsL2127ekV1/9nwXrE7j6Mm3YcBnPPXcIqOlf/Cek5+tL\nGscw2M++vBj3VyFzmrPfC9wAkGQncLyqlpySkSRNx8iRe5LPAQNgU5KngD3AuUBV1b6qui/JdUm+\nB7wE3LiaDUuSRkvV9D5uJKm+P95s2HAZL7wwK9MyffcAs9HHLPQAEKb5etDZIZmF52eoqmXNzXiH\nqiQ1yHCXpAYZ7pLUIMNdkhpkuEtSgwx3SWqQ4S5JDTLcJalBhrskNchwl6QGGe6S1CDDXZIaZLhL\nUoMMd0lqkOEuSQ0y3CWpQYa7JDXIcJekBhnuktQgw12SGmS4S1KDDHdJapDhLkkNMtwlqUGGuyQ1\nyHCXpAYZ7pLUIMNdkho0VrgnuTbJkSTfTfKRJY5fk+R4kke65WOTb1WSNK71owqSnAN8AngX8Azw\nrSRfqaoji0ofqqrrV6FHSdIyjTNyvwJ4oqqerKoTwOeB3UvUZaKdSZJWbJxw3wIcXbD9dLdvsauS\nHEzy1SSXTqQ7SdKKjJyWGdPDwIVV9XKSXcCXgUsmdG5J0jKNE+7HgAsXbG/t9p1UVS8uWL8/ySeT\nvLmqnn/j6fYuWB90iyTpdXPdsnKpqtMXJOuA7zD8QvWHwDeB91fV4QU1m6tqvlu/AvhCVW1f4lwF\np7/eatuw4TJeeOEQffcx/Iqi7x5gNvqYhR4AwqjXg9aeZBaen6GqlvW95siRe1X9OMmHgQcYztHf\nWVWHk9w0PFz7gPck+SBwAngFeO/ym5ckTcrIkftEL+bIfYFZGA3AbPQxCz2AI3ct5WwduXuHqiQ1\nyHCXpAYZ7pLUIMNdkhpkuEtSgwx3SWqQ4S5JDTLcJalBhrskNchwl6QGGe6S1CDDXZIaZLhLUoMM\nd0lqkOEuSQ0y3CWpQYa7JDXIcJekBhnuktQgw12SGmS4S1KDDHdJapDhLkkNMtwlqUGGuyQ1yHCX\npAYZ7pLUIMNdkho0VrgnuTbJkSTfTfKRU9TcnuSJJAeT7Jhsm5Kk5RgZ7knOAT4BvBt4B/D+JL+6\nqGYXcFFVXQzcBNyxCr1KzZubm+u7hZnhY3Fmxhm5XwE8UVVPVtUJ4PPA7kU1u4H9AFV1ANiYZPNE\nO5XWAAPtdT4WZ2accN8CHF2w/XS373Q1x5aokSRNyfppX3DDht+f9iV/wiuv/KDX60vSNKSqTl+Q\n7AT2VtW13fZHgaqqv15Qcwfw9aq6u9s+AlxTVfOLznX6i0mSllRVWU79OCP3bwG/kmQb8EPgfcD7\nF9XcC3wIuLt7Mzi+ONhX0pwkaWVGhntV/TjJh4EHGM7R31lVh5PcNDxc+6rqviTXJfke8BJw4+q2\nLUk6nZHTMpKks8/U7lAd50aotSDJ1iQPJvl2kkNJbu67pz4lOSfJI0nu7buXviXZmOSLSQ53z48r\n++6pD0n+PMl/JXksyWeTnNt3T9OU5M4k80keW7Dv55M8kOQ7Sf4tycZR55lKuI9zI9Qa8ipwa1W9\nA7gK+NAafiwAbgEe77uJGfFx4L6q+jXg14HDPfczdUneCvwZcHlVXcZw6vh9/XY1dXcxzMqFPgp8\nrareDjwI/OWok0xr5D7OjVBrQlU9W1UHu/UXGb6A1+Q9AUm2AtcB/9h3L31LsgH47aq6C6CqXq2q\nF3puqy/rgJ9Nsh74GeCZnvuZqqr6BvCjRbt3A5/u1j8N/MGo80wr3Me5EWrNSbId2AEc6LeT3vwt\n8BeAX/zALwHPJbmrm6bal+RNfTc1bVX1DPA3wFMMb4Y8XlVf67ermfCW134DsaqeBd4y6gf8q5A9\nSXI+cA9wSzeCX1OS/B4w332KSbesZeuBy4G/r6rLgZcZfhRfU5L8HMNR6jbgrcD5Sf6o365m0sgB\n0bTC/Rhw4YLtrd2+Nan7uHkP8Jmq+krf/fTkauD6JN8H/gl4Z5L9PffUp6eBo1X1n932PQzDfq35\nHeD7VfV8Vf0Y+BLwWz33NAvmX/t7XUkuAP571A9MK9xP3gjVffP9PoY3Pq1VnwIer6qP991IX6rq\ntqq6sKp+meHz4cGquqHvvvrSfeQ+muSSbte7WJtfND8F7Ezy00nC8HFYc18s88ZPs/cCf9Kt/zEw\nclA4lb8tc6oboaZx7VmT5GrgA8ChJI8y/Hh1W1X9a7+daQbcDHw2yU8B32cN3gxYVd9Mcg/wKHCi\n+3dfv11NV5LPAQNgU5KngD3AXwFfTPKnwJPAH448jzcxSVJ7/EJVkhpkuEtSgwx3SWqQ4S5JDTLc\nJalBhrskNchwl6QGGe6S1KD/B19YUsQgbm54AAAAAElFTkSuQmCC\n", 214 | "text/plain": [ 215 | "" 216 | ] 217 | }, 218 | "metadata": {}, 219 | "output_type": "display_data" 220 | } 221 | ], 222 | "source": [ 223 | "# Code cells can also generate graphical output\n", 224 | "%matplotlib inline\n", 225 | "import matplotlib\n", 226 | "matplotlib.pyplot.hist([0, 1, 2, 2, 3, 3, 3, 4, 4, 4, 10]);" 227 | ] 228 | }, 229 | { 230 | "cell_type": "markdown", 231 | "metadata": { 232 | "slideshow": { 233 | "slide_type": "slide" 234 | } 235 | }, 236 | "source": [ 237 | "## Modal editor" 238 | ] 239 | }, 240 | { 241 | "cell_type": "markdown", 242 | "metadata": {}, 243 | "source": [ 244 | "Starting with IPython 2.0, the IPython Notebook has a modal user interface. This means that the keyboard does different things depending on which mode the Notebook is in. There are two modes: edit mode and command mode." 245 | ] 246 | }, 247 | { 248 | "cell_type": "markdown", 249 | "metadata": { 250 | "slideshow": { 251 | "slide_type": "subslide" 252 | } 253 | }, 254 | "source": [ 255 | "### Edit mode" 256 | ] 257 | }, 258 | { 259 | "cell_type": "markdown", 260 | "metadata": {}, 261 | "source": [ 262 | "Edit mode is indicated by a green cell border and a prompt showing in the editor area:\n", 263 | "\n", 264 | "\n", 265 | "\n", 266 | "When a cell is in edit mode, you can type into the cell, like a normal text editor." 267 | ] 268 | }, 269 | { 270 | "cell_type": "markdown", 271 | "metadata": { 272 | "slideshow": { 273 | "slide_type": "fragment" 274 | } 275 | }, 276 | "source": [ 277 | "
\n", 278 | "Enter edit mode by pressing `enter` or using the mouse to click on a cell's editor area.\n", 279 | "
" 280 | ] 281 | }, 282 | { 283 | "cell_type": "markdown", 284 | "metadata": { 285 | "slideshow": { 286 | "slide_type": "fragment" 287 | } 288 | }, 289 | "source": [ 290 | "
\n", 291 | "While in edit mode, tab-completion works for variables the kernel knows about from executing previous cells.\n", 292 | "
" 293 | ] 294 | }, 295 | { 296 | "cell_type": "markdown", 297 | "metadata": { 298 | "slideshow": { 299 | "slide_type": "subslide" 300 | } 301 | }, 302 | "source": [ 303 | "### Command mode" 304 | ] 305 | }, 306 | { 307 | "cell_type": "markdown", 308 | "metadata": {}, 309 | "source": [ 310 | "Command mode is indicated by a grey cell border:\n", 311 | "\n", 312 | "\n", 313 | "\n", 314 | "When you are in command mode, you are able to edit the notebook as a whole, but not type into individual cells. Most importantly, in command mode, the keyboard is mapped to a set of shortcuts that let you perform notebook and cell actions efficiently. For example, if you are in command mode and you press `c`, you will copy the current cell - no modifier is needed." 315 | ] 316 | }, 317 | { 318 | "cell_type": "markdown", 319 | "metadata": { 320 | "slideshow": { 321 | "slide_type": "fragment" 322 | } 323 | }, 324 | "source": [ 325 | "
\n", 326 | "Don't try to type into a cell in command mode; unexpected things will happen!\n", 327 | "
" 328 | ] 329 | }, 330 | { 331 | "cell_type": "markdown", 332 | "metadata": { 333 | "slideshow": { 334 | "slide_type": "fragment" 335 | } 336 | }, 337 | "source": [ 338 | "
\n", 339 | "Enter command mode by pressing `esc` or using the mouse to click *outside* a cell's editor area.\n", 340 | "
" 341 | ] 342 | }, 343 | { 344 | "cell_type": "markdown", 345 | "metadata": { 346 | "slideshow": { 347 | "slide_type": "slide" 348 | } 349 | }, 350 | "source": [ 351 | "## Mouse navigation" 352 | ] 353 | }, 354 | { 355 | "cell_type": "markdown", 356 | "metadata": {}, 357 | "source": [ 358 | "All navigation and actions in the Notebook are available using the mouse through the menubar and toolbar, which are both above the main Notebook area:\n", 359 | "\n", 360 | "" 361 | ] 362 | }, 363 | { 364 | "cell_type": "markdown", 365 | "metadata": { 366 | "slideshow": { 367 | "slide_type": "notes" 368 | } 369 | }, 370 | "source": [ 371 | "The first idea of mouse based navigation is that **cells can be selected by clicking on them.** The currently selected cell gets a grey or green border depending on whether the notebook is in edit or command mode. If you click inside a cell's editor area, you will enter edit mode. If you click on the prompt or output area of a cell you will enter command mode.\n", 372 | "\n", 373 | "If you are running this notebook in a live session (not on http://nbviewer.ipython.org) try selecting different cells and going between edit and command mode. Try typing into a cell." 374 | ] 375 | }, 376 | { 377 | "cell_type": "markdown", 378 | "metadata": { 379 | "slideshow": { 380 | "slide_type": "notes" 381 | } 382 | }, 383 | "source": [ 384 | "The second idea of mouse based navigation is that **cell actions usually apply to the currently selected cell**. Thus if you want to run the code in a cell, you would select it and click the \"Play\" button in the toolbar or the \"Cell:Run\" menu item. Similarly, to copy a cell you would select it and click the \"Copy\" button in the toolbar or the \"Edit:Copy\" menu item. With this simple pattern, you should be able to do most everything you need with the mouse.\n", 385 | "\n", 386 | "Markdown and heading cells have one other state that can be modified with the mouse. These cells can either be rendered or unrendered. When they are rendered, you will see a nice formatted representation of the cell's contents. When they are unrendered, you will see the raw text source of the cell. To render the selected cell with the mouse, click the \"Play\" button in the toolbar or the \"Cell:Run\" menu item. To unrender the selected cell, double click on the cell." 387 | ] 388 | }, 389 | { 390 | "cell_type": "markdown", 391 | "metadata": { 392 | "slideshow": { 393 | "slide_type": "slide" 394 | } 395 | }, 396 | "source": [ 397 | "## Keyboard Navigation" 398 | ] 399 | }, 400 | { 401 | "cell_type": "markdown", 402 | "metadata": { 403 | "slideshow": { 404 | "slide_type": "fragment" 405 | } 406 | }, 407 | "source": [ 408 | "The modal user interface of the IPython Notebook has been optimized for efficient keyboard usage. This is made possible by having two different sets of keyboard shortcuts: one set that is active in edit mode and another in command mode." 409 | ] 410 | }, 411 | { 412 | "cell_type": "markdown", 413 | "metadata": { 414 | "slideshow": { 415 | "slide_type": "fragment" 416 | } 417 | }, 418 | "source": [ 419 | "The most important keyboard shortcuts are `enter`, which enters edit mode, and `esc`, which enters command mode.\n", 420 | "\n", 421 | "In edit mode, most of the keyboard is dedicated to typing into the cell's editor. Thus, in edit mode there are relatively few shortcuts:" 422 | ] 423 | }, 424 | { 425 | "cell_type": "markdown", 426 | "metadata": {}, 427 | "source": [ 428 | "In command mode, the entire keyboard is available for shortcuts:" 429 | ] 430 | }, 431 | { 432 | "cell_type": "markdown", 433 | "metadata": { 434 | "slideshow": { 435 | "slide_type": "slide" 436 | } 437 | }, 438 | "source": [ 439 | "Here the rough order in which the IPython Developers recommend learning the command mode **shortcuts**:\n", 440 | "\n", 441 | "1. Basic navigation: `enter`, `shift-enter`, `up/k`, `down/j`\n", 442 | "2. Saving the notebook: `s`\n", 443 | "2. Cell types: `y`, `m`, `1-6`, `t`\n", 444 | "3. Cell creation and movement: `a`, `b`, `ctrl+k`, `ctrl+j`\n", 445 | "4. Cell editing: `x`, `c`, `v`, `d`, `z`, `shift+=`\n", 446 | "5. Kernel operations: `i`, `0`" 447 | ] 448 | }, 449 | { 450 | "cell_type": "markdown", 451 | "metadata": { 452 | "slideshow": { 453 | "slide_type": "fragment" 454 | } 455 | }, 456 | "source": [ 457 | "I personally (& humbly) suggest learning `h` first!" 458 | ] 459 | }, 460 | { 461 | "cell_type": "markdown", 462 | "metadata": { 463 | "slideshow": { 464 | "slide_type": "slide" 465 | } 466 | }, 467 | "source": [ 468 | "## The IPython Notebook Architecture" 469 | ] 470 | }, 471 | { 472 | "cell_type": "markdown", 473 | "metadata": { 474 | "slideshow": { 475 | "slide_type": "notes" 476 | } 477 | }, 478 | "source": [ 479 | "So far, we have learned the basics of using IPython Notebooks.\n", 480 | "\n", 481 | "For simple demonstrations, the typical user doesn't need to understand how the computations are being handled, but to successfully write and present computational notebooks, **you** will need to understand how the notebook architecture works." 482 | ] 483 | }, 484 | { 485 | "cell_type": "markdown", 486 | "metadata": { 487 | "slideshow": { 488 | "slide_type": "notes" 489 | } 490 | }, 491 | "source": [ 492 | "A *live* notebook is composed of an interactive web page (the front end), a running IPython session (the kernel or back end), and a web server responsible for handling communication between the two (the, err..., middle-end)" 493 | ] 494 | }, 495 | { 496 | "cell_type": "markdown", 497 | "metadata": { 498 | "slideshow": { 499 | "slide_type": "notes" 500 | } 501 | }, 502 | "source": [ 503 | "A *static* notebook, as for example seen on NBViewer, is a static view of the notebook's content. The default format is HTML, but a notebook can also be output in PDF or other formats." 504 | ] 505 | }, 506 | { 507 | "cell_type": "markdown", 508 | "metadata": {}, 509 | "source": [ 510 | "The centerpiece of an IPython Notebook is the \"kernel\", the IPython instance responsible for executing all code. Your IPython kernel maintains its state between executed cells." 511 | ] 512 | }, 513 | { 514 | "cell_type": "code", 515 | "execution_count": 4, 516 | "metadata": { 517 | "collapsed": false, 518 | "slideshow": { 519 | "slide_type": "subslide" 520 | } 521 | }, 522 | "outputs": [ 523 | { 524 | "name": "stdout", 525 | "output_type": "stream", 526 | "text": [ 527 | "0\n" 528 | ] 529 | } 530 | ], 531 | "source": [ 532 | "x = 0\n", 533 | "print(x)" 534 | ] 535 | }, 536 | { 537 | "cell_type": "code", 538 | "execution_count": 5, 539 | "metadata": { 540 | "collapsed": false, 541 | "slideshow": { 542 | "slide_type": "fragment" 543 | } 544 | }, 545 | "outputs": [ 546 | { 547 | "name": "stdout", 548 | "output_type": "stream", 549 | "text": [ 550 | "1\n" 551 | ] 552 | } 553 | ], 554 | "source": [ 555 | "x += 1\n", 556 | "print(x)" 557 | ] 558 | }, 559 | { 560 | "cell_type": "markdown", 561 | "metadata": { 562 | "slideshow": { 563 | "slide_type": "notes" 564 | } 565 | }, 566 | "source": [ 567 | "There are two important actions for interacting with the kernel. The first is to interrupt it. This is the same as sending a Control-C from the command line. The second is to restart it. This completely terminates the kernel and starts it anew. None of the kernel state is saved across a restart. " 568 | ] 569 | }, 570 | { 571 | "cell_type": "markdown", 572 | "metadata": { 573 | "slideshow": { 574 | "slide_type": "slide" 575 | } 576 | }, 577 | "source": [ 578 | "## Markdown cells" 579 | ] 580 | }, 581 | { 582 | "cell_type": "markdown", 583 | "metadata": {}, 584 | "source": [ 585 | "Text can be added to IPython Notebooks using Markdown cells. Markdown is a popular markup language that is a superset of HTML. Its specification can be found here:\n", 586 | "\n", 587 | "" 588 | ] 589 | }, 590 | { 591 | "cell_type": "markdown", 592 | "metadata": { 593 | "slideshow": { 594 | "slide_type": "slide" 595 | } 596 | }, 597 | "source": [ 598 | "## Markdown basics" 599 | ] 600 | }, 601 | { 602 | "cell_type": "markdown", 603 | "metadata": { 604 | "slideshow": { 605 | "slide_type": "subslide" 606 | } 607 | }, 608 | "source": [ 609 | "### Text formatting" 610 | ] 611 | }, 612 | { 613 | "cell_type": "markdown", 614 | "metadata": { 615 | "slideshow": { 616 | "slide_type": "fragment" 617 | } 618 | }, 619 | "source": [ 620 | "You can make text *italic* or **bold** or `monospace`" 621 | ] 622 | }, 623 | { 624 | "cell_type": "markdown", 625 | "metadata": { 626 | "slideshow": { 627 | "slide_type": "subslide" 628 | } 629 | }, 630 | "source": [ 631 | "### Itemized Lists" 632 | ] 633 | }, 634 | { 635 | "cell_type": "markdown", 636 | "metadata": {}, 637 | "source": [ 638 | "* One\n", 639 | " - Sublist\n", 640 | " - This\n", 641 | " - Sublist\n", 642 | " - That\n", 643 | " - The other thing\n", 644 | "* Two\n", 645 | " - Sublist\n", 646 | "* Three\n", 647 | " - Sublist" 648 | ] 649 | }, 650 | { 651 | "cell_type": "markdown", 652 | "metadata": { 653 | "slideshow": { 654 | "slide_type": "subslide" 655 | } 656 | }, 657 | "source": [ 658 | "### Enumerated Lists" 659 | ] 660 | }, 661 | { 662 | "cell_type": "markdown", 663 | "metadata": {}, 664 | "source": [ 665 | "1. Here we go\n", 666 | " 1. Sublist\n", 667 | " 2. Sublist\n", 668 | "2. There we go\n", 669 | "3. Now this" 670 | ] 671 | }, 672 | { 673 | "cell_type": "markdown", 674 | "metadata": { 675 | "slideshow": { 676 | "slide_type": "subslide" 677 | } 678 | }, 679 | "source": [ 680 | "### Horizontal Rules" 681 | ] 682 | }, 683 | { 684 | "cell_type": "markdown", 685 | "metadata": {}, 686 | "source": [ 687 | "---\n", 688 | "\n", 689 | "---\n", 690 | "\n", 691 | "---" 692 | ] 693 | }, 694 | { 695 | "cell_type": "markdown", 696 | "metadata": { 697 | "slideshow": { 698 | "slide_type": "subslide" 699 | } 700 | }, 701 | "source": [ 702 | "### Blockquotes" 703 | ] 704 | }, 705 | { 706 | "cell_type": "markdown", 707 | "metadata": {}, 708 | "source": [ 709 | "> To me programming is more than an important practical art. It is also a gigantic undertaking in the foundations of knowledge. -- Rear Admiral Grace Hopper" 710 | ] 711 | }, 712 | { 713 | "cell_type": "markdown", 714 | "metadata": { 715 | "slideshow": { 716 | "slide_type": "subslide" 717 | } 718 | }, 719 | "source": [ 720 | "### Links" 721 | ] 722 | }, 723 | { 724 | "cell_type": "markdown", 725 | "metadata": {}, 726 | "source": [ 727 | "[IPython's website](http://ipython.org)" 728 | ] 729 | }, 730 | { 731 | "cell_type": "markdown", 732 | "metadata": { 733 | "slideshow": { 734 | "slide_type": "subslide" 735 | } 736 | }, 737 | "source": [ 738 | "### Code" 739 | ] 740 | }, 741 | { 742 | "cell_type": "markdown", 743 | "metadata": {}, 744 | "source": [ 745 | "This is a code snippet: \n", 746 | " \n", 747 | "```Python\n", 748 | "def f(x):\n", 749 | " \"\"\"a docstring\"\"\"\n", 750 | " return x**2\n", 751 | "```\n", 752 | " \n", 753 | "This is an example of a **Python** function" 754 | ] 755 | }, 756 | { 757 | "cell_type": "markdown", 758 | "metadata": { 759 | "slideshow": { 760 | "slide_type": "fragment" 761 | } 762 | }, 763 | "source": [ 764 | "You can also use triple-backticks to denote code blocks.\n", 765 | "This also allows you to choose the appropriate syntax highlighter.\n", 766 | "\n", 767 | "```C\n", 768 | "if (i=0; i\n", 847 | " " 848 | ], 849 | "text/plain": [ 850 | "" 851 | ] 852 | }, 853 | "execution_count": 6, 854 | "metadata": {}, 855 | "output_type": "execute_result" 856 | } 857 | ], 858 | "source": [ 859 | "from IPython.display import YouTubeVideo\n", 860 | "YouTubeVideo('vW_DRAJ0dtc')" 861 | ] 862 | }, 863 | { 864 | "cell_type": "markdown", 865 | "metadata": { 866 | "slideshow": { 867 | "slide_type": "slide" 868 | } 869 | }, 870 | "source": [ 871 | "### Other HTML" 872 | ] 873 | }, 874 | { 875 | "cell_type": "markdown", 876 | "metadata": {}, 877 | "source": [ 878 | " Be Bold! " 879 | ] 880 | }, 881 | { 882 | "cell_type": "markdown", 883 | "metadata": { 884 | "slideshow": { 885 | "slide_type": "slide" 886 | } 887 | }, 888 | "source": [ 889 | "## Mathematical Equations" 890 | ] 891 | }, 892 | { 893 | "cell_type": "markdown", 894 | "metadata": { 895 | "slideshow": { 896 | "slide_type": "fragment" 897 | } 898 | }, 899 | "source": [ 900 | "Courtesy of MathJax, you can beautifully render mathematical expressions, both inline: \n", 901 | "$e^{i\\pi} + 1 = 0$, and displayed:\n", 902 | "\n", 903 | "$$e^x=\\sum_{i=0}^\\infty \\frac{1}{i!}x^i$$" 904 | ] 905 | }, 906 | { 907 | "cell_type": "markdown", 908 | "metadata": { 909 | "slideshow": { 910 | "slide_type": "subslide" 911 | } 912 | }, 913 | "source": [ 914 | "### Equation Environments" 915 | ] 916 | }, 917 | { 918 | "cell_type": "markdown", 919 | "metadata": {}, 920 | "source": [ 921 | "You can also use a number of equation environments, such as `align`:\n", 922 | "\n", 923 | "\\begin{align}\n", 924 | " x &= 4 \\\\\n", 925 | "y+z &= x\n", 926 | "\\end{align}\n", 927 | "\n", 928 | "[A full list of available TeX and LaTeX commands is maintained by Dr. Carol Burns.](http://www.onemathematicalcat.org/MathJaxDocumentation/TeXSyntax.htm)" 929 | ] 930 | }, 931 | { 932 | "cell_type": "markdown", 933 | "metadata": { 934 | "slideshow": { 935 | "slide_type": "subslide" 936 | } 937 | }, 938 | "source": [ 939 | "### Other Useful MathJax Notes" 940 | ] 941 | }, 942 | { 943 | "cell_type": "markdown", 944 | "metadata": {}, 945 | "source": [ 946 | "* inline math is demarcated by `$ $`, or `\\( \\)`\n", 947 | "* displayed math is demarcated by `$$ $$` or `\\[ \\]`\n", 948 | "* displayed math environments can also be directly demarcated by `\\begin` and `\\end`\n", 949 | "* `\\newcommand` and `\\def` are supported, *within* areas MathJax processes (such as in a `\\[ \\]` block)\n", 950 | "* equation numbering is not officially supported, but it can be indirectly enabled" 951 | ] 952 | }, 953 | { 954 | "cell_type": "markdown", 955 | "metadata": { 956 | "slideshow": { 957 | "slide_type": "slide" 958 | } 959 | }, 960 | "source": [ 961 | "## A Note about Notebook Security" 962 | ] 963 | }, 964 | { 965 | "cell_type": "markdown", 966 | "metadata": {}, 967 | "source": [ 968 | "By default, a notebook downloaded to a new computer is *untrusted*\n", 969 | "\n", 970 | "* HTML and Javascript in Markdown cells is now *never* executed\n", 971 | "* HTML and Javascript code outputs must be explicitly *re-executed*\n", 972 | "* Some of these restrictions can be mitigrated through shared accounts (Sage MathCloud) and secrets" 973 | ] 974 | }, 975 | { 976 | "cell_type": "markdown", 977 | "metadata": { 978 | "slideshow": { 979 | "slide_type": "notes" 980 | } 981 | }, 982 | "source": [ 983 | "More information on notebook security is in the [IPython Notebook documentation](http://ipython.org/ipython-doc/stable/notebook/security.html)" 984 | ] 985 | }, 986 | { 987 | "cell_type": "markdown", 988 | "metadata": { 989 | "slideshow": { 990 | "slide_type": "slide" 991 | } 992 | }, 993 | "source": [ 994 | "## Magics" 995 | ] 996 | }, 997 | { 998 | "cell_type": "markdown", 999 | "metadata": { 1000 | "slideshow": { 1001 | "slide_type": "-" 1002 | } 1003 | }, 1004 | "source": [ 1005 | "IPython kernels execute a superset of the Python language. The extension functions, commonly referred to as *magics*, come in two variants. " 1006 | ] 1007 | }, 1008 | { 1009 | "cell_type": "markdown", 1010 | "metadata": { 1011 | "slideshow": { 1012 | "slide_type": "subslide" 1013 | } 1014 | }, 1015 | "source": [ 1016 | "### Line Magics" 1017 | ] 1018 | }, 1019 | { 1020 | "cell_type": "markdown", 1021 | "metadata": { 1022 | "slideshow": { 1023 | "slide_type": "-" 1024 | } 1025 | }, 1026 | "source": [ 1027 | "* A *line magic* looks like a command line call. The most important of these is `%matplotlib inline`, which embeds all matplotlib plot output as images in the notebook itself." 1028 | ] 1029 | }, 1030 | { 1031 | "cell_type": "code", 1032 | "execution_count": 7, 1033 | "metadata": { 1034 | "collapsed": false, 1035 | "slideshow": { 1036 | "slide_type": "fragment" 1037 | } 1038 | }, 1039 | "outputs": [], 1040 | "source": [ 1041 | "%matplotlib inline" 1042 | ] 1043 | }, 1044 | { 1045 | "cell_type": "code", 1046 | "execution_count": 8, 1047 | "metadata": { 1048 | "collapsed": false, 1049 | "slideshow": { 1050 | "slide_type": "subslide" 1051 | } 1052 | }, 1053 | "outputs": [ 1054 | { 1055 | "name": "stdout", 1056 | "output_type": "stream", 1057 | "text": [ 1058 | "Variable Type Data/Info\n", 1059 | "----------------------------------\n", 1060 | "YouTubeVideo type \n", 1061 | "matplotlib module /matplotlib/__init__.py'>\n", 1062 | "x int 1\n" 1063 | ] 1064 | } 1065 | ], 1066 | "source": [ 1067 | "%whos" 1068 | ] 1069 | }, 1070 | { 1071 | "cell_type": "markdown", 1072 | "metadata": { 1073 | "slideshow": { 1074 | "slide_type": "subslide" 1075 | } 1076 | }, 1077 | "source": [ 1078 | "### Cell Magics" 1079 | ] 1080 | }, 1081 | { 1082 | "cell_type": "markdown", 1083 | "metadata": { 1084 | "slideshow": { 1085 | "slide_type": "-" 1086 | } 1087 | }, 1088 | "source": [ 1089 | "* A *cell magic* takes its entire cell as an argument. Although there are a number of useful cell magics, you may find `%%timeit` to be useful for exploring code performance." 1090 | ] 1091 | }, 1092 | { 1093 | "cell_type": "code", 1094 | "execution_count": 9, 1095 | "metadata": { 1096 | "collapsed": false, 1097 | "slideshow": { 1098 | "slide_type": "fragment" 1099 | } 1100 | }, 1101 | "outputs": [ 1102 | { 1103 | "name": "stdout", 1104 | "output_type": "stream", 1105 | "text": [ 1106 | "The slowest run took 7.40 times longer than the fastest. This could mean that an intermediate result is being cached \n", 1107 | "10000 loops, best of 3: 30.7 µs per loop\n" 1108 | ] 1109 | } 1110 | ], 1111 | "source": [ 1112 | "%%timeit\n", 1113 | "\n", 1114 | "import numpy as np\n", 1115 | "np.sum(np.random.rand(1000))" 1116 | ] 1117 | }, 1118 | { 1119 | "cell_type": "markdown", 1120 | "metadata": {}, 1121 | "source": [ 1122 | "### Execute Code as Python 2" 1123 | ] 1124 | }, 1125 | { 1126 | "cell_type": "code", 1127 | "execution_count": 10, 1128 | "metadata": { 1129 | "collapsed": false 1130 | }, 1131 | "outputs": [ 1132 | { 1133 | "name": "stdout", 1134 | "output_type": "stream", 1135 | "text": [ 1136 | "\n" 1137 | ] 1138 | } 1139 | ], 1140 | "source": [ 1141 | "%%python2\n", 1142 | "\n", 1143 | "i = 10**60\n", 1144 | "print type(i)" 1145 | ] 1146 | }, 1147 | { 1148 | "cell_type": "markdown", 1149 | "metadata": { 1150 | "slideshow": { 1151 | "slide_type": "slide" 1152 | } 1153 | }, 1154 | "source": [ 1155 | "### Interacting with the Command Line" 1156 | ] 1157 | }, 1158 | { 1159 | "cell_type": "markdown", 1160 | "metadata": { 1161 | "slideshow": { 1162 | "slide_type": "subslide" 1163 | } 1164 | }, 1165 | "source": [ 1166 | "IPython supports one final trick, the ability to interact directly with your shell by using the `!` operator." 1167 | ] 1168 | }, 1169 | { 1170 | "cell_type": "code", 1171 | "execution_count": 11, 1172 | "metadata": { 1173 | "collapsed": false, 1174 | "slideshow": { 1175 | "slide_type": "fragment" 1176 | } 1177 | }, 1178 | "outputs": [ 1179 | { 1180 | "name": "stdout", 1181 | "output_type": "stream", 1182 | "text": [ 1183 | "00 Programming Environment.ipynb\r\n", 1184 | "01 Hello World.ipynb\r\n", 1185 | "01 Introducing the IPython Notebook.ipynb\r\n", 1186 | "02 Variable Strings and Numbers.ipynb\r\n", 1187 | "03 List and Tuples.ipynb\r\n", 1188 | "04 If Statements.ipynb\r\n", 1189 | "05 While Loops and User input.ipynb\r\n", 1190 | "06 Dictionaries.ipynb\r\n", 1191 | "Index.ipynb\r\n", 1192 | "LICENSE\r\n", 1193 | "README.md\r\n", 1194 | "Resources and References.ipynb\r\n", 1195 | "TOC.ipynb\r\n", 1196 | "\u001b[34mfiles\u001b[m\u001b[m\r\n" 1197 | ] 1198 | } 1199 | ], 1200 | "source": [ 1201 | "!ls" 1202 | ] 1203 | }, 1204 | { 1205 | "cell_type": "code", 1206 | "execution_count": 12, 1207 | "metadata": { 1208 | "collapsed": false, 1209 | "slideshow": { 1210 | "slide_type": "fragment" 1211 | } 1212 | }, 1213 | "outputs": [], 1214 | "source": [ 1215 | "x = !ls" 1216 | ] 1217 | }, 1218 | { 1219 | "cell_type": "code", 1220 | "execution_count": 13, 1221 | "metadata": { 1222 | "collapsed": false, 1223 | "slideshow": { 1224 | "slide_type": "fragment" 1225 | } 1226 | }, 1227 | "outputs": [ 1228 | { 1229 | "name": "stdout", 1230 | "output_type": "stream", 1231 | "text": [ 1232 | "['00 Programming Environment.ipynb', '01 Hello World.ipynb', '01 Introducing the IPython Notebook.ipynb', '02 Variable Strings and Numbers.ipynb', '03 List and Tuples.ipynb', '04 If Statements.ipynb', '05 While Loops and User input.ipynb', '06 Dictionaries.ipynb', 'Index.ipynb', 'LICENSE', 'README.md', 'Resources and References.ipynb', 'TOC.ipynb', 'files']\n" 1233 | ] 1234 | } 1235 | ], 1236 | "source": [ 1237 | "print(x)" 1238 | ] 1239 | }, 1240 | { 1241 | "cell_type": "markdown", 1242 | "metadata": { 1243 | "slideshow": { 1244 | "slide_type": "slide" 1245 | } 1246 | }, 1247 | "source": [ 1248 | "## A Note about Notebook Version Control" 1249 | ] 1250 | }, 1251 | { 1252 | "cell_type": "markdown", 1253 | "metadata": { 1254 | "slideshow": { 1255 | "slide_type": "-" 1256 | } 1257 | }, 1258 | "source": [ 1259 | "The IPython Notebook is stored using canonicalized JSON for ease of use with version control systems.\n", 1260 | "\n", 1261 | "There are two things to be aware of:\n", 1262 | "\n", 1263 | "* By default, IPython embeds all content and saves kernel execution numbers. You may want to get in the habit of clearing all cells before committing.\n", 1264 | "\n", 1265 | "* As of IPython 2.0, all notebooks are signed on save. This increases the chances of a commit collision during merge, forcing a manual resolution. Either signature can be safely deleted in this situation." 1266 | ] 1267 | } 1268 | ], 1269 | "metadata": { 1270 | "kernelspec": { 1271 | "display_name": "Python 3", 1272 | "language": "python", 1273 | "name": "python3" 1274 | }, 1275 | "language_info": { 1276 | "codemirror_mode": { 1277 | "name": "ipython", 1278 | "version": 3 1279 | }, 1280 | "file_extension": ".py", 1281 | "mimetype": "text/x-python", 1282 | "name": "python", 1283 | "nbconvert_exporter": "python", 1284 | "pygments_lexer": "ipython3", 1285 | "version": "3.5.1" 1286 | } 1287 | }, 1288 | "nbformat": 4, 1289 | "nbformat_minor": 0 1290 | } 1291 | -------------------------------------------------------------------------------- /07 Introduction to Functions.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "slideshow": { 7 | "slide_type": "slide" 8 | } 9 | }, 10 | "source": [ 11 | "Introducing Functions\n", 12 | "===" 13 | ] 14 | }, 15 | { 16 | "cell_type": "markdown", 17 | "metadata": { 18 | "slideshow": { 19 | "slide_type": "subslide" 20 | } 21 | }, 22 | "source": [ 23 | "One of the core principles of any programming language is, \"Don't Repeat Yourself\". If you have an action that should occur many times, you can define that action once and then call that code whenever you need to carry out that action.\n", 24 | "\n", 25 | "We are already repeating ourselves in our code, so this is a good time to introduce simple functions. Functions mean less work for us as programmers, and effective use of functions results in code that is less error-prone." 26 | ] 27 | }, 28 | { 29 | "cell_type": "markdown", 30 | "metadata": { 31 | "slideshow": { 32 | "slide_type": "skip" 33 | } 34 | }, 35 | "source": [ 36 | "Contents\n", 37 | "===\n", 38 | "- [What are functions?](#what)\n", 39 | " - [General Syntax](#general_syntax)\n", 40 | "- [Examples](#examples)\n", 41 | " - [Returning a Value](#return_value)\n", 42 | " - [Exercises](#exercises)\n", 43 | "- [Challenges](#challenges)" 44 | ] 45 | }, 46 | { 47 | "cell_type": "markdown", 48 | "metadata": { 49 | "slideshow": { 50 | "slide_type": "slide" 51 | } 52 | }, 53 | "source": [ 54 | "What are functions?\n", 55 | "===\n", 56 | "Functions are a set of actions that we group together, and give a name to. You have already used a number of functions from the core Python language, such as *string.title()* and *list.sort()*. We can define our own functions, which allows us to \"teach\" Python new behavior." 57 | ] 58 | }, 59 | { 60 | "cell_type": "markdown", 61 | "metadata": { 62 | "slideshow": { 63 | "slide_type": "subslide" 64 | } 65 | }, 66 | "source": [ 67 | "General Syntax\n", 68 | "---\n", 69 | "A general function looks something like this:" 70 | ] 71 | }, 72 | { 73 | "cell_type": "code", 74 | "execution_count": null, 75 | "metadata": { 76 | "collapsed": false, 77 | "slideshow": { 78 | "slide_type": "fragment" 79 | } 80 | }, 81 | "outputs": [], 82 | "source": [ 83 | "# Let's define a function.\n", 84 | "def function_name(argument_1, argument_2):\n", 85 | " # Do whatever we want this function to do,\n", 86 | " # using argument_1 and argument_2\n", 87 | "\n", 88 | "# Use function_name to call the function.\n", 89 | "function_name(value_1, value_2)" 90 | ] 91 | }, 92 | { 93 | "cell_type": "markdown", 94 | "metadata": { 95 | "slideshow": { 96 | "slide_type": "subslide" 97 | } 98 | }, 99 | "source": [ 100 | "This code will not run, but it shows how functions are used in general." 101 | ] 102 | }, 103 | { 104 | "cell_type": "markdown", 105 | "metadata": { 106 | "slideshow": { 107 | "slide_type": "fragment" 108 | } 109 | }, 110 | "source": [ 111 | "- **Defining a function**\n", 112 | " - Give the keyword `def`, which tells Python that you are about to *define* a function.\n", 113 | " - Give your function a name. A variable name tells you what kind of value the variable contains; a function name should tell you what the function does.\n", 114 | " - Give names for each value the function needs in order to do its work.\n", 115 | " - These are basically variable names, but they are only used in the function.\n", 116 | " - They can be different names than what you use in the rest of your program.\n", 117 | " - These are called the function's *arguments*.\n", 118 | " - Make sure the function definition line ends with a colon.\n", 119 | " - Inside the function, write whatever code you need to make the function do its work." 120 | ] 121 | }, 122 | { 123 | "cell_type": "markdown", 124 | "metadata": { 125 | "slideshow": { 126 | "slide_type": "fragment" 127 | } 128 | }, 129 | "source": [ 130 | "- **Using your function**\n", 131 | " - To *call* your function, write its name followed by parentheses.\n", 132 | " - Inside the parentheses, give the values you want the function to work with.\n", 133 | " - These can be variables such as `current_name` and `current_age`, or they can be actual values such as 'eric' and 5." 134 | ] 135 | }, 136 | { 137 | "cell_type": "markdown", 138 | "metadata": { 139 | "slideshow": { 140 | "slide_type": "skip" 141 | } 142 | }, 143 | "source": [ 144 | "[top](#top)" 145 | ] 146 | }, 147 | { 148 | "cell_type": "markdown", 149 | "metadata": { 150 | "slideshow": { 151 | "slide_type": "slide" 152 | } 153 | }, 154 | "source": [ 155 | "Basic Examples\n", 156 | "===\n", 157 | "For a simple first example, we will look at a program that compliments people. Let's look at the example, and then try to understand the code. First we will look at a version of this program as we would have written it earlier, with no functions." 158 | ] 159 | }, 160 | { 161 | "cell_type": "code", 162 | "execution_count": 2, 163 | "metadata": { 164 | "collapsed": false, 165 | "slideshow": { 166 | "slide_type": "subslide" 167 | } 168 | }, 169 | "outputs": [ 170 | { 171 | "name": "stdout", 172 | "output_type": "stream", 173 | "text": [ 174 | "You are doing good work, Adriana!\n", 175 | "Thank you very much for your efforts on this project.\n", 176 | "\n", 177 | "You are doing good work, Billy!\n", 178 | "Thank you very much for your efforts on this project.\n", 179 | "\n", 180 | "You are doing good work, Caroline!\n", 181 | "Thank you very much for your efforts on this project.\n" 182 | ] 183 | } 184 | ], 185 | "source": [ 186 | "print(\"You are doing good work, Adriana!\")\n", 187 | "print(\"Thank you very much for your efforts on this project.\")\n", 188 | "\n", 189 | "print(\"\\nYou are doing good work, Billy!\")\n", 190 | "print(\"Thank you very much for your efforts on this project.\")\n", 191 | "\n", 192 | "print(\"\\nYou are doing good work, Caroline!\")\n", 193 | "print(\"Thank you very much for your efforts on this project.\")" 194 | ] 195 | }, 196 | { 197 | "cell_type": "markdown", 198 | "metadata": { 199 | "slideshow": { 200 | "slide_type": "subslide" 201 | } 202 | }, 203 | "source": [ 204 | "Functions take repeated code, put it in one place, and then you call that code when you want to use it. Here's what the same program looks like with a function." 205 | ] 206 | }, 207 | { 208 | "cell_type": "code", 209 | "execution_count": 4, 210 | "metadata": { 211 | "collapsed": false, 212 | "slideshow": { 213 | "slide_type": "fragment" 214 | } 215 | }, 216 | "outputs": [ 217 | { 218 | "name": "stdout", 219 | "output_type": "stream", 220 | "text": [ 221 | "\n", 222 | "You are doing good work, Adriana!\n", 223 | "Thank you very much for your efforts on this project.\n", 224 | "\n", 225 | "You are doing good work, Billy!\n", 226 | "Thank you very much for your efforts on this project.\n", 227 | "\n", 228 | "You are doing good work, Caroline!\n", 229 | "Thank you very much for your efforts on this project.\n" 230 | ] 231 | } 232 | ], 233 | "source": [ 234 | "def thank_you(name):\n", 235 | " # This function prints a two-line personalized thank you message.\n", 236 | " print(\"\\nYou are doing good work, %s!\" % name)\n", 237 | " print(\"Thank you very much for your efforts on this project.\")\n", 238 | " \n", 239 | "thank_you('Adriana')\n", 240 | "thank_you('Billy')\n", 241 | "thank_you('Caroline')" 242 | ] 243 | }, 244 | { 245 | "cell_type": "markdown", 246 | "metadata": { 247 | "slideshow": { 248 | "slide_type": "subslide" 249 | } 250 | }, 251 | "source": [ 252 | "In our original code, each pair of print statements was run three times, and the only difference was the name of the person being thanked. When you see repetition like this, you can usually make your program more efficient by defining a function." 253 | ] 254 | }, 255 | { 256 | "cell_type": "markdown", 257 | "metadata": { 258 | "slideshow": { 259 | "slide_type": "fragment" 260 | } 261 | }, 262 | "source": [ 263 | "The keyword *def* tells Python that we are about to define a function. We give our function a name, *thank\\_you()* in this case. A variable's name should tell us what kind of information it holds; a function's name should tell us what the variable does. We then put parentheses. Inside these parenthese we create variable names for any variable the function will need to be given in order to do its job. In this case the function will need a name to include in the thank you message. The variable `name` will hold the value that is passed into the function *thank\\_you()*." 264 | ] 265 | }, 266 | { 267 | "cell_type": "markdown", 268 | "metadata": { 269 | "slideshow": { 270 | "slide_type": "fragment" 271 | } 272 | }, 273 | "source": [ 274 | "To use a function we give the function's name, and then put any values the function needs in order to do its work. In this case we call the function three times, each time passing it a different name." 275 | ] 276 | }, 277 | { 278 | "cell_type": "markdown", 279 | "metadata": { 280 | "slideshow": { 281 | "slide_type": "subslide" 282 | } 283 | }, 284 | "source": [ 285 | "### A common error\n", 286 | "A function must be defined before you use it in your program. For example, putting the function at the end of the program would not work." 287 | ] 288 | }, 289 | { 290 | "cell_type": "code", 291 | "execution_count": 1, 292 | "metadata": { 293 | "collapsed": false, 294 | "slideshow": { 295 | "slide_type": "fragment" 296 | } 297 | }, 298 | "outputs": [ 299 | { 300 | "ename": "NameError", 301 | "evalue": "name 'thank_you' is not defined", 302 | "output_type": "error", 303 | "traceback": [ 304 | "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)", 305 | "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0mthank_you\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m'Adriana'\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 2\u001b[0m \u001b[0mthank_you\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m'Billy'\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 3\u001b[0m \u001b[0mthank_you\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m'Caroline'\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 4\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 5\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0mthank_you\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mname\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", 306 | "\u001b[1;31mNameError\u001b[0m: name 'thank_you' is not defined" 307 | ] 308 | } 309 | ], 310 | "source": [ 311 | "thank_you('Adriana')\n", 312 | "thank_you('Billy')\n", 313 | "thank_you('Caroline')\n", 314 | "\n", 315 | "def thank_you(name):\n", 316 | " # This function prints a two-line personalized thank you message.\n", 317 | " print(\"\\nYou are doing good work, %s!\" % name)\n", 318 | " print(\"Thank you very much for your efforts on this project.\")" 319 | ] 320 | }, 321 | { 322 | "cell_type": "markdown", 323 | "metadata": { 324 | "slideshow": { 325 | "slide_type": "fragment" 326 | } 327 | }, 328 | "source": [ 329 | "On the first line we ask Python to run the function *thank\\_you()*, but Python does not yet know how to do this function. We define our functions at the beginning of our programs, and then we can use them when we need to." 330 | ] 331 | }, 332 | { 333 | "cell_type": "markdown", 334 | "metadata": { 335 | "slideshow": { 336 | "slide_type": "subslide" 337 | } 338 | }, 339 | "source": [ 340 | "A second example\n", 341 | "---\n", 342 | "When we introduced the different methods for [sorting a list](http://nbviewer.ipython.org/urls/raw.github.com/ehmatthes/intro_programming/master/notebooks/lists_tuples.ipynb#sorting_list), our code got very repetitive. It takes two lines of code to print a list using a for loop, so these two lines are repeated whenever you want to print out the contents of a list. This is the perfect opportunity to use a function, so let's see how the code looks with a function.\n", 343 | "\n", 344 | "First, let's see the code we had without a function:" 345 | ] 346 | }, 347 | { 348 | "cell_type": "code", 349 | "execution_count": 3, 350 | "metadata": { 351 | "collapsed": false, 352 | "slideshow": { 353 | "slide_type": "fragment" 354 | } 355 | }, 356 | "outputs": [ 357 | { 358 | "name": "stdout", 359 | "output_type": "stream", 360 | "text": [ 361 | "Our students are currently in alphabetical order.\n", 362 | "Aaron\n", 363 | "Bernice\n", 364 | "Cody\n", 365 | "\n", 366 | "Our students are now in reverse alphabetical order.\n", 367 | "Cody\n", 368 | "Bernice\n", 369 | "Aaron\n" 370 | ] 371 | } 372 | ], 373 | "source": [ 374 | "students = ['bernice', 'aaron', 'cody']\n", 375 | "\n", 376 | "# Put students in alphabetical order.\n", 377 | "students.sort()\n", 378 | "\n", 379 | "# Display the list in its current order.\n", 380 | "print(\"Our students are currently in alphabetical order.\")\n", 381 | "for student in students:\n", 382 | " print(student.title())\n", 383 | "\n", 384 | "# Put students in reverse alphabetical order.\n", 385 | "students.sort(reverse=True)\n", 386 | "\n", 387 | "# Display the list in its current order.\n", 388 | "print(\"\\nOur students are now in reverse alphabetical order.\")\n", 389 | "for student in students:\n", 390 | " print(student.title())" 391 | ] 392 | }, 393 | { 394 | "cell_type": "markdown", 395 | "metadata": { 396 | "slideshow": { 397 | "slide_type": "subslide" 398 | } 399 | }, 400 | "source": [ 401 | "Here's what the same code looks like, using a function to print out the list:" 402 | ] 403 | }, 404 | { 405 | "cell_type": "code", 406 | "execution_count": 9, 407 | "metadata": { 408 | "collapsed": false, 409 | "slideshow": { 410 | "slide_type": "fragment" 411 | } 412 | }, 413 | "outputs": [ 414 | { 415 | "name": "stdout", 416 | "output_type": "stream", 417 | "text": [ 418 | "Our students are currently in alphabetical order.\n", 419 | "Aaron\n", 420 | "Bernice\n", 421 | "Cody\n", 422 | "\n", 423 | "Our students are now in reverse alphabetical order.\n", 424 | "Cody\n", 425 | "Bernice\n", 426 | "Aaron\n" 427 | ] 428 | } 429 | ], 430 | "source": [ 431 | "def show_students(students, message):\n", 432 | " # Print out a message, and then the list of students\n", 433 | " print(message)\n", 434 | " for student in students:\n", 435 | " print(student.title())\n", 436 | "\n", 437 | "students = ['bernice', 'aaron', 'cody']\n", 438 | "\n", 439 | "# Put students in alphabetical order.\n", 440 | "students.sort()\n", 441 | "show_students(students, \"Our students are currently in alphabetical order.\")\n", 442 | "\n", 443 | "#Put students in reverse alphabetical order.\n", 444 | "students.sort(reverse=True)\n", 445 | "show_students(students, \"\\nOur students are now in reverse alphabetical order.\")" 446 | ] 447 | }, 448 | { 449 | "cell_type": "markdown", 450 | "metadata": { 451 | "slideshow": { 452 | "slide_type": "subslide" 453 | } 454 | }, 455 | "source": [ 456 | "This is much cleaner code. We have an action we want to take, which is to show the students in our list along with a message. We give this action a name, *show\\_students()*. \n", 457 | "\n", 458 | "This function needs two pieces of information to do its work, the list of students and a message to display. Inside the function, the code for printing the message and looping through the list is exactly as it was in the non-function code.\n", 459 | "\n", 460 | "Now the rest of our program is cleaner, because it gets to focus on the things we are changing in the list, rather than having code for printing the list. We define the list, then we sort it and call our function to print the list. We sort it again, and then call the printing function a second time, with a different message. This is much more readable code." 461 | ] 462 | }, 463 | { 464 | "cell_type": "markdown", 465 | "metadata": { 466 | "slideshow": { 467 | "slide_type": "subslide" 468 | } 469 | }, 470 | "source": [ 471 | "### Advantages of using functions\n", 472 | "You might be able to see some advantages of using functions, through this example:\n", 473 | "\n", 474 | "- We write a set of instructions once. We save some work in this simple example, and we save even more work in larger programs." 475 | ] 476 | }, 477 | { 478 | "cell_type": "markdown", 479 | "metadata": { 480 | "slideshow": { 481 | "slide_type": "fragment" 482 | } 483 | }, 484 | "source": [ 485 | "- When our function works, we don't have to worry about that code anymore. Every time you repeat code in your program, you introduce an opportunity to make a mistake. Writing a function means there is one place to fix mistakes, and when those bugs are fixed, we can be confident that this function will continue to work correctly." 486 | ] 487 | }, 488 | { 489 | "cell_type": "markdown", 490 | "metadata": { 491 | "slideshow": { 492 | "slide_type": "fragment" 493 | } 494 | }, 495 | "source": [ 496 | "- We can modify our function's behavior, and that change takes effect every time the function is called. This is much better than deciding we need some new behavior, and then having to change code in many different places in our program." 497 | ] 498 | }, 499 | { 500 | "cell_type": "markdown", 501 | "metadata": { 502 | "slideshow": { 503 | "slide_type": "subslide" 504 | } 505 | }, 506 | "source": [ 507 | "For a quick example, let's say we decide our printed output would look better with some form of a bulleted list. Without functions, we'd have to change each print statement. With a function, we change just the print statement in the function:" 508 | ] 509 | }, 510 | { 511 | "cell_type": "code", 512 | "execution_count": 10, 513 | "metadata": { 514 | "collapsed": false, 515 | "slideshow": { 516 | "slide_type": "fragment" 517 | } 518 | }, 519 | "outputs": [ 520 | { 521 | "name": "stdout", 522 | "output_type": "stream", 523 | "text": [ 524 | "Our students are currently in alphabetical order.\n", 525 | "- Aaron\n", 526 | "- Bernice\n", 527 | "- Cody\n", 528 | "\n", 529 | "Our students are now in reverse alphabetical order.\n", 530 | "- Cody\n", 531 | "- Bernice\n", 532 | "- Aaron\n" 533 | ] 534 | } 535 | ], 536 | "source": [ 537 | "def show_students(students, message):\n", 538 | " # Print out a message, and then the list of students\n", 539 | " print(message)\n", 540 | " for student in students:\n", 541 | " print(\"- \" + student.title())\n", 542 | "\n", 543 | "students = ['bernice', 'aaron', 'cody']\n", 544 | "\n", 545 | "# Put students in alphabetical order.\n", 546 | "students.sort()\n", 547 | "show_students(students, \"Our students are currently in alphabetical order.\")\n", 548 | "\n", 549 | "#Put students in reverse alphabetical order.\n", 550 | "students.sort(reverse=True)\n", 551 | "show_students(students, \"\\nOur students are now in reverse alphabetical order.\")" 552 | ] 553 | }, 554 | { 555 | "cell_type": "markdown", 556 | "metadata": { 557 | "slideshow": { 558 | "slide_type": "fragment" 559 | } 560 | }, 561 | "source": [ 562 | "You can think of functions as a way to \"teach\" Python some new behavior. In this case, we taught Python how to create a list of students using hyphens; now we can tell Python to do this with our students whenever we want to." 563 | ] 564 | }, 565 | { 566 | "cell_type": "markdown", 567 | "metadata": { 568 | "slideshow": { 569 | "slide_type": "subslide" 570 | } 571 | }, 572 | "source": [ 573 | "Returning a Value\n", 574 | "---\n", 575 | "Each function you create can return a value. This can be in addition to the primary work the function does, or it can be the function's main job. The following function takes in a number, and returns the corresponding word for that number:" 576 | ] 577 | }, 578 | { 579 | "cell_type": "code", 580 | "execution_count": 3, 581 | "metadata": { 582 | "collapsed": false, 583 | "slideshow": { 584 | "slide_type": "fragment" 585 | } 586 | }, 587 | "outputs": [ 588 | { 589 | "name": "stdout", 590 | "output_type": "stream", 591 | "text": [ 592 | "0 None\n", 593 | "1 one\n", 594 | "2 two\n", 595 | "3 three\n" 596 | ] 597 | } 598 | ], 599 | "source": [ 600 | "def get_number_word(number):\n", 601 | " # Takes in a numerical value, and returns\n", 602 | " # the word corresponding to that number.\n", 603 | " if number == 1:\n", 604 | " return 'one'\n", 605 | " elif number == 2:\n", 606 | " return 'two'\n", 607 | " elif number == 3:\n", 608 | " return 'three'\n", 609 | " # ...\n", 610 | " \n", 611 | "# Let's try out our function.\n", 612 | "for current_number in range(0,4):\n", 613 | " number_word = get_number_word(current_number)\n", 614 | " print(current_number, number_word)" 615 | ] 616 | }, 617 | { 618 | "cell_type": "markdown", 619 | "metadata": { 620 | "slideshow": { 621 | "slide_type": "fragment" 622 | } 623 | }, 624 | "source": [ 625 | "It's helpful sometimes to see programs that don't quite work as they are supposed to, and then see how those programs can be improved. In this case, there are no Python errors; all of the code has proper Python syntax. But there is a logical error, in the first line of the output." 626 | ] 627 | }, 628 | { 629 | "cell_type": "markdown", 630 | "metadata": { 631 | "slideshow": { 632 | "slide_type": "subslide" 633 | } 634 | }, 635 | "source": [ 636 | "We want to either not include 0 in the range we send to the function, or have the function return something other than `None` when it receives a value that it doesn't know. Let's teach our function the word 'zero', but let's also add an `else` clause that returns a more informative message for numbers that are not in the if-chain.m" 637 | ] 638 | }, 639 | { 640 | "cell_type": "code", 641 | "execution_count": 5, 642 | "metadata": { 643 | "collapsed": false, 644 | "slideshow": { 645 | "slide_type": "fragment" 646 | } 647 | }, 648 | "outputs": [ 649 | { 650 | "name": "stdout", 651 | "output_type": "stream", 652 | "text": [ 653 | "0 zero\n", 654 | "1 one\n", 655 | "2 two\n", 656 | "3 three\n", 657 | "4 I'm sorry, I don't know that number.\n", 658 | "5 I'm sorry, I don't know that number.\n" 659 | ] 660 | } 661 | ], 662 | "source": [ 663 | "def get_number_word(number):\n", 664 | " # Takes in a numerical value, and returns\n", 665 | " # the word corresponding to that number.\n", 666 | " if number == 0:\n", 667 | " return 'zero'\n", 668 | " elif number == 1:\n", 669 | " return 'one'\n", 670 | " elif number == 2:\n", 671 | " return 'two'\n", 672 | " elif number == 3:\n", 673 | " return 'three'\n", 674 | " else:\n", 675 | " return \"I'm sorry, I don't know that number.\"\n", 676 | " \n", 677 | "# Let's try out our function.\n", 678 | "for current_number in range(0,6):\n", 679 | " number_word = get_number_word(current_number)\n", 680 | " print(current_number, number_word)" 681 | ] 682 | }, 683 | { 684 | "cell_type": "markdown", 685 | "metadata": { 686 | "slideshow": { 687 | "slide_type": "subslide" 688 | } 689 | }, 690 | "source": [ 691 | "If you use a return statement in one of your functions, keep in mind that the function stops executing as soon as it hits a return statement. For example, we can add a line to the *get\\_number\\_word()* function that will never execute, because it comes after the function has returned a value:" 692 | ] 693 | }, 694 | { 695 | "cell_type": "code", 696 | "execution_count": 7, 697 | "metadata": { 698 | "collapsed": false, 699 | "slideshow": { 700 | "slide_type": "fragment" 701 | } 702 | }, 703 | "outputs": [ 704 | { 705 | "name": "stdout", 706 | "output_type": "stream", 707 | "text": [ 708 | "0 zero\n", 709 | "1 one\n", 710 | "2 two\n", 711 | "3 three\n", 712 | "4 I'm sorry, I don't know that number.\n", 713 | "5 I'm sorry, I don't know that number.\n" 714 | ] 715 | } 716 | ], 717 | "source": [ 718 | "def get_number_word(number):\n", 719 | " # Takes in a numerical value, and returns\n", 720 | " # the word corresponding to that number.\n", 721 | " if number == 0:\n", 722 | " return 'zero'\n", 723 | " elif number == 1:\n", 724 | " return 'one'\n", 725 | " elif number == 2:\n", 726 | " return 'two'\n", 727 | " elif number == 3:\n", 728 | " return 'three'\n", 729 | " else:\n", 730 | " return \"I'm sorry, I don't know that number.\"\n", 731 | " \n", 732 | " # This line will never execute, because the function has already\n", 733 | " # returned a value and stopped executing.\n", 734 | " print(\"This message will never be printed.\")\n", 735 | " \n", 736 | "# Let's try out our function.\n", 737 | "for current_number in range(0,6):\n", 738 | " number_word = get_number_word(current_number)\n", 739 | " print(current_number, number_word)" 740 | ] 741 | }, 742 | { 743 | "cell_type": "markdown", 744 | "metadata": { 745 | "slideshow": { 746 | "slide_type": "subslide" 747 | } 748 | }, 749 | "source": [ 750 | "More Later\n", 751 | "---\n", 752 | "There is much more to learn about functions, but we will get to those details later. For now, feel free to use functions whenever you find yourself writing the same code several times in a program. Some of the things you will learn when we focus on functions:\n", 753 | "\n", 754 | "- How to give the arguments in your function default values.\n", 755 | "- How to let your functions accept different numbers of arguments." 756 | ] 757 | }, 758 | { 759 | "cell_type": "markdown", 760 | "metadata": { 761 | "slideshow": { 762 | "slide_type": "skip" 763 | } 764 | }, 765 | "source": [ 766 | "[top](#top)" 767 | ] 768 | }, 769 | { 770 | "cell_type": "markdown", 771 | "metadata": {}, 772 | "source": [ 773 | "Exercises\n", 774 | "---\n", 775 | "#### Greeter\n", 776 | "- Write a function that takes in a person's name, and prints out a greeting.\n", 777 | " - The greeting must be at least three lines, and the person's name must be in each line.\n", 778 | "- Use your function to greet at least three different people.\n", 779 | "- **Bonus:** Store your three people in a list, and call your function from a `for` loop.\n", 780 | "\n", 781 | "#### Full Names\n", 782 | "- Write a function that takes in a first name and a last name, and prints out a nicely formatted full name, in a sentence. Your sentence could be as simple as, \"Hello, *full\\_name*.\"\n", 783 | "- Call your function three times, with a different name each time.\n", 784 | "\n", 785 | "#### Addition Calculator\n", 786 | "- Write a function that takes in two numbers, and adds them together. Make your function print out a sentence showing the two numbers, and the result.\n", 787 | "- Call your function with three different sets of numbers.\n", 788 | "\n", 789 | "#### Return Calculator\n", 790 | "- Modify *Addition Calculator* so that your function returns the sum of the two numbers. The printing should happen outside of the function.\n", 791 | "\n", 792 | "#### List Exercises - Functions\n", 793 | "- Go back and solve each of the following exercises from the section on [Lists and Tuples](http://nbviewer.ipython.org/urls/raw.github.com/ehmatthes/intro_programming/master/notebooks/lists_tuples.ipynb), using functions to avoid repetetive code:\n", 794 | " - [Ordered Working List](http://nbviewer.ipython.org/urls/raw.github.com/ehmatthes/intro_programming/master/notebooks/lists_tuples.ipynb#exercises_common_operations)\n", 795 | " - [Ordered Numbers](http://nbviewer.ipython.org/urls/raw.github.com/ehmatthes/intro_programming/master/notebooks/lists_tuples.ipynb#exercises_common_operations)\n", 796 | "\n" 797 | ] 798 | }, 799 | { 800 | "cell_type": "code", 801 | "execution_count": null, 802 | "metadata": { 803 | "collapsed": false, 804 | "slideshow": { 805 | "slide_type": "skip" 806 | } 807 | }, 808 | "outputs": [], 809 | "source": [ 810 | "# Ex 4.1 : Greeter\n", 811 | "\n", 812 | "# put your code here" 813 | ] 814 | }, 815 | { 816 | "cell_type": "code", 817 | "execution_count": null, 818 | "metadata": { 819 | "collapsed": false, 820 | "slideshow": { 821 | "slide_type": "skip" 822 | } 823 | }, 824 | "outputs": [], 825 | "source": [ 826 | "# Ex 4.2 : Full Names\n", 827 | "\n", 828 | "# put your code here" 829 | ] 830 | }, 831 | { 832 | "cell_type": "code", 833 | "execution_count": null, 834 | "metadata": { 835 | "collapsed": false, 836 | "slideshow": { 837 | "slide_type": "skip" 838 | } 839 | }, 840 | "outputs": [], 841 | "source": [ 842 | "# Ex 4.3 : Addition Calculator\n", 843 | "\n", 844 | "# put your code here" 845 | ] 846 | }, 847 | { 848 | "cell_type": "code", 849 | "execution_count": null, 850 | "metadata": { 851 | "collapsed": false, 852 | "slideshow": { 853 | "slide_type": "skip" 854 | } 855 | }, 856 | "outputs": [], 857 | "source": [ 858 | "# Ex 4.4 : Return Calculator\n", 859 | "\n", 860 | "# put your code here" 861 | ] 862 | }, 863 | { 864 | "cell_type": "code", 865 | "execution_count": null, 866 | "metadata": { 867 | "collapsed": false, 868 | "slideshow": { 869 | "slide_type": "skip" 870 | } 871 | }, 872 | "outputs": [], 873 | "source": [ 874 | "# Ex 4.5 : List Exercises - Functions\n", 875 | "\n", 876 | "# put your code here" 877 | ] 878 | }, 879 | { 880 | "cell_type": "markdown", 881 | "metadata": { 882 | "slideshow": { 883 | "slide_type": "skip" 884 | } 885 | }, 886 | "source": [ 887 | "[top](#top)" 888 | ] 889 | }, 890 | { 891 | "cell_type": "markdown", 892 | "metadata": { 893 | "slideshow": { 894 | "slide_type": "skip" 895 | } 896 | }, 897 | "source": [ 898 | "Challenges\n", 899 | "---\n", 900 | "#### Lyrics\n", 901 | "- Many songs follow a familiar variation of the pattern of *verse*, *refrain*, *verse*, *refrain*. The verses are the parts of the song that tell a story - they are not repeated in the song. The refrain is the part of the song that is repeated throughout the song.\n", 902 | "- Find the lyrics to a [song you like](http://www.metrolyrics.com/dont-stop-believin-lyrics-journey.html) that follows this pattern. Write a program that prints out the lyrics to this song, using as few lines of Python code as possible. [hint](#hint_challenges_lyrics)" 903 | ] 904 | }, 905 | { 906 | "cell_type": "code", 907 | "execution_count": null, 908 | "metadata": { 909 | "collapsed": false, 910 | "slideshow": { 911 | "slide_type": "skip" 912 | } 913 | }, 914 | "outputs": [], 915 | "source": [ 916 | "# Challenge: Lyrics\n", 917 | "\n", 918 | "# Put your code here" 919 | ] 920 | }, 921 | { 922 | "cell_type": "markdown", 923 | "metadata": { 924 | "slideshow": { 925 | "slide_type": "skip" 926 | } 927 | }, 928 | "source": [ 929 | "[top](#top)" 930 | ] 931 | }, 932 | { 933 | "cell_type": "markdown", 934 | "metadata": { 935 | "slideshow": { 936 | "slide_type": "skip" 937 | } 938 | }, 939 | "source": [ 940 | "Hints\n", 941 | "===\n", 942 | "These are placed at the bottom, so you can have a chance to solve exercises without seeing any hints.\n", 943 | "\n", 944 | "#### Lyrics\n", 945 | "- Define a function that prints out the lyrics of the refrain. Use this function any time the refrain comes up in the song." 946 | ] 947 | } 948 | ], 949 | "metadata": { 950 | "kernelspec": { 951 | "display_name": "Python 3", 952 | "language": "python", 953 | "name": "python3" 954 | }, 955 | "language_info": { 956 | "codemirror_mode": { 957 | "name": "ipython", 958 | "version": 3 959 | }, 960 | "file_extension": ".py", 961 | "mimetype": "text/x-python", 962 | "name": "python", 963 | "nbconvert_exporter": "python", 964 | "pygments_lexer": "ipython3", 965 | "version": "3.5.1" 966 | } 967 | }, 968 | "nbformat": 4, 969 | "nbformat_minor": 0 970 | } 971 | -------------------------------------------------------------------------------- /09 Exceptions.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Exceptions" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "Exceptions which are events that can modify the *flow* of control through a program. \n", 15 | "\n", 16 | "In Python, exceptions are triggered automatically on errors, and they can be triggered and intercepted by your code.\n", 17 | "\n", 18 | "They are processed by **four** statements we’ll study in this notebook, the first of which has two variations (listed separately here) and the last of which was an optional extension until Python 2.6 and 3.0:\n", 19 | "\n", 20 | "* `try/except`:\n", 21 | " * Catch and recover from exceptions raised by Python, or by you\n", 22 | " \n", 23 | "* `try/finally`:\n", 24 | " * Perform cleanup actions, whether exceptions occur or not.\n", 25 | "\n", 26 | "* `raise`:\n", 27 | " * Trigger an exception manually in your code.\n", 28 | " \n", 29 | "* `assert`:\n", 30 | " * Conditionally trigger an exception in your code.\n", 31 | " \n", 32 | "* `with/as`:\n", 33 | " * Implement context managers in Python 2.6, 3.0, and later (optional in 2.5)." 34 | ] 35 | }, 36 | { 37 | "cell_type": "markdown", 38 | "metadata": {}, 39 | "source": [ 40 | "# `try/except` Statement" 41 | ] 42 | }, 43 | { 44 | "cell_type": "markdown", 45 | "metadata": {}, 46 | "source": [ 47 | "```\n", 48 | "try:\n", 49 | " statements # Run this main action first\n", 50 | "except name1: \n", 51 | " # Run if name1 is raised during try block\n", 52 | " statements\n", 53 | "except (name2, name3): \n", 54 | " # Run if any of these exceptions occur\n", 55 | " statements \n", 56 | "except name4 as var: \n", 57 | " # Run if name4 is raised, assign instance raised to var \n", 58 | " statements\n", 59 | "except: # Run for all other exceptions raised\n", 60 | " statements\n", 61 | "else:\n", 62 | " statements # Run if no exception was raised during try block\n", 63 | "```" 64 | ] 65 | }, 66 | { 67 | "cell_type": "code", 68 | "execution_count": 1, 69 | "metadata": { 70 | "collapsed": false, 71 | "scrolled": true 72 | }, 73 | "outputs": [ 74 | { 75 | "name": "stdout", 76 | "output_type": "stream", 77 | "text": [ 78 | "[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99]\n" 79 | ] 80 | } 81 | ], 82 | "source": [ 83 | "list_of_numbers = [number for number in range(1, 100)]\n", 84 | "print(list_of_numbers)" 85 | ] 86 | }, 87 | { 88 | "cell_type": "code", 89 | "execution_count": 10, 90 | "metadata": { 91 | "collapsed": false 92 | }, 93 | "outputs": [ 94 | { 95 | "name": "stdout", 96 | "output_type": "stream", 97 | "text": [ 98 | "Getting number at position 1 : 1\n", 99 | "Cleaning UP\n" 100 | ] 101 | } 102 | ], 103 | "source": [ 104 | "dictionary_of_numbers = {}\n", 105 | "for number in list_of_numbers:\n", 106 | " dictionary_of_numbers[number**2] = number\n", 107 | " \n", 108 | "try:\n", 109 | " index = list_of_numbers.index(2)\n", 110 | " value = dictionary_of_numbers[index]\n", 111 | "except (ValueError, KeyError):\n", 112 | " print('Error Raised, but Controlled! ')\n", 113 | "else: \n", 114 | " # This executes ONLY if no exception is raised\n", 115 | " print('Getting number at position %d : %d' % (index, value))\n", 116 | "finally:\n", 117 | " # Do cleanup operations\n", 118 | " print('Cleaning UP')" 119 | ] 120 | }, 121 | { 122 | "cell_type": "markdown", 123 | "metadata": {}, 124 | "source": [ 125 | "# `try/finally` Statement" 126 | ] 127 | }, 128 | { 129 | "cell_type": "markdown", 130 | "metadata": {}, 131 | "source": [ 132 | "The other flavor of the try statement is a specialization that has to do with finalization (a.k.a. termination) actions. If a finally clause is included in a try, Python will always run its block of statements “on the way out” of the try statement, whether an exception occurred while the try block was running or not. \n", 133 | "\n", 134 | "In it's general form, it is:\n", 135 | "\n", 136 | "```\n", 137 | "try:\n", 138 | " statements # Run this action first \n", 139 | "finally:\n", 140 | " statements # Always run this code on the way out\n", 141 | "```" 142 | ] 143 | }, 144 | { 145 | "cell_type": "markdown", 146 | "metadata": {}, 147 | "source": [ 148 | "" 149 | ] 150 | }, 151 | { 152 | "cell_type": "markdown", 153 | "metadata": {}, 154 | "source": [ 155 | "# `with/as` Context Managers" 156 | ] 157 | }, 158 | { 159 | "cell_type": "markdown", 160 | "metadata": {}, 161 | "source": [ 162 | "Python 2.6 and 3.0 introduced a new exception-related statement—the with, and its optional as clause. This statement is designed to work with context manager objects, which support a new method-based protocol, similar in spirit to the way that iteration tools work with methods of the iteration protocol. " 163 | ] 164 | }, 165 | { 166 | "cell_type": "markdown", 167 | "metadata": {}, 168 | "source": [ 169 | "## Context Manager Intro" 170 | ] 171 | }, 172 | { 173 | "cell_type": "markdown", 174 | "metadata": {}, 175 | "source": [ 176 | "### Basic Usage:\n", 177 | "\n", 178 | "```\n", 179 | "with expression [as variable]: \n", 180 | " with-block\n", 181 | "```" 182 | ] 183 | }, 184 | { 185 | "cell_type": "markdown", 186 | "metadata": {}, 187 | "source": [ 188 | "### Classical Usage\n", 189 | "\n", 190 | "```python\n", 191 | "\n", 192 | "with open(r'C:\\misc\\data') as myfile: \n", 193 | " for line in myfile:\n", 194 | " print(line)\n", 195 | " # ...more code here...\n", 196 | "```\n", 197 | "\n", 198 | "... even using multiple context managers:\n", 199 | "\n", 200 | "```python\n", 201 | "with open('script1.py') as f1, open('script2.py') as f2: \n", 202 | " for (linenum, (line1, line2)) in enumerate(zip(f1, f2)):\n", 203 | " if line1 != line2:\n", 204 | " print('%s\\n%r\\n%r' % (linenum, line1, line2))\n", 205 | "```" 206 | ] 207 | }, 208 | { 209 | "cell_type": "markdown", 210 | "metadata": {}, 211 | "source": [ 212 | "### How it works\n", 213 | "\n", 214 | "1. The expression is evaluated,resulting in an object known as a **context manager** that must have `__enter__` and `__exit__` methods\n", 215 | "\n", 216 | "2. The context manager’s `__enter__` method is called. The value it returns is assigned to the variable in the as clause if present, or simply discarded otherwise\n", 217 | "\n", 218 | "3. The code in the nested with block is executed.\n", 219 | "\n", 220 | "4. If the with block raises an exception, the `__exit__(type,value,traceback)` method is called with the exception details. These are the same three values returned by `sys.exc_info` (Python function). If this method returns a `false` value, the exception is **re-raised**; otherwise, the exception is terminated. The exception should normally be reraised so that it is propagated outside the with statement.\n", 221 | "\n", 222 | "5. If the with block does not raise an exception, the `__exit__` method is still called, but its type, value, and traceback arguments are all passed in as `None`." 223 | ] 224 | }, 225 | { 226 | "cell_type": "markdown", 227 | "metadata": {}, 228 | "source": [ 229 | "## Usage with Exceptions" 230 | ] 231 | }, 232 | { 233 | "cell_type": "code", 234 | "execution_count": 4, 235 | "metadata": { 236 | "collapsed": true 237 | }, 238 | "outputs": [], 239 | "source": [ 240 | "class TraceBlock:\n", 241 | " def message(self, arg):\n", 242 | " print('running ' + arg) \n", 243 | " \n", 244 | " def __enter__(self):\n", 245 | " print('starting with block')\n", 246 | " return self\n", 247 | " \n", 248 | " def __exit__(self, exc_type, exc_value, exc_tb):\n", 249 | " if exc_type is None: \n", 250 | " print('exited normally\\n')\n", 251 | " else:\n", 252 | " print('raise an exception! ' + str(exc_type)) \n", 253 | " return False # Propagate" 254 | ] 255 | }, 256 | { 257 | "cell_type": "code", 258 | "execution_count": 5, 259 | "metadata": { 260 | "collapsed": false 261 | }, 262 | "outputs": [ 263 | { 264 | "name": "stdout", 265 | "output_type": "stream", 266 | "text": [ 267 | "starting with block\n", 268 | "running test 1\n", 269 | "reached\n", 270 | "exited normally\n", 271 | "\n" 272 | ] 273 | } 274 | ], 275 | "source": [ 276 | "with TraceBlock() as action: \n", 277 | " action.message('test 1')\n", 278 | " print('reached')" 279 | ] 280 | }, 281 | { 282 | "cell_type": "code", 283 | "execution_count": 6, 284 | "metadata": { 285 | "collapsed": false 286 | }, 287 | "outputs": [ 288 | { 289 | "name": "stdout", 290 | "output_type": "stream", 291 | "text": [ 292 | "starting with block\n", 293 | "running test 2\n", 294 | "raise an exception! \n" 295 | ] 296 | }, 297 | { 298 | "ename": "TypeError", 299 | "evalue": "", 300 | "output_type": "error", 301 | "traceback": [ 302 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", 303 | "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", 304 | "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;32mwith\u001b[0m \u001b[0mTraceBlock\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0maction\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0maction\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmessage\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'test 2'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 3\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mTypeError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 4\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'not reached'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", 305 | "\u001b[0;31mTypeError\u001b[0m: " 306 | ] 307 | } 308 | ], 309 | "source": [ 310 | "with TraceBlock() as action: \n", 311 | " action.message('test 2') \n", 312 | " raise TypeError()\n", 313 | " print('not reached')" 314 | ] 315 | }, 316 | { 317 | "cell_type": "markdown", 318 | "metadata": {}, 319 | "source": [ 320 | "## User Defined Exceptions" 321 | ] 322 | }, 323 | { 324 | "cell_type": "code", 325 | "execution_count": 1, 326 | "metadata": { 327 | "collapsed": true 328 | }, 329 | "outputs": [], 330 | "source": [ 331 | "class AlreadyGotOne(Exception): \n", 332 | " pass\n", 333 | "\n", 334 | "def gail():\n", 335 | " raise AlreadyGotOne()" 336 | ] 337 | }, 338 | { 339 | "cell_type": "code", 340 | "execution_count": 2, 341 | "metadata": { 342 | "collapsed": false 343 | }, 344 | "outputs": [ 345 | { 346 | "name": "stdout", 347 | "output_type": "stream", 348 | "text": [ 349 | "got exception\n" 350 | ] 351 | } 352 | ], 353 | "source": [ 354 | "try:\n", 355 | " gail()\n", 356 | "except AlreadyGotOne:\n", 357 | " print('got exception')" 358 | ] 359 | }, 360 | { 361 | "cell_type": "code", 362 | "execution_count": 2, 363 | "metadata": { 364 | "collapsed": false, 365 | "scrolled": true 366 | }, 367 | "outputs": [ 368 | { 369 | "ename": "Career", 370 | "evalue": "So I became a waiter of Engineer", 371 | "output_type": "error", 372 | "traceback": [ 373 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", 374 | "\u001b[0;31mCareer\u001b[0m Traceback (most recent call last)", 375 | "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 8\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0;34m'So I became a waiter of {}'\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mformat\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_job\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 9\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 10\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mCareer\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'Engineer'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", 376 | "\u001b[0;31mCareer\u001b[0m: So I became a waiter of Engineer" 377 | ] 378 | } 379 | ], 380 | "source": [ 381 | "class Career(Exception):\n", 382 | " \n", 383 | " def __init__(self, job, *args, **kwargs):\n", 384 | " super(Career, self).__init__(*args, **kwargs)\n", 385 | " self._job = job\n", 386 | " \n", 387 | " def __str__(self): \n", 388 | " return 'So I became a waiter of {}'.format(self._job)\n", 389 | " \n", 390 | "raise Career('Engineer')" 391 | ] 392 | } 393 | ], 394 | "metadata": { 395 | "kernelspec": { 396 | "display_name": "Python 3", 397 | "language": "python", 398 | "name": "python3" 399 | }, 400 | "language_info": { 401 | "codemirror_mode": { 402 | "name": "ipython", 403 | "version": 3 404 | }, 405 | "file_extension": ".py", 406 | "mimetype": "text/x-python", 407 | "name": "python", 408 | "nbconvert_exporter": "python", 409 | "pygments_lexer": "ipython3", 410 | "version": "3.5.1" 411 | } 412 | }, 413 | "nbformat": 4, 414 | "nbformat_minor": 0 415 | } 416 | -------------------------------------------------------------------------------- /11 Persistence.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Persistence" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "In this notebook, our focus is on **persistent data** — the kind that outlives a program that creates it. \n", 15 | "\n", 16 | "That’s not true by default for objects a script constructs, of course; things like lists, dictionaries, and even class instance objects live in your computer’s memory and are lost as soon as the script ends. \n", 17 | "\n", 18 | "To make data live longer, we need to do something special. \n", 19 | "\n", 20 | "In Python there are (at least) five *traditional* ways to save information in between program executions:\n", 21 | "\n", 22 | "* *Flat files*\n", 23 | " * Text and bytes stored directly on your computer\n", 24 | " \n", 25 | "* *DBM keyed files*\n", 26 | " * Keyed access to strings stored in dictionary-like files\n", 27 | " \n", 28 | "* *Pickled objects*\n", 29 | " * Pickled objects \n", 30 | " \n", 31 | "* *Shelve files*\n", 32 | " * Pickled Python objects saved in DBM keyed files\n", 33 | "\n", 34 | "* *SQL relational databases (RDBMSs)*\n", 35 | " * Table-based storage that supports SQL queries (SQLite, MySQL, PostGreSQL, etc.)" 36 | ] 37 | }, 38 | { 39 | "cell_type": "markdown", 40 | "metadata": {}, 41 | "source": [ 42 | "# SQL Database Interface" 43 | ] 44 | }, 45 | { 46 | "cell_type": "markdown", 47 | "metadata": {}, 48 | "source": [ 49 | "For programs that can benefit from the power of SQL, Python also broadly supports relational database management systems (**RDBMSs**).\n", 50 | "\n", 51 | "The databases we’ll meet in this notebook, though, are structured and processed in very different ways:\n", 52 | "\n", 53 | "* They store data in related tables of columns (rather than in persistent dictionaries of arbitrarily structured persistent Python objects).\n", 54 | "\n", 55 | "* They support the SQL query language for accessing data and exploiting relation- ships among it (instead of Python object traversals).\n", 56 | "\n", 57 | "For some applications, the end result can be a potent combination. Moreover, some SQL-based database systems provide industrial-strength persistence support for enterprise-level data." 58 | ] 59 | }, 60 | { 61 | "cell_type": "markdown", 62 | "metadata": {}, 63 | "source": [ 64 | "## Python Modules" 65 | ] 66 | }, 67 | { 68 | "cell_type": "markdown", 69 | "metadata": {}, 70 | "source": [ 71 | "Today, there are freely available interfaces that let Python scripts utilize all common relational database systems, both free and commercial: MySQL, Oracle, Sybase, Informix, InterBase, PostgreSQL (Postgres), SQLite, ODBC, and more.\n", 72 | "\n", 73 | "In addition, the Python community has defined a **database API** (*aka* `DB API`) specification that works portably with a variety of underlying database packages. \n", 74 | "\n", 75 | "Scripts written for this API can be migrated to different database vendor packages, with minimal or no source code changes.\n", 76 | "\n", 77 | "As of Python 2.5, Python itself includes built-in support for the SQLite relational database system as part of its standard library. \n", 78 | "\n", 79 | "Because this system supports the portable database API, it serves as a tool for both program storage and prototyping—systems developed with SQLite work largely unchanged when a more feature-rich database such as MySQL or Oracle is deployed.\n", 80 | "\n", 81 | "Moreover, the popular `SQLObject` and `SQLAlchemy` third-party systems both provide an **Object Relational Mapper (ORM)**, which grafts an object interface onto your database, in which tables are modeled by as Python classes, rows by instances of those classes, and columns by instance attributes. " 82 | ] 83 | }, 84 | { 85 | "cell_type": "markdown", 86 | "metadata": {}, 87 | "source": [ 88 | "## Python SQL Interface" 89 | ] 90 | }, 91 | { 92 | "cell_type": "markdown", 93 | "metadata": {}, 94 | "source": [ 95 | "The **Python Database API** (DB API) specification defines an interface for communicating with underlying database systems from Python scripts. \n", 96 | "\n", 97 | "Vendor-specific database interfaces for Python may or may not conform to this API completely, but all database extensions for Python in common use are minor variations on a theme. \n", 98 | "\n", 99 | "Under the database API, SQL databases in Python are grounded on three core concepts:\n", 100 | "\n", 101 | "* **Connection Objects**:\n", 102 | " > Represent a connection to a database, are the interface to rollback and commit operations, provide package implementation details, and generate cursor objects.\n", 103 | " \n", 104 | "* **Cursor Objects**:\n", 105 | " > Represent an SQL statement submitted as a string and can be used to access and step through SQL statement results.\n", 106 | " \n", 107 | "* **Query results of SQL select statements**:\n", 108 | " > Are returned to scripts as Python sequences of sequences (e.g., a *list of tuples*), representing database tables of rows. Within these row sequences, column field values are normal Python objects such as strings, integers, and floats (e.g., `[('bob', 48), ('emily',47)]`). Column values may also be special types that encapsulate things such as date and time, and database `NULL` values are returned as the Python `None` object." 109 | ] 110 | }, 111 | { 112 | "cell_type": "markdown", 113 | "metadata": {}, 114 | "source": [ 115 | "### Connection Objects" 116 | ] 117 | }, 118 | { 119 | "cell_type": "markdown", 120 | "metadata": {}, 121 | "source": [ 122 | "Beyond this, the API defines a standard set of database exception types, special database type object constructors, and informational top-level calls including thread safety and replacement style checks.\n", 123 | "\n", 124 | "For instance, to establish a database connection under the Python API-compliant **Oracle** interface, install the commonly used Python Oracle extension module (i.e. `pip install cx_oracle`) as well as Oracle itself, and then run a statement of this form:\n", 125 | "\n", 126 | "```python\n", 127 | " connobj = connect(\"user/password@system\")\n", 128 | "```" 129 | ] 130 | }, 131 | { 132 | "cell_type": "markdown", 133 | "metadata": {}, 134 | "source": [ 135 | "This call’s arguments may vary per database and vendor (e.g., some may require network details or a local file’s name), but they generally contain what you provide to log in to your database system. \n", 136 | "\n", 137 | "Once you have a connection object, there a variety of things you can do with it, including:\n", 138 | "\n", 139 | "```python\n", 140 | " connobj.close() # close connection now (not at object __del__ time)\n", 141 | " connobj.commit() # commit any pending transactions to the database \n", 142 | " connobj.rollback() # roll database back to start of pending transactions\n", 143 | "```" 144 | ] 145 | }, 146 | { 147 | "cell_type": "markdown", 148 | "metadata": {}, 149 | "source": [ 150 | "### Cursor Objects" 151 | ] 152 | }, 153 | { 154 | "cell_type": "markdown", 155 | "metadata": {}, 156 | "source": [ 157 | "But one of the most useful things to do with a connection object is to generate a cursor object:\n", 158 | "\n", 159 | "```python\n", 160 | " cursobj = connobj.cursor() # return a new cursor object for running SQL\n", 161 | "```\n", 162 | "\n", 163 | "Cursor objects have a set of methods, too (e.g., close to close the cursor before its destructor runs, and callproc to call a stored procedure), but the most important may be this one:\n", 164 | "\n", 165 | "```python\n", 166 | " cursobj.execute(sqlstring [, parameters]) # run SQL query or command string\n", 167 | "```\n" 168 | ] 169 | }, 170 | { 171 | "cell_type": "markdown", 172 | "metadata": {}, 173 | "source": [ 174 | "Parameters are passed in as a sequence or mapping of values, and are substituted into the `SQL` statement string according to the interface module’s replacement target conventions. \n", 175 | "\n", 176 | "The execute method can be used to run a variety of `SQL` statement strings:\n", 177 | "\n", 178 | "* DDL definition statements (e.g., `CREATE TABLE`);\n", 179 | "* DML modification statements (e.g., `UPDATE` or `INSERT`);\n", 180 | "* DQL query statements (e.g., `SELECT`)\n", 181 | "\n", 182 | "After running an SQL statement, the cursor’s `rowcount` attribute gives the number of rows *changed* (for **DML** changes) or *fetched* (for **DQL** queries), and the cursor’s `description` attribute gives column names and types after a query; \n", 183 | "`execute` also returns the number of rows affected or fetched in the most vendor interfaces. \n", 184 | "\n", 185 | "For **DQL** query statements, you must call one of the `fetch` methods to complete the operation:\n", 186 | "\n", 187 | "```python\n", 188 | " single_tuple = cursobj.fetchone() # fetch next row of a query result \n", 189 | " list_of_tuple = cursobj.fetchmany([size]) # fetch next set of rows of query result\n", 190 | " list_of_tuple = cursobj.fetchall() # fetch all remaining rows of the result\n", 191 | "```" 192 | ] 193 | }, 194 | { 195 | "cell_type": "markdown", 196 | "metadata": {}, 197 | "source": [ 198 | "And once you’ve received fetch method results, table information is processed using normal Python sequence operations; for example, you can step through the tuples in a `fetchall` result list with a simple for loop or comprehension expression. \n", 199 | "\n", 200 | "Most Python database interfaces also allow you to provide values to be passed to `SQL` statement strings, by providing targets and a tuple of parameters. For instance:\n", 201 | "\n", 202 | "```python\n", 203 | "\n", 204 | "query = 'SELECT name, shoesize FROM spam WHERE job = ? AND age = ?' \n", 205 | "cursobj.execute(query, (value1, value2))\n", 206 | "results = cursobj.fetchall()\n", 207 | "for row in results: \n", 208 | " pass # do something\n", 209 | " \n", 210 | "```" 211 | ] 212 | }, 213 | { 214 | "cell_type": "markdown", 215 | "metadata": {}, 216 | "source": [ 217 | "In this event, the database interface utilizes *prepared statements* (an optimization and convenience) and correctly passes the parameters to the database regardless of their Python types. \n", 218 | "\n", 219 | "The notation used to code targets in the query string may vary in some database interfaces (e.g., `:p1` and `:p2` or two `%s`, rather than the two `?s` used by the **Oracle interface**); in any event, this is not the same as Python’s \n", 220 | "`%` string formatting operator, as it sidesteps security issues along the way.\n", 221 | "\n", 222 | "Finally, if your database supports stored procedures, you can call them with the `callproc` method or by passing an `SQL CALL` or `EXEC` statement string to the execute method. \n", 223 | "\n", 224 | "`callproc` may generate a result table retrieved with a `fetch` variant, and returns a modified copy of the input sequence — input parameters are left untouched, and output and input/output parameters are replaced with possibly new values. \n", 225 | "\n", 226 | "Additional API features, including support for database `blobs` (roughly, with sized results), is described in the API’s documentation. \n", 227 | "\n", 228 | "For now, let’s move on to do some real SQL processing in Python." 229 | ] 230 | }, 231 | { 232 | "cell_type": "markdown", 233 | "metadata": {}, 234 | "source": [ 235 | "## An SQL Database API Tutorial with SQLite" 236 | ] 237 | }, 238 | { 239 | "cell_type": "markdown", 240 | "metadata": {}, 241 | "source": [ 242 | "We don’t have space to provide an exhaustive reference for the database API in this notebook. \n", 243 | "\n", 244 | "To sample the flavor of the interface, though, let’s step through a few simple examples. \n", 245 | "\n", 246 | "We’ll use the **SQLite** database system for this tutorial. \n", 247 | "\n", 248 | "SQLite is a standard part of Python itself, which you can reasonably expect to be available in all Python installations. Although SQLite implements a complete relational database system, it takes the form of an in-process library instead of a server. \n", 249 | "\n", 250 | "This generally makes it better suited for program storage than for enterprise-level data needs." 251 | ] 252 | }, 253 | { 254 | "cell_type": "markdown", 255 | "metadata": {}, 256 | "source": [ 257 | "### Note:\n", 258 | "\n", 259 | "Thanks to Python’s portable DB API, though, other popular database packages such as **PostgreSQL, MySQL, and Oracle** are used almost identically; the initial call to log in to the database will be all that normally requires different argument values for scripts that use standard SQL code. \n", 260 | "\n", 261 | "Because of this, we can use the SQLite system both as a prototyping tool in applications development and as an easy way to get started with the Python SQL database API in this book.\n" 262 | ] 263 | }, 264 | { 265 | "cell_type": "markdown", 266 | "metadata": {}, 267 | "source": [ 268 | "## Getting Started" 269 | ] 270 | }, 271 | { 272 | "cell_type": "markdown", 273 | "metadata": {}, 274 | "source": [ 275 | "Regardless of which database system your scripts talk to, the basic SQL interface in Python is very simple. \n", 276 | "\n", 277 | "In fact, it’s hardly object-oriented at all queries and other database commands are sent as strings of SQL. \n", 278 | "\n", 279 | "Whether large or small, though, the Python code needed to process your database turns out to be surprisingly straightforward. \n", 280 | "\n", 281 | "To get started, the first thing we need to do is open a connection to the database and create a table for storing records:" 282 | ] 283 | }, 284 | { 285 | "cell_type": "code", 286 | "execution_count": 1, 287 | "metadata": { 288 | "collapsed": true 289 | }, 290 | "outputs": [], 291 | "source": [ 292 | "import sqlite3\n", 293 | "conn = sqlite3.connect('data/dbase1')" 294 | ] 295 | }, 296 | { 297 | "cell_type": "markdown", 298 | "metadata": {}, 299 | "source": [ 300 | "We start out by importing the Python SQLite interface here— it’s a standard library module called `sqlite3` to our scripts. \n", 301 | "\n", 302 | "Next we create a **connection** object, passing in the items our database requires at start-up time—here, the name of the local file where our databases will be stored. \n", 303 | "\n", 304 | "This file is what you’ll want to back up to save your database. It will create the file if needed, or open its current content; SQLite also accepts that special string `:memory:` to create a temporary database in memory instead." 305 | ] 306 | }, 307 | { 308 | "cell_type": "markdown", 309 | "metadata": {}, 310 | "source": [ 311 | "As long as a script sticks to using standard SQL code, the connect call’s arguments are usually the only thing that can vary across different database systems. \n", 312 | "\n", 313 | "For example, in the MySQL interface this call accepts a network host’s domain name, user name, and password, passed as keyword arguments instead, and the **Oracle example** sketched earlier expects a more specific sting syntax. \n", 314 | "\n", 315 | "Once we’ve gotten past this platform-specific call, though, the rest of the API is largely database **neutral**." 316 | ] 317 | }, 318 | { 319 | "cell_type": "markdown", 320 | "metadata": {}, 321 | "source": [ 322 | "### Making Database and Tables" 323 | ] 324 | }, 325 | { 326 | "cell_type": "markdown", 327 | "metadata": {}, 328 | "source": [ 329 | "Next, let’s make a cursor for submitting SQL statements to the database server, and submit one to create a first table:" 330 | ] 331 | }, 332 | { 333 | "cell_type": "code", 334 | "execution_count": 2, 335 | "metadata": { 336 | "collapsed": false 337 | }, 338 | "outputs": [ 339 | { 340 | "data": { 341 | "text/plain": [ 342 | "" 343 | ] 344 | }, 345 | "execution_count": 2, 346 | "metadata": {}, 347 | "output_type": "execute_result" 348 | } 349 | ], 350 | "source": [ 351 | "curs = conn.cursor()\n", 352 | "try:\n", 353 | " curs.execute('drop table people')\n", 354 | "except:\n", 355 | " pass # did not exist\n", 356 | "curs.execute('create table people (name char(30), job char(10), pay int(4))')" 357 | ] 358 | }, 359 | { 360 | "cell_type": "markdown", 361 | "metadata": {}, 362 | "source": [ 363 | "The last command here creates the table called “people” within the database; the name, job, and pay information specifies the columns in this table, as well as their datatypes, using a “type(size)” syntax — two strings and an integer. \n", 364 | "\n", 365 | "Datatypes can be more sophisticated than ours, but we’ll ignore such details here. \n", 366 | "\n", 367 | "In SQLite, the file is the database, so there’s no notion of creating or using a specific database within it, as there is in some systems." 368 | ] 369 | }, 370 | { 371 | "cell_type": "markdown", 372 | "metadata": {}, 373 | "source": [ 374 | "### Adding Records" 375 | ] 376 | }, 377 | { 378 | "cell_type": "markdown", 379 | "metadata": {}, 380 | "source": [ 381 | "There are three basic statement-based approaches we can use here: \n", 382 | "\n", 383 | "* inserting one row at a time; \n", 384 | "* inserting multiple rows with a single call statement;\n", 385 | "* using a Python loop.\n", 386 | "\n", 387 | "Here is the simple case" 388 | ] 389 | }, 390 | { 391 | "cell_type": "code", 392 | "execution_count": 3, 393 | "metadata": { 394 | "collapsed": false 395 | }, 396 | "outputs": [ 397 | { 398 | "data": { 399 | "text/plain": [ 400 | "1" 401 | ] 402 | }, 403 | "execution_count": 3, 404 | "metadata": {}, 405 | "output_type": "execute_result" 406 | } 407 | ], 408 | "source": [ 409 | "curs.execute('insert into people values (?, ?, ?)', ('Bob', 'dev', 50000))\n", 410 | "curs.rowcount" 411 | ] 412 | }, 413 | { 414 | "cell_type": "code", 415 | "execution_count": 4, 416 | "metadata": { 417 | "collapsed": false 418 | }, 419 | "outputs": [ 420 | { 421 | "data": { 422 | "text/plain": [ 423 | "'qmark'" 424 | ] 425 | }, 426 | "execution_count": 4, 427 | "metadata": {}, 428 | "output_type": "execute_result" 429 | } 430 | ], 431 | "source": [ 432 | "sqlite3.paramstyle" 433 | ] 434 | }, 435 | { 436 | "cell_type": "markdown", 437 | "metadata": {}, 438 | "source": [ 439 | "Here, `qmark` means this module accepts `?` for replacement targets. \n", 440 | "\n", 441 | "Other database modules might use styles such as format (meaning a `%s` target), or numeric indexes or mapping keys; see the **DB API** for more details." 442 | ] 443 | }, 444 | { 445 | "cell_type": "markdown", 446 | "metadata": {}, 447 | "source": [ 448 | "To insert multiple rows with a single statement, use the `executemany` method and a sequence of row sequences (e.g., a list of lists). This call is like calling `execute` once for each row sequence in the argument, and in fact may be implemented as such; database interfaces may also use database-specific techniques to make this run quicker, though:" 449 | ] 450 | }, 451 | { 452 | "cell_type": "code", 453 | "execution_count": 5, 454 | "metadata": { 455 | "collapsed": false 456 | }, 457 | "outputs": [ 458 | { 459 | "data": { 460 | "text/plain": [ 461 | "2" 462 | ] 463 | }, 464 | "execution_count": 5, 465 | "metadata": {}, 466 | "output_type": "execute_result" 467 | } 468 | ], 469 | "source": [ 470 | "curs.executemany('insert into people values (?, ?, ?)', \n", 471 | " [ ('Sue', 'mus', '70000'),\n", 472 | " ('Ann', 'mus', '60000')])\n", 473 | "curs.rowcount" 474 | ] 475 | }, 476 | { 477 | "cell_type": "markdown", 478 | "metadata": {}, 479 | "source": [ 480 | "We inserted two rows at once in the last statement. \n", 481 | "\n", 482 | "It’s hardly any more work to achieve the same result by inserting one row at a time with a Python loop:" 483 | ] 484 | }, 485 | { 486 | "cell_type": "code", 487 | "execution_count": 6, 488 | "metadata": { 489 | "collapsed": true 490 | }, 491 | "outputs": [], 492 | "source": [ 493 | "rows = [['Tom', 'mgr', 100000], ['Kim', 'adm', 30000], ['pat', 'dev', 90000]]\n", 494 | "for row in rows:\n", 495 | " curs.execute('insert into people values (? , ?, ?)', row)\n", 496 | "conn.commit()" 497 | ] 498 | }, 499 | { 500 | "cell_type": "markdown", 501 | "metadata": {}, 502 | "source": [ 503 | "Blending Python and SQL like this starts to open up all sorts of interesting possibilities. \n", 504 | "\n", 505 | "Notice the last command; we always need to call the connection’s `commit` method to write our changes out to the database. Otherwise, when the connection is closed, our changes may be lost. \n", 506 | "\n", 507 | "In fact, until we call the `commit` method, none of our inserts may be visible from other database connections." 508 | ] 509 | }, 510 | { 511 | "cell_type": "markdown", 512 | "metadata": {}, 513 | "source": [ 514 | "### Side note:\n", 515 | "\n", 516 | "Technically, the API suggests that a connection object should automatically call its `rollback` method to back out changes that have not yet been committed, when it is closed (which happens manually when its close method is called, or automatically when the connection object is about to be garbage collected). \n", 517 | "\n", 518 | "For database systems that don’t support transaction commit and rollback operations, these calls may do nothing. SQLite implements both the commit and rollback methods; the latter rolls back any changes made since the last commit." 519 | ] 520 | }, 521 | { 522 | "cell_type": "markdown", 523 | "metadata": {}, 524 | "source": [ 525 | "### Running Queries" 526 | ] 527 | }, 528 | { 529 | "cell_type": "code", 530 | "execution_count": 7, 531 | "metadata": { 532 | "collapsed": false 533 | }, 534 | "outputs": [ 535 | { 536 | "name": "stdout", 537 | "output_type": "stream", 538 | "text": [ 539 | "('Bob', 'dev', 50000)\n", 540 | "('Sue', 'mus', 70000)\n", 541 | "('Ann', 'mus', 60000)\n", 542 | "('Tom', 'mgr', 100000)\n", 543 | "('Kim', 'adm', 30000)\n", 544 | "('pat', 'dev', 90000)\n" 545 | ] 546 | } 547 | ], 548 | "source": [ 549 | "curs.execute('select * from people')\n", 550 | "for row in curs.fetchall():\n", 551 | " print(row)" 552 | ] 553 | }, 554 | { 555 | "cell_type": "markdown", 556 | "metadata": {}, 557 | "source": [ 558 | "**Tuple unpacking** comes in handy in loops here, too, to pick out column values as we go. \n", 559 | "\n", 560 | "Here’s a simple formatted display of two of the columns’ values:" 561 | ] 562 | }, 563 | { 564 | "cell_type": "code", 565 | "execution_count": 8, 566 | "metadata": { 567 | "collapsed": false 568 | }, 569 | "outputs": [ 570 | { 571 | "name": "stdout", 572 | "output_type": "stream", 573 | "text": [ 574 | "Bob : 50000\n", 575 | "Sue : 70000\n", 576 | "Ann : 60000\n", 577 | "Tom : 100000\n", 578 | "Kim : 30000\n", 579 | "pat : 90000\n" 580 | ] 581 | } 582 | ], 583 | "source": [ 584 | "curs.execute('select * from people')\n", 585 | "for (name, job, pay) in curs.fetchall():\n", 586 | " print(name, ':', pay)" 587 | ] 588 | }, 589 | { 590 | "cell_type": "markdown", 591 | "metadata": {}, 592 | "source": [ 593 | "Because the query result is a sequence, we can use Python’s powerful sequence and iteration tools to process it. \n", 594 | "\n", 595 | "For instance, to select just the name column values, we can run a more specific SQL query and get a list of tuples" 596 | ] 597 | }, 598 | { 599 | "cell_type": "code", 600 | "execution_count": 9, 601 | "metadata": { 602 | "collapsed": false 603 | }, 604 | "outputs": [ 605 | { 606 | "data": { 607 | "text/plain": [ 608 | "[('Bob',), ('Sue',), ('Ann',), ('Tom',), ('Kim',), ('pat',)]" 609 | ] 610 | }, 611 | "execution_count": 9, 612 | "metadata": {}, 613 | "output_type": "execute_result" 614 | } 615 | ], 616 | "source": [ 617 | "curs.execute('select name from people')\n", 618 | "names = curs.fetchall()\n", 619 | "names" 620 | ] 621 | }, 622 | { 623 | "cell_type": "markdown", 624 | "metadata": {}, 625 | "source": [ 626 | "#### `fetchall` vs `fetchone`\n", 627 | "\n", 628 | "The `fetchall` call we’ve used so far fetches the entire query result table all at once, as a single sequence (an empty sequence comes back, if the result is empty). \n", 629 | "\n", 630 | "That’s convenient, but it may be slow enough to block the caller temporarily for large result tables or generate substantial network traffic if the server is running remotely (something could easily require a parallel thread in GUI). \n", 631 | "\n", 632 | "To avoid such a bottleneck, we can also grab just one row, or a bunch of rows, at a time with `fetchone` and `fetchmany`. \n", 633 | "\n", 634 | "The `fetchone` call returns the next result row or a `None` false value at the end of the table:" 635 | ] 636 | }, 637 | { 638 | "cell_type": "code", 639 | "execution_count": 10, 640 | "metadata": { 641 | "collapsed": false 642 | }, 643 | "outputs": [ 644 | { 645 | "name": "stdout", 646 | "output_type": "stream", 647 | "text": [ 648 | "('Bob', 'dev', 50000)\n", 649 | "('Sue', 'mus', 70000)\n", 650 | "('Ann', 'mus', 60000)\n", 651 | "('Tom', 'mgr', 100000)\n", 652 | "('Kim', 'adm', 30000)\n", 653 | "('pat', 'dev', 90000)\n" 654 | ] 655 | } 656 | ], 657 | "source": [ 658 | "curs.execute('select * from people')\n", 659 | "while True:\n", 660 | " row = curs.fetchone() \n", 661 | " if not row: \n", 662 | " break \n", 663 | " print(row)" 664 | ] 665 | }, 666 | { 667 | "cell_type": "code", 668 | "execution_count": 11, 669 | "metadata": { 670 | "collapsed": false 671 | }, 672 | "outputs": [ 673 | { 674 | "name": "stdout", 675 | "output_type": "stream", 676 | "text": [ 677 | "('Bob', 'dev', 50000)\n", 678 | "('Sue', 'mus', 70000)\n", 679 | "('Ann', 'mus', 60000)\n", 680 | "('Tom', 'mgr', 100000)\n", 681 | "('Kim', 'adm', 30000)\n", 682 | "('pat', 'dev', 90000)\n" 683 | ] 684 | } 685 | ], 686 | "source": [ 687 | "curs.execute('select * from people')\n", 688 | "for row in curs:\n", 689 | " print(row)" 690 | ] 691 | }, 692 | { 693 | "cell_type": "markdown", 694 | "metadata": {}, 695 | "source": [ 696 | "The `fetchmany` call returns a sequence of rows from the result, but not the entire table; you can specify how many rows to grab each time with a parameter or rely on the default as given by the cursor’s `arraysize` attribute. \n", 697 | "\n", 698 | "Each call gets at most that many more rows from the result or an empty sequence at the end of the table:" 699 | ] 700 | }, 701 | { 702 | "cell_type": "code", 703 | "execution_count": 13, 704 | "metadata": { 705 | "collapsed": false 706 | }, 707 | "outputs": [ 708 | { 709 | "name": "stdout", 710 | "output_type": "stream", 711 | "text": [ 712 | "('Bob', 'dev', 50000)\n", 713 | "('Sue', 'mus', 70000)\n", 714 | "('Ann', 'mus', 60000)\n", 715 | "('Tom', 'mgr', 100000)\n", 716 | "('Kim', 'adm', 30000)\n", 717 | "('pat', 'dev', 90000)\n" 718 | ] 719 | } 720 | ], 721 | "source": [ 722 | "curs.execute('select * from people')\n", 723 | "while True:\n", 724 | " rows = curs.fetchmany() # size=N optional argument\n", 725 | " if not rows: \n", 726 | " break\n", 727 | " for row in rows:\n", 728 | " print(row)" 729 | ] 730 | }, 731 | { 732 | "cell_type": "markdown", 733 | "metadata": {}, 734 | "source": [ 735 | "#### More sophisticated Example" 736 | ] 737 | }, 738 | { 739 | "cell_type": "code", 740 | "execution_count": 14, 741 | "metadata": { 742 | "collapsed": false 743 | }, 744 | "outputs": [ 745 | { 746 | "data": { 747 | "text/plain": [ 748 | "(('name', None, None, None, None, None, None),\n", 749 | " ('job', None, None, None, None, None, None),\n", 750 | " ('pay', None, None, None, None, None, None))" 751 | ] 752 | }, 753 | "execution_count": 14, 754 | "metadata": {}, 755 | "output_type": "execute_result" 756 | } 757 | ], 758 | "source": [ 759 | "curs.description" 760 | ] 761 | }, 762 | { 763 | "cell_type": "code", 764 | "execution_count": 15, 765 | "metadata": { 766 | "collapsed": false 767 | }, 768 | "outputs": [ 769 | { 770 | "name": "stdout", 771 | "output_type": "stream", 772 | "text": [ 773 | "------------------------------\n", 774 | "name => Bob\n", 775 | "job => dev\n", 776 | "pay => 50000\n", 777 | "------------------------------\n", 778 | "name => Sue\n", 779 | "job => mus\n", 780 | "pay => 70000\n", 781 | "------------------------------\n", 782 | "name => Ann\n", 783 | "job => mus\n", 784 | "pay => 60000\n", 785 | "------------------------------\n", 786 | "name => Tom\n", 787 | "job => mgr\n", 788 | "pay => 100000\n", 789 | "------------------------------\n", 790 | "name => Kim\n", 791 | "job => adm\n", 792 | "pay => 30000\n", 793 | "------------------------------\n", 794 | "name => pat\n", 795 | "job => dev\n", 796 | "pay => 90000\n" 797 | ] 798 | } 799 | ], 800 | "source": [ 801 | "curs.execute('select * from people')\n", 802 | "colnames = [desc[0] for desc in curs.description]\n", 803 | "for row in curs:\n", 804 | " print('-' * 30)\n", 805 | " for (name, value) in zip(colnames, row):\n", 806 | " print('%s => %s' % (name, value))" 807 | ] 808 | }, 809 | { 810 | "cell_type": "markdown", 811 | "metadata": {}, 812 | "source": [ 813 | "## Exercise:\n", 814 | "\n", 815 | "Convert list of row tuples to list of row dicts with field name keys." 816 | ] 817 | }, 818 | { 819 | "cell_type": "code", 820 | "execution_count": null, 821 | "metadata": { 822 | "collapsed": false 823 | }, 824 | "outputs": [], 825 | "source": [ 826 | "# %load files/makedicts.py\n", 827 | "\"\"\"\n", 828 | "convert list of row tuples to list of row dicts with field name keys\n", 829 | "\"\"\"\n", 830 | "import sqlite3\n", 831 | "\n", 832 | "def makedicts(cursor, query, params=()):\n", 833 | " cursor.execute(query, params)\n", 834 | " colnames = [desc[0] for desc in cursor.description]\n", 835 | " rowdicts = [dict(zip(colnames, row)) for row in cursor]\n", 836 | " return rowdicts\n", 837 | "\n", 838 | "conn = sqlite3.connect('data/dbase1')\n", 839 | "cursor = conn.cursor()\n", 840 | "query = 'select name, pay from people where pay < ?'\n", 841 | "lowpay = makedicts(cursor, query, [70000])\n", 842 | "for rec in lowpay: \n", 843 | " print(rec)\n" 844 | ] 845 | }, 846 | { 847 | "cell_type": "markdown", 848 | "metadata": {}, 849 | "source": [ 850 | "## Exercise no. 2\n", 851 | "\n", 852 | "Load Data from Text files: load table from comma-delimited text file." 853 | ] 854 | }, 855 | { 856 | "cell_type": "code", 857 | "execution_count": 18, 858 | "metadata": { 859 | "collapsed": false 860 | }, 861 | "outputs": [ 862 | { 863 | "name": "stdout", 864 | "output_type": "stream", 865 | "text": [ 866 | "bob,devel,50000\r", 867 | "\r\n", 868 | "sue,music,60000\r", 869 | "\r\n", 870 | "ann,devel,40000\r", 871 | "\r\n", 872 | "tim,admin,30000\r", 873 | "\r\n", 874 | "kim,devel,60000" 875 | ] 876 | } 877 | ], 878 | "source": [ 879 | "!cat data/data.txt" 880 | ] 881 | }, 882 | { 883 | "cell_type": "code", 884 | "execution_count": 19, 885 | "metadata": { 886 | "collapsed": false 887 | }, 888 | "outputs": [ 889 | { 890 | "name": "stdout", 891 | "output_type": "stream", 892 | "text": [ 893 | "bob,developer,80000\r", 894 | "\r\n", 895 | "sue,music,90000\r", 896 | "\r\n", 897 | "ann,manager,80000" 898 | ] 899 | } 900 | ], 901 | "source": [ 902 | "!cat data/data2.txt" 903 | ] 904 | } 905 | ], 906 | "metadata": { 907 | "kernelspec": { 908 | "display_name": "Python 3", 909 | "language": "python", 910 | "name": "python3" 911 | }, 912 | "language_info": { 913 | "codemirror_mode": { 914 | "name": "ipython", 915 | "version": 3 916 | }, 917 | "file_extension": ".py", 918 | "mimetype": "text/x-python", 919 | "name": "python", 920 | "nbconvert_exporter": "python", 921 | "pygments_lexer": "ipython3", 922 | "version": "3.5.1" 923 | } 924 | }, 925 | "nbformat": 4, 926 | "nbformat_minor": 0 927 | } 928 | -------------------------------------------------------------------------------- /Coding Style (PEP8).ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "slideshow": { 7 | "slide_type": "slide" 8 | } 9 | }, 10 | "source": [ 11 | "# Coding Style: PEP 8\n", 12 | "\n" 13 | ] 14 | }, 15 | { 16 | "cell_type": "markdown", 17 | "metadata": { 18 | "slideshow": { 19 | "slide_type": "fragment" 20 | } 21 | }, 22 | "source": [ 23 | "You are now starting to write Python programs that have a little substance. Your programs are growing a little longer, and there is a little more structure to your programs. This is a really good time to consider your overall style in writing code." 24 | ] 25 | }, 26 | { 27 | "cell_type": "markdown", 28 | "metadata": { 29 | "slideshow": { 30 | "slide_type": "subslide" 31 | } 32 | }, 33 | "source": [ 34 | "Why do we need style conventions?\n", 35 | "---\n", 36 | "\n", 37 | "The people who originally developed Python made some of their decisions based on the realization that code is read much more often than it is written. The original developers paid as much attention to making the language easy to read, as well as easy to write. " 38 | ] 39 | }, 40 | { 41 | "cell_type": "markdown", 42 | "metadata": { 43 | "slideshow": { 44 | "slide_type": "fragment" 45 | } 46 | }, 47 | "source": [ 48 | "Python has gained a lot of respect as a programming language because of how readable the code is. You have seen that Python uses indentation to show which lines in a program are grouped together. This makes the structure of your code visible to anyone who reads it." 49 | ] 50 | }, 51 | { 52 | "cell_type": "markdown", 53 | "metadata": { 54 | "slideshow": { 55 | "slide_type": "fragment" 56 | } 57 | }, 58 | "source": [ 59 | "There are, however, some styling decisions we get to make as programmers that can make our programs more readable for ourselves, and for others." 60 | ] 61 | }, 62 | { 63 | "cell_type": "markdown", 64 | "metadata": { 65 | "slideshow": { 66 | "slide_type": "fragment" 67 | } 68 | }, 69 | "source": [ 70 | "There are several audiences to consider when you think about how readable your code is." 71 | ] 72 | }, 73 | { 74 | "cell_type": "markdown", 75 | "metadata": { 76 | "slideshow": { 77 | "slide_type": "subslide" 78 | } 79 | }, 80 | "source": [ 81 | "#### Yourself, 6 months from now\n", 82 | "\n", 83 | "- You know what you are thinking when you write code for the first time. But how easily will you recall what you were thinking when you come back to that code tomorrow, next week, or six months from now? We want our code to be as easy to read as possible six months from now, so we can jump back into our projects when we want to." 84 | ] 85 | }, 86 | { 87 | "cell_type": "markdown", 88 | "metadata": { 89 | "slideshow": { 90 | "slide_type": "fragment" 91 | } 92 | }, 93 | "source": [ 94 | "#### Other programmers you might want to collaborate with\n", 95 | "\n", 96 | "- Every significant project is the result of collaboration these days. If you stay in programming, you will work with others in jobs and in open source projects. If you write readable code with good commments, people will be happy to work with you in any setting." 97 | ] 98 | }, 99 | { 100 | "cell_type": "markdown", 101 | "metadata": { 102 | "slideshow": { 103 | "slide_type": "fragment" 104 | } 105 | }, 106 | "source": [ 107 | "#### Potential employers\n", 108 | "\n", 109 | "- Most people who hire programmers will ask to see some code you have written, and they will probably ask you to write some code during your interview. If you are in the habit of writing code that is easy to read, you will do well in these situations." 110 | ] 111 | }, 112 | { 113 | "cell_type": "markdown", 114 | "metadata": { 115 | "slideshow": { 116 | "slide_type": "subslide" 117 | } 118 | }, 119 | "source": [ 120 | "What is a PEP?\n", 121 | "---\n", 122 | "\n", 123 | "A PEP is a *Python Enhancement Proposal*. " 124 | ] 125 | }, 126 | { 127 | "cell_type": "markdown", 128 | "metadata": { 129 | "slideshow": { 130 | "slide_type": "fragment" 131 | } 132 | }, 133 | "source": [ 134 | "One of the earliest PEPs was a collection of guidelines for writing code that is easy to read. It was PEP 8, the [Style Guide for Python Code](http://www.python.org/dev/peps/pep-0008/). " 135 | ] 136 | }, 137 | { 138 | "cell_type": "markdown", 139 | "metadata": { 140 | "slideshow": { 141 | "slide_type": "fragment" 142 | } 143 | }, 144 | "source": [ 145 | "When people want to suggest changes to the actual Python language, someone drafts a Python Enhancement Proposal. \n", 146 | "\n", 147 | "There is a lot in there that won't make sense to you for some time yet, but there are some suggestions that you should be aware of from the beginning. Starting with good style habits now will help you write clean code from the beginning, which will help you make sense of your code as well." 148 | ] 149 | }, 150 | { 151 | "cell_type": "markdown", 152 | "metadata": { 153 | "slideshow": { 154 | "slide_type": "subslide" 155 | } 156 | }, 157 | "source": [ 158 | "Basic Python style guidelines\n", 159 | "---\n" 160 | ] 161 | }, 162 | { 163 | "cell_type": "markdown", 164 | "metadata": { 165 | "slideshow": { 166 | "slide_type": "fragment" 167 | } 168 | }, 169 | "source": [ 170 | "#### Indentation\n", 171 | "- Use 4 spaces for indentation. This is enough space to give your code some visual structure, while leaving room for multiple indentation levels. There are configuration settings in most editors to automatically convert tabs to 4 spaces, and it is a good idea to check this setting. On Geany, this is under Edit>Preferences>Editor>Indentation; set Width to 4, and Type to *Spaces*." 172 | ] 173 | }, 174 | { 175 | "cell_type": "markdown", 176 | "metadata": { 177 | "slideshow": { 178 | "slide_type": "fragment" 179 | } 180 | }, 181 | "source": [ 182 | "#### Line Length\n", 183 | "- Use up to 79 characters per line of code, and 72 characters for comments. This is a style guideline that some people adhere to and others completely ignore. This used to relate to a limit on the display size of most monitors. Now almost every monitor is capable of showing much more than 80 characters per line. But we often work in terminals, which are not always high-resolution. We also like to have multiple code files open, next to each other. It turns out this is still a useful guideline to follow in most cases. There is a secondary guideline of sticking to 99 characters per line, if you want longer lines." 184 | ] 185 | }, 186 | { 187 | "cell_type": "markdown", 188 | "metadata": { 189 | "slideshow": { 190 | "slide_type": "fragment" 191 | } 192 | }, 193 | "source": [ 194 | "Many editors have a setting that shows a vertical line that helps you keep your lines to a certain length. " 195 | ] 196 | }, 197 | { 198 | "cell_type": "markdown", 199 | "metadata": { 200 | "slideshow": { 201 | "slide_type": "subslide" 202 | } 203 | }, 204 | "source": [ 205 | "#### Blank Lines\n", 206 | "- Use single blank lines to break up your code into meaningful blocks. You have seen this in many examples so far. You can use two blank lines in longer programs, but don't get excessive with blank lines." 207 | ] 208 | }, 209 | { 210 | "cell_type": "markdown", 211 | "metadata": { 212 | "slideshow": { 213 | "slide_type": "fragment" 214 | } 215 | }, 216 | "source": [ 217 | "#### Comments\n", 218 | "- Use a single space after the pound sign at the beginning of a line. If you are writing more than one paragraph, use an empty line with a pound sign between paragraphs." 219 | ] 220 | }, 221 | { 222 | "cell_type": "markdown", 223 | "metadata": { 224 | "slideshow": { 225 | "slide_type": "fragment" 226 | } 227 | }, 228 | "source": [ 229 | "#### Naming Variables\n", 230 | "- Name variables and program files using only lowercase letters, underscores, and numbers. Python won't complain or throw errors if you use capitalization, but you will mislead other programmers if you use capital letters in variables at this point." 231 | ] 232 | }, 233 | { 234 | "cell_type": "markdown", 235 | "metadata": { 236 | "slideshow": { 237 | "slide_type": "subslide" 238 | } 239 | }, 240 | "source": [ 241 | "That's all for now. We will go over more style guidelines as we introduce more complicated programming structures. If you follow these guidelines for now, you will be well on your way to writing readable code that professionals will respect." 242 | ] 243 | }, 244 | { 245 | "cell_type": "markdown", 246 | "metadata": {}, 247 | "source": [ 248 | "Import statements\n", 249 | "---\n", 250 | "PEP8 provides clear guidelines about [where](http://www.python.org/dev/peps/pep-0008/#imports) import statements should appear in a file. The names of modules should be on separate lines:" 251 | ] 252 | }, 253 | { 254 | "cell_type": "code", 255 | "execution_count": 1, 256 | "metadata": { 257 | "collapsed": true 258 | }, 259 | "outputs": [], 260 | "source": [ 261 | "# this\n", 262 | "import sys\n", 263 | "import os\n", 264 | "\n", 265 | "# not this\n", 266 | "import sys, os" 267 | ] 268 | }, 269 | { 270 | "cell_type": "markdown", 271 | "metadata": {}, 272 | "source": [ 273 | "The names of classes can be on the same line:" 274 | ] 275 | }, 276 | { 277 | "cell_type": "code", 278 | "execution_count": 3, 279 | "metadata": { 280 | "collapsed": false 281 | }, 282 | "outputs": [], 283 | "source": [ 284 | "from rocket import Rocket, Shuttle" 285 | ] 286 | }, 287 | { 288 | "cell_type": "markdown", 289 | "metadata": {}, 290 | "source": [ 291 | "Imports should always be placed at the top of the file. When you are working on a longer program, you might have an idea that requires an import statement. You might write the import statement in the code block you are working on to see if your idea works. If you end up keeping the import, make sure you move the import statement to the top of the file. This lets anyone who works with your program see what modules are required for the program to work.\n", 292 | "\n", 293 | "Your import statements should be in a predictable order:\n", 294 | "\n", 295 | "- The first imports should be standard Python modules such as *sys*, *os*, and *math*.\n", 296 | "- The second set of imports should be \"third-party\" libraries. These are libraries that are written and maintained by independent programmers, which are not part of the official Python language." 297 | ] 298 | }, 299 | { 300 | "cell_type": "markdown", 301 | "metadata": {}, 302 | "source": [ 303 | "Module and class names\n", 304 | "---\n", 305 | "Modules should have [short, lowercase names](http://www.python.org/dev/peps/pep-0008/#package-and-module-names). If you want to have a space in the module name, use an underscore.\n", 306 | "\n", 307 | "[Class names](http://www.python.org/dev/peps/pep-0008/#class-names) should be written in *CamelCase*, with an initial capital letter and any new word capitalized. There should be no underscores in your class names.\n", 308 | "\n", 309 | "This convention helps distinguish modules from classes, for example when you are writing import statements." 310 | ] 311 | }, 312 | { 313 | "cell_type": "markdown", 314 | "metadata": { 315 | "slideshow": { 316 | "slide_type": "slide" 317 | } 318 | }, 319 | "source": [ 320 | "Exercises\n", 321 | "---\n", 322 | "#### Skim PEP 8\n", 323 | "- If you haven't done so already, skim [PEP 8 - Style Guide for Python Code](http://www.python.org/dev/peps/pep-0008/#block-comments). As you continue to learn Python, go back and look at this every once in a while. I can't stress enough that many good programmers will take you much more seriously from the start if you are following community-wide conventions as you write your code.\n", 324 | "\n", 325 | "#### Implement PEP 8\n", 326 | "- Take three of your longest programs, and add the extension *\\_pep8.py* to the filename of each program. Revise your code so that it meets the styling conventions listed above." 327 | ] 328 | }, 329 | { 330 | "cell_type": "code", 331 | "execution_count": null, 332 | "metadata": { 333 | "collapsed": false, 334 | "slideshow": { 335 | "slide_type": "skip" 336 | } 337 | }, 338 | "outputs": [], 339 | "source": [ 340 | "# Ex 3.28 : Skim PEP 8\n", 341 | "\n", 342 | "# put your code here" 343 | ] 344 | }, 345 | { 346 | "cell_type": "code", 347 | "execution_count": null, 348 | "metadata": { 349 | "collapsed": false, 350 | "slideshow": { 351 | "slide_type": "skip" 352 | } 353 | }, 354 | "outputs": [], 355 | "source": [ 356 | "# Ex 3.29 : Implement PEP 8\n", 357 | "\n", 358 | "# put your code here" 359 | ] 360 | } 361 | ], 362 | "metadata": { 363 | "kernelspec": { 364 | "display_name": "Python 3", 365 | "language": "python", 366 | "name": "python3" 367 | }, 368 | "language_info": { 369 | "codemirror_mode": { 370 | "name": "ipython", 371 | "version": 3 372 | }, 373 | "file_extension": ".py", 374 | "mimetype": "text/x-python", 375 | "name": "python", 376 | "nbconvert_exporter": "python", 377 | "pygments_lexer": "ipython3", 378 | "version": "3.5.1" 379 | } 380 | }, 381 | "nbformat": 4, 382 | "nbformat_minor": 0 383 | } 384 | -------------------------------------------------------------------------------- /Importing Modules.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "slideshow": { 7 | "slide_type": "slide" 8 | } 9 | }, 10 | "source": [ 11 | "# Modules" 12 | ] 13 | }, 14 | { 15 | "cell_type": "markdown", 16 | "metadata": { 17 | "slideshow": { 18 | "slide_type": "subslide" 19 | } 20 | }, 21 | "source": [ 22 | "Most of the functionality in Python is provided by *modules*. The Python Standard Library is a large collection of modules that provides *cross-platform* implementations of common facilities such as access to the operating system, file I/O, string management, network communication, and much more." 23 | ] 24 | }, 25 | { 26 | "cell_type": "markdown", 27 | "metadata": { 28 | "slideshow": { 29 | "slide_type": "subslide" 30 | } 31 | }, 32 | "source": [ 33 | "## References" 34 | ] 35 | }, 36 | { 37 | "cell_type": "markdown", 38 | "metadata": {}, 39 | "source": [ 40 | " * The Python Language Reference: http://docs.python.org/3/reference/index.html\n", 41 | " * The Python Standard Library: http://docs.python.org/3/library/" 42 | ] 43 | }, 44 | { 45 | "cell_type": "markdown", 46 | "metadata": { 47 | "slideshow": { 48 | "slide_type": "fragment" 49 | } 50 | }, 51 | "source": [ 52 | "To use a module in a Python program it first has to be imported. A module can be imported using the `import` statement." 53 | ] 54 | }, 55 | { 56 | "cell_type": "markdown", 57 | "metadata": { 58 | "slideshow": { 59 | "slide_type": "subslide" 60 | } 61 | }, 62 | "source": [ 63 | "For example, to import the module `math`, which contains many standard mathematical functions, we can do:" 64 | ] 65 | }, 66 | { 67 | "cell_type": "code", 68 | "execution_count": 3, 69 | "metadata": { 70 | "collapsed": false 71 | }, 72 | "outputs": [], 73 | "source": [ 74 | "import math" 75 | ] 76 | }, 77 | { 78 | "cell_type": "markdown", 79 | "metadata": {}, 80 | "source": [ 81 | "This includes the whole module and makes it available for use later in the program. " 82 | ] 83 | }, 84 | { 85 | "cell_type": "markdown", 86 | "metadata": { 87 | "slideshow": { 88 | "slide_type": "subslide" 89 | } 90 | }, 91 | "source": [ 92 | "For example, we can do:" 93 | ] 94 | }, 95 | { 96 | "cell_type": "code", 97 | "execution_count": 2, 98 | "metadata": { 99 | "collapsed": false 100 | }, 101 | "outputs": [ 102 | { 103 | "name": "stdout", 104 | "output_type": "stream", 105 | "text": [ 106 | "1.0\n" 107 | ] 108 | } 109 | ], 110 | "source": [ 111 | "import math\n", 112 | "\n", 113 | "x = math.cos(2 * math.pi)\n", 114 | "\n", 115 | "print(x)" 116 | ] 117 | }, 118 | { 119 | "cell_type": "markdown", 120 | "metadata": { 121 | "slideshow": { 122 | "slide_type": "subslide" 123 | } 124 | }, 125 | "source": [ 126 | "Alternatively, we can chose to import all symbols (functions and variables) in a module to the current namespace (so that we don't need to use the prefix \"`math.`\" every time we use something from the `math` module:" 127 | ] 128 | }, 129 | { 130 | "cell_type": "code", 131 | "execution_count": 5, 132 | "metadata": { 133 | "collapsed": false, 134 | "slideshow": { 135 | "slide_type": "fragment" 136 | } 137 | }, 138 | "outputs": [ 139 | { 140 | "name": "stdout", 141 | "output_type": "stream", 142 | "text": [ 143 | "1.0\n" 144 | ] 145 | } 146 | ], 147 | "source": [ 148 | "from math import cos, pi\n", 149 | "\n", 150 | "x = cos(2 * pi)\n", 151 | "\n", 152 | "print(x)" 153 | ] 154 | }, 155 | { 156 | "cell_type": "markdown", 157 | "metadata": { 158 | "slideshow": { 159 | "slide_type": "fragment" 160 | } 161 | }, 162 | "source": [ 163 | "This is called **selective Import**" 164 | ] 165 | }, 166 | { 167 | "cell_type": "markdown", 168 | "metadata": { 169 | "slideshow": { 170 | "slide_type": "subslide" 171 | } 172 | }, 173 | "source": [ 174 | "This pattern can be very convenient, but in large programs that include many modules it is often a good idea to keep the symbols from each module in their own namespaces, by using the `import math` pattern. This would elminate potentially confusing problems with name space collisions." 175 | ] 176 | }, 177 | { 178 | "cell_type": "markdown", 179 | "metadata": { 180 | "slideshow": { 181 | "slide_type": "fragment" 182 | } 183 | }, 184 | "source": [ 185 | "Btw, in case of `namespace collisions` (or to avoid `namespace pollution`) we may use the `as` **keyword**" 186 | ] 187 | }, 188 | { 189 | "cell_type": "code", 190 | "execution_count": 6, 191 | "metadata": { 192 | "collapsed": false, 193 | "slideshow": { 194 | "slide_type": "fragment" 195 | } 196 | }, 197 | "outputs": [], 198 | "source": [ 199 | "from math import cos as cosine # Now the `cos` function can be referenced as `cosine`" 200 | ] 201 | }, 202 | { 203 | "cell_type": "code", 204 | "execution_count": 12, 205 | "metadata": { 206 | "collapsed": false, 207 | "slideshow": { 208 | "slide_type": "fragment" 209 | } 210 | }, 211 | "outputs": [ 212 | { 213 | "data": { 214 | "text/plain": [ 215 | "6.123233995736766e-17" 216 | ] 217 | }, 218 | "execution_count": 12, 219 | "metadata": {}, 220 | "output_type": "execute_result" 221 | } 222 | ], 223 | "source": [ 224 | "cosine(pi/2)" 225 | ] 226 | }, 227 | { 228 | "cell_type": "markdown", 229 | "metadata": { 230 | "slideshow": { 231 | "slide_type": "subslide" 232 | } 233 | }, 234 | "source": [ 235 | "Finally, if we want to import **everything** from a module, we may the `*` character:" 236 | ] 237 | }, 238 | { 239 | "cell_type": "code", 240 | "execution_count": 13, 241 | "metadata": { 242 | "collapsed": false, 243 | "slideshow": { 244 | "slide_type": "fragment" 245 | } 246 | }, 247 | "outputs": [], 248 | "source": [ 249 | "from math import *" 250 | ] 251 | }, 252 | { 253 | "cell_type": "code", 254 | "execution_count": 18, 255 | "metadata": { 256 | "collapsed": false, 257 | "slideshow": { 258 | "slide_type": "fragment" 259 | } 260 | }, 261 | "outputs": [ 262 | { 263 | "name": "stdout", 264 | "output_type": "stream", 265 | "text": [ 266 | "Cosine Function: -1.0\n", 267 | "Sin Function: 1.2246467991473532e-16\n", 268 | "Logarithm: 1.0\n", 269 | "Power function: 27.0\n" 270 | ] 271 | } 272 | ], 273 | "source": [ 274 | "print(\"Cosine Function: \", cos(pi))\n", 275 | "print(\"Sin Function: \", sin(pi))\n", 276 | "print(\"Logarithm: \", log(e))\n", 277 | "print(\"Power function: \", pow(3, 3))" 278 | ] 279 | }, 280 | { 281 | "cell_type": "markdown", 282 | "metadata": { 283 | "slideshow": { 284 | "slide_type": "subslide" 285 | } 286 | }, 287 | "source": [ 288 | "### Looking at what a module contains, and its documentation" 289 | ] 290 | }, 291 | { 292 | "cell_type": "markdown", 293 | "metadata": { 294 | "slideshow": { 295 | "slide_type": "fragment" 296 | } 297 | }, 298 | "source": [ 299 | "Once a module is imported, we can list the symbols it provides using the `dir` function:" 300 | ] 301 | }, 302 | { 303 | "cell_type": "code", 304 | "execution_count": 19, 305 | "metadata": { 306 | "collapsed": false, 307 | "slideshow": { 308 | "slide_type": "fragment" 309 | } 310 | }, 311 | "outputs": [ 312 | { 313 | "name": "stdout", 314 | "output_type": "stream", 315 | "text": [ 316 | "['__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atan2', 'atanh', 'ceil', 'copysign', 'cos', 'cosh', 'degrees', 'e', 'erf', 'erfc', 'exp', 'expm1', 'fabs', 'factorial', 'floor', 'fmod', 'frexp', 'fsum', 'gamma', 'hypot', 'isfinite', 'isinf', 'isnan', 'ldexp', 'lgamma', 'log', 'log10', 'log1p', 'log2', 'modf', 'pi', 'pow', 'radians', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'trunc']\n" 317 | ] 318 | } 319 | ], 320 | "source": [ 321 | "import math\n", 322 | "\n", 323 | "print(dir(math))" 324 | ] 325 | }, 326 | { 327 | "cell_type": "markdown", 328 | "metadata": { 329 | "slideshow": { 330 | "slide_type": "subslide" 331 | } 332 | }, 333 | "source": [ 334 | "And using the function `help` we can get a description of each function (almost .. not all functions have docstrings, as they are technically called, but the vast majority of functions are documented this way). " 335 | ] 336 | }, 337 | { 338 | "cell_type": "code", 339 | "execution_count": 20, 340 | "metadata": { 341 | "collapsed": false, 342 | "slideshow": { 343 | "slide_type": "fragment" 344 | } 345 | }, 346 | "outputs": [ 347 | { 348 | "name": "stdout", 349 | "output_type": "stream", 350 | "text": [ 351 | "Help on built-in function log in module math:\n", 352 | "\n", 353 | "log(...)\n", 354 | " log(x[, base])\n", 355 | " \n", 356 | " Return the logarithm of x to the given base.\n", 357 | " If the base not specified, returns the natural logarithm (base e) of x.\n", 358 | "\n" 359 | ] 360 | } 361 | ], 362 | "source": [ 363 | "help(math.log)" 364 | ] 365 | }, 366 | { 367 | "cell_type": "markdown", 368 | "metadata": { 369 | "slideshow": { 370 | "slide_type": "subslide" 371 | } 372 | }, 373 | "source": [ 374 | "We can also use the `help` function directly on modules: Try\n", 375 | "\n", 376 | " help(math) \n", 377 | "\n", 378 | "Some very useful modules form the Python standard library are `os`, `sys`, `math`, `shutil`, `re`, `subprocess`, `multiprocessing`, `threading`. " 379 | ] 380 | }, 381 | { 382 | "cell_type": "markdown", 383 | "metadata": {}, 384 | "source": [ 385 | "---" 386 | ] 387 | }, 388 | { 389 | "cell_type": "markdown", 390 | "metadata": {}, 391 | "source": [ 392 | "## How Import Works" 393 | ] 394 | }, 395 | { 396 | "cell_type": "markdown", 397 | "metadata": {}, 398 | "source": [ 399 | "Because imports are at the heart of program structure in **Python**, this section goes into more formal detail on the import operation to make this process less abstract.\n", 400 | "\n", 401 | "In more details, this is particularly important as in Python, the import process is **not** just a textual insertions of one file into another. \n", 402 | "\n", 403 | "It really consists of a set of runtime operations that perform three distinct steps the first time a program imports a given file:\n", 404 | "\n", 405 | "1. *Find* the module file\n", 406 | "2. *Compile* it to byte code\n", 407 | "3. *Run* the module's code to build the objects it defines\n", 408 | "\n" 409 | ] 410 | }, 411 | { 412 | "cell_type": "markdown", 413 | "metadata": {}, 414 | "source": [ 415 | "### 1. Find It" 416 | ] 417 | }, 418 | { 419 | "cell_type": "markdown", 420 | "metadata": {}, 421 | "source": [ 422 | "First, Python must locate the (module) file the code is trying to `import` (omitting extension and directory paths).\n", 423 | "\n", 424 | "To do so, Python applies a proper *module search path* algorithm. In particular, Python looks for the module to import in the following directories, and in the following order:\n", 425 | "\n", 426 | "1. The Home Directory of the program\n", 427 | "2. `PYTHONPATH` directories\n", 428 | "3. Standard library directories\n", 429 | "4. The contents of any `.pth` file (if present)\n", 430 | "5. The `site-packages` home of third-party extensions (e.g., `/usr/lib/python3/site-packages/`)\n", 431 | "\n", 432 | "(**More on this, later**)" 433 | ] 434 | }, 435 | { 436 | "cell_type": "markdown", 437 | "metadata": {}, 438 | "source": [ 439 | "### 2. Compile it" 440 | ] 441 | }, 442 | { 443 | "cell_type": "markdown", 444 | "metadata": {}, 445 | "source": [ 446 | "After finding a source code file that matches an import statement by traversing the module search path, Python next compiles it to byte code, if necessary.\n", 447 | "\n", 448 | "In particular, in this step, the two choices are:\n", 449 | "\n", 450 | "* **Compile**: \n", 451 | "\n", 452 | "If the byte code file is older than the source file (i.e., if you’ve changed the source) or was created by a different Python version, Python automatically regenerates the byte code when the program is run.\n", 453 | "\n", 454 | "This model is modified somewhat in Python 3.2+ where byte code files are segregated in a `__pycache__` subdirectory and named with their Python version to avoid contention and recompiles when multiple Pythons are installed. \n", 455 | "\n", 456 | "This obviates the need to check version numbers in the byte code, but the timestamp check is still used to detect changes in the source.\n", 457 | "\n", 458 | "* **Don't Compile**:\n", 459 | "\n", 460 | "If, on the other hand, Python finds a `.pyc` byte code file that is not older than the corresponding `.py` source file and was created by the same Python version, it skips the source-to-byte-code compile step.\n", 461 | "\n", 462 | "In addition, if Python finds only a byte code file on the search path and no source, **it simply loads the byte code directly**.\n", 463 | "\n", 464 | "This means you can ship a program **as just byte code files** and avoid sending source. \n", 465 | "\n", 466 | "In other words, the compile step is *by-passed* if possible to speed program startup." 467 | ] 468 | }, 469 | { 470 | "cell_type": "markdown", 471 | "metadata": {}, 472 | "source": [ 473 | "### 3. Run it" 474 | ] 475 | }, 476 | { 477 | "cell_type": "markdown", 478 | "metadata": {}, 479 | "source": [ 480 | "The final step of an import operation executes the byte code of the module.\n", 481 | "\n", 482 | "All statements in the file are run in turn, from top to bottom, and any assignments made to names during this step generate attributes of the resulting module object. \n", 483 | "\n" 484 | ] 485 | }, 486 | { 487 | "cell_type": "markdown", 488 | "metadata": {}, 489 | "source": [ 490 | "## Modules & Packages" 491 | ] 492 | }, 493 | { 494 | "cell_type": "markdown", 495 | "metadata": {}, 496 | "source": [ 497 | "**Modules** are probably best understood as simply packages of names - i.e., *places to define names you want to make visible to the rest of a system*. \n", 498 | "\n", 499 | "Technically, modules usually correspond to **files**, and Python creates a **module object** to contain all the names assigned in a module file. \n", 500 | "\n", 501 | "But in simple terms, modules are just namespaces (places where names are created), and the names that live in a module are called its *attributes*." 502 | ] 503 | }, 504 | { 505 | "cell_type": "markdown", 506 | "metadata": {}, 507 | "source": [ 508 | "In addition to a module name, an import can name a *directory path*. \n", 509 | "\n", 510 | "A directory of Python code is said to be a **package**, so such imports are known as package imports. \n", 511 | "\n", 512 | "In effect, a package import turns a directory on your computer into another Python namespace, with *attributes* corresponding to the *subdirectories* and *module files* that the directory contains." 513 | ] 514 | }, 515 | { 516 | "cell_type": "markdown", 517 | "metadata": {}, 518 | "source": [ 519 | "### Package Relative Imports" 520 | ] 521 | }, 522 | { 523 | "cell_type": "markdown", 524 | "metadata": {}, 525 | "source": [ 526 | "The coverage of package imports so far has focused mostly on importing package files from *outside* the package.\n", 527 | "\n", 528 | "Within the package itself, imports of same-package files can use the same full path syntax as imports from outside the package. However, package files can also make use of special *intrapackage* search rules to simplify import statements. \n", 529 | "\n", 530 | "That is, rather than listing package import paths, imports within the package can be **relative** to the package." 531 | ] 532 | }, 533 | { 534 | "cell_type": "markdown", 535 | "metadata": {}, 536 | "source": [ 537 | "The way this works is version-dependent: \n", 538 | "\n", 539 | "**Python 2.X** implicitly searches package directories first on imports, while **Python 3.X** requires explicit relative import syntax in order to import from the package directory. \n", 540 | "\n", 541 | "This 3.X change can enhance code readability by making same-package imports more obvious, but it’s also incompatible with 2.X and may break some programs." 542 | ] 543 | }, 544 | { 545 | "cell_type": "markdown", 546 | "metadata": {}, 547 | "source": [ 548 | "#### Python 3.3 changes" 549 | ] 550 | }, 551 | { 552 | "cell_type": "markdown", 553 | "metadata": {}, 554 | "source": [ 555 | "For imports in packages, though, Python 3.X introduces two changes:\n", 556 | "\n", 557 | "* It modifies the module import search path semantics to skip the package’s own directory by default. Imports check only paths on the sys.path search path. These are known as **absolute imports**.\n", 558 | "\n", 559 | "* It extends the syntax of `from` statements to allow them to explicitly request that imports search the package’s directory only, with leading dots. This is known as **relative import** syntax." 560 | ] 561 | }, 562 | { 563 | "cell_type": "markdown", 564 | "metadata": {}, 565 | "source": [ 566 | "Examples:\n", 567 | "\n", 568 | "```python\n", 569 | "\n", 570 | "from . import spam\n", 571 | "\n", 572 | "from .spam import name\n", 573 | "\n", 574 | "```" 575 | ] 576 | }, 577 | { 578 | "cell_type": "markdown", 579 | "metadata": {}, 580 | "source": [ 581 | "### Why Relative Imports?" 582 | ] 583 | }, 584 | { 585 | "cell_type": "markdown", 586 | "metadata": {}, 587 | "source": [ 588 | "Consider the following package directory:\n", 589 | "\n", 590 | "```\n", 591 | " mypkg\\ \n", 592 | " __init__.py\n", 593 | " main.py \n", 594 | " string.py\n", 595 | "```\n", 596 | "\n", 597 | "This defines a package named `mypkg` containing modules named `mypkg.main` and `mypkg.string`. \n", 598 | "\n", 599 | "Now, suppose that the main module tries to import a module named `string`. \n", 600 | "\n", 601 | "In **Python 2.X** and earlier, Python will first look in the mypkg directory to perform a relative import. \n", 602 | "\n", 603 | "It will find and import the `string.py` file located there, assigning it to the name string in the `mypkg.main`\n", 604 | "module’s namespace.\n", 605 | "It could be, though, that the intent of this import was to load the Python standard library’s **string module** instead.\n", 606 | "\n", 607 | "Unfortunately, in these versions of Python, there’s **no straightforward** way to ignore `mypkg.string` and look for the standard library’s string module located on the module search path.\n" 608 | ] 609 | }, 610 | { 611 | "cell_type": "markdown", 612 | "metadata": {}, 613 | "source": [ 614 | "On the other hand, in Python 3.3+, you could:\n", 615 | "\n", 616 | "```python\n", 617 | "\n", 618 | "from string import punctuations # standard library module\n", 619 | "from .string import * # relative import (intrapackage)\n", 620 | "\n", 621 | "```" 622 | ] 623 | } 624 | ], 625 | "metadata": { 626 | "kernelspec": { 627 | "display_name": "Python 3", 628 | "language": "python", 629 | "name": "python3" 630 | }, 631 | "language_info": { 632 | "codemirror_mode": { 633 | "name": "ipython", 634 | "version": 3 635 | }, 636 | "file_extension": ".py", 637 | "mimetype": "text/x-python", 638 | "name": "python", 639 | "nbconvert_exporter": "python", 640 | "pygments_lexer": "ipython3", 641 | "version": "3.5.1" 642 | } 643 | }, 644 | "nbformat": 4, 645 | "nbformat_minor": 0 646 | } 647 | -------------------------------------------------------------------------------- /Index.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "Introduction to Python\n", 8 | "===\n", 9 | "Introduction to Python is a resource for students who want to learn Python as their first language, and for teachers who want a free and open curriculum to use with their students." 10 | ] 11 | }, 12 | { 13 | "cell_type": "markdown", 14 | "metadata": {}, 15 | "source": [ 16 | "## Set Up Your Programming Environment\n", 17 | "\n", 18 | "If your computer is not yet set up to run Python programs, you may consider to take a look at the \n", 19 | "[Programming Environment](00 Programming Environment.ipynb) notebook.\n", 20 | "\n", 21 | "Otherwise, feel free to skip ahead!" 22 | ] 23 | }, 24 | { 25 | "cell_type": "markdown", 26 | "metadata": {}, 27 | "source": [ 28 | "## Start Learning Python\n", 29 | "\n", 30 | "If your computer is already set up to run Python programs, you can get started with [Hello World](01 Hello World.ipynb), to test that everything works properly and fine." 31 | ] 32 | }, 33 | { 34 | "cell_type": "markdown", 35 | "metadata": {}, 36 | "source": [ 37 | "## Contents\n", 38 | "\n", 39 | "Please take a look at the [Table of Contents](toc.ipynb) to see a list of the topics covered throughout the notebooks, along with a brief description of each part." 40 | ] 41 | }, 42 | { 43 | "cell_type": "markdown", 44 | "metadata": {}, 45 | "source": [ 46 | "## Feedback\n", 47 | "\n", 48 | "If you have any questions or comments, feel free to get in touch:\n", 49 | "\n", 50 | "- **Twitter**: [@leriomaggio](https://twitter.com/leriomaggio)\n", 51 | "- **Email**: `valeriomaggio at gmail dot com`\n" 52 | ] 53 | }, 54 | { 55 | "cell_type": "markdown", 56 | "metadata": {}, 57 | "source": [ 58 | "## Contribute\n", 59 | "\n", 60 | "If you already know Python and would like to help contribute to the project, please see the project's [GitHub page](https://github.com/leriomaggio/python-in-a-notebook)." 61 | ] 62 | } 63 | ], 64 | "metadata": { 65 | "kernelspec": { 66 | "display_name": "Python 3", 67 | "language": "python", 68 | "name": "python3" 69 | }, 70 | "language_info": { 71 | "codemirror_mode": { 72 | "name": "ipython", 73 | "version": 3 74 | }, 75 | "file_extension": ".py", 76 | "mimetype": "text/x-python", 77 | "name": "python", 78 | "nbconvert_exporter": "python", 79 | "pygments_lexer": "ipython3", 80 | "version": "3.5.1" 81 | } 82 | }, 83 | "nbformat": 4, 84 | "nbformat_minor": 0 85 | } 86 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Valerio Maggio 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Python in a Notebook # 2 | 3 | This repository contains a curated collection of Jupyter/IPython Notebooks of 4 | introductory materials about programming in Python. 5 | 6 | ## Goals ## 7 | 8 | Available notebooks are intended to aid both students and teachers in learning and teaching 9 | Python programming, respectively. 10 | 11 | In more details, the goals of this project are: 12 | 13 | - Introduce students as quickly as possible to the basics of Python programming; 14 | - Introduce best practice as early as possible, while remaining accessible to students with no background in programming at all; 15 | - Provide teachers an easy-to-use material about programming in Python to be used in their lectures 16 | 17 | ## Running Notebooks ## 18 | 19 | All you need to do to play notebooks is to open a Terminal, and type the following command: 20 | 21 | jupyter notebook 22 | 23 | 24 | **That's it!** :) 25 | 26 | ## Programming Environment 27 | 28 | These notebooks are written primarily in **Python 3**. 29 | 30 | If the default Python on your system is Python 3, then you will have a simpler time contributing to the project. 31 | If you only have Python 2, you might want to consider adding Python 3 to your system. 32 | 33 | In this regards, you may find useful to take a look at the *Programming Environment* [notebook]() where you 34 | could find links and details on how to set up your environment depending on your platform. 35 | 36 | ### Requirements ### 37 | 38 | * Python 3.x (2.x would work as well) 39 | * IPython 4.x (with **notebook support**) or Jupyter: 40 | * `pip install ipython[notebook]` (OR) 41 | * `pip install jupyter` 42 | 43 | 44 | 45 | ## License and Sharing Material 46 | 47 | Creative Commons License
This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License. -------------------------------------------------------------------------------- /Resources and References.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# References" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "Some of the notebooks included in this collection have been borrowed or adapted from the ones available in the [**Introduction to Python**](https://github.com/ehmatthes/intro_programming) project by [Eric Matthes](mailto:ehmatthes@gmail.com)." 15 | ] 16 | }, 17 | { 18 | "cell_type": "markdown", 19 | "metadata": {}, 20 | "source": [ 21 | "Documentation\n", 22 | "---\n", 23 | "\n", 24 | "For information related to Python programming, always refer to the [official Python documentation](https://docs.python.org/3/) (v3.5.1)." 25 | ] 26 | }, 27 | { 28 | "cell_type": "markdown", 29 | "metadata": {}, 30 | "source": [ 31 | " \n", 32 | "#### Exploring the Python Community\n", 33 | "\n", 34 | "As I have said earlier, the Python community is incredibly rich and diverse. Here are a couple resources to look at, if you want to do some exploring.\n", 35 | "\n", 36 | "- [The Python website](http://python.org/)\n", 37 | "\n", 38 | " The main Python website is probably not of too much interest to you at this point, but it is a great resource to know about as you start to learn more.\n", 39 | " \n", 40 | "\n", 41 | "\n", 42 | "- [PyCon](https://us.pycon.org/)\n", 43 | "\n", 44 | " The Python Conference (PyCon) is an incredible event, and the community is entirely welcoming to new programmers. They happen all over the world, throughout the year. If you can make your way to one of these conferences, you will learn a great deal and meet some really interesting people.\n", 45 | " \n", 46 | "\n", 47 | "- [PyCon Italia](http://pycon.it)\n", 48 | "\n", 49 | " PyCon Italia is the Italian Python conference where professionals, researchers and lovers of the most beautiful programming language, gather together.\n", 50 | "\n", 51 | "\n", 52 | " \n", 53 | "- [PyLadies](http://www.pyladies.com/)\n", 54 | "\n", 55 | " Women and minorities are still under-represented in most technology fields, and the programming world is no different in this regard. That said, the Python community may well be the most welcoming and supportive programming community for women and minorities. There are a number of groups dedicated to bringing women and minorities together around programming in Python, and there are a number of explicit Codes of Conduct for Python-related events.\n", 56 | "\n", 57 | " PyLadies is one of the most visible of these organizations. They are a great resource, so go see what they do and what they have to offer.\n", 58 | "\n", 59 | "\n", 60 | " \n", 61 | "- [Python User Groups](https://wiki.python.org/moin/LocalUserGroups)\n", 62 | "\n", 63 | " Wherever there are a number of Python programmers, they will find a way to get together. Python user groups are regular meetings of Python users from a local area. Go take a look at the list of user groups, and see if there is one near you." 64 | ] 65 | }, 66 | { 67 | "cell_type": "markdown", 68 | "metadata": {}, 69 | "source": [ 70 | "---" 71 | ] 72 | }, 73 | { 74 | "cell_type": "markdown", 75 | "metadata": {}, 76 | "source": [ 77 | "Resources\n", 78 | "===\n", 79 | "\n" 80 | ] 81 | }, 82 | { 83 | "cell_type": "markdown", 84 | "metadata": {}, 85 | "source": [ 86 | "A preliminary list of tutorials, talks, and challenges is provided below. This page will be updated frequently.\n" 87 | ] 88 | }, 89 | { 90 | "cell_type": "markdown", 91 | "metadata": {}, 92 | "source": [ 93 | "Tutorials\n", 94 | "--\n", 95 | "\n", 96 | "- Google Python class - YouTube videos\n", 97 | "\n", 98 | " [Part 1(1)](https://www.youtube.com/watch?v=tKTZoB2Vjuk) - Introduction to Python and strings\n", 99 | " \n", 100 | " [Part 1(2)](https://www.youtube.com/watch?v=EPYupizJYQI) - Working with lists, tuples and sorting\n", 101 | " \n", 102 | " [Part 1(3)](https://www.youtube.com/watch?v=haycL41dAhg) - Working with dictionaries and files\n", 103 | " \n", 104 | " [Part 2(1)](https://www.youtube.com/watch?v=kWyoYtvJpe4) - Regular expressions\n", 105 | " \n", 106 | " [Part 2(2)](https://www.youtube.com/watch?v=uKZ8GBKmeDM) - Using modules, system commands\n", 107 | " \n", 108 | " [Part 2(3)](https://www.youtube.com/watch?v=Nn2KQmVF5Og) - Exceptions, parsing URLs\n", 109 | " \n", 110 | " [Part 2(4)](https://www.youtube.com/watch?v=IcteAbMC1Ok) - List comprehensions\n", 111 | "\n", 112 | "\n", 113 | "- [Guide for beginners who are non-programmers](https://wiki.python.org/moin/BeginnersGuide/NonProgrammers)\n", 114 | "\n", 115 | " Python's wiki page lists several resources for beginners.\n", 116 | "\n", 117 | "\n", 118 | "- [Python Tutor](http://pythontutor.com/)\n", 119 | "\n", 120 | " Python Tutor visually helps understand how code executes on a computer." 121 | ] 122 | }, 123 | { 124 | "cell_type": "markdown", 125 | "metadata": {}, 126 | "source": [ 127 | "---" 128 | ] 129 | }, 130 | { 131 | "cell_type": "markdown", 132 | "metadata": {}, 133 | "source": [ 134 | "Talks\n", 135 | "--\n", 136 | "\n", 137 | "Pyvideos - Videos related to Python programming in different events including [Pycon](http://www.pycon.org/), [Scipy](https://conference.scipy.org/).\n", 138 | "\n", 139 | "Example: [Fast Python, Slow Python at Pycon 2014](http://pyvideo.org/video/2627/fast-python-slow-python)" 140 | ] 141 | }, 142 | { 143 | "cell_type": "markdown", 144 | "metadata": {}, 145 | "source": [ 146 | "---" 147 | ] 148 | }, 149 | { 150 | "cell_type": "markdown", 151 | "metadata": {}, 152 | "source": [ 153 | "Challenges\n", 154 | "--\n", 155 | "\n", 156 | "If you are equipped with basics of Python, taking up challenges is a great way to implement the skills.\n", 157 | "\n", 158 | "- [Google Python class exercises](https://developers.google.com/edu/python/exercises/basic)\n", 159 | "\n", 160 | " Four exercises are provided as part of the Python class by Google. \n", 161 | " \n", 162 | " Level - Basic/intermediate\n", 163 | " \n", 164 | "\n", 165 | "- [Project Euler](https://projecteuler.net/)\n", 166 | "\n", 167 | " Project Euler is a project of mathematical/programming challenges aimed at designing efficient solutions. Project Euler is a good place to challenge your mathematical and programming skills. Most of the problems can be solved within few seconds provided you have an efficient solution.\n", 168 | "\n", 169 | " Level - Advanced | Requires knowledge of mathematics.\n", 170 | "\n", 171 | "\n", 172 | "- [Python Challenge](http://www.pythonchallenge.com/)\n", 173 | "\n", 174 | " Level - Intermediate/Advanced\n", 175 | "\n", 176 | "\n", 177 | "\n" 178 | ] 179 | } 180 | ], 181 | "metadata": { 182 | "kernelspec": { 183 | "display_name": "Python 3", 184 | "language": "python", 185 | "name": "python3" 186 | }, 187 | "language_info": { 188 | "codemirror_mode": { 189 | "name": "ipython", 190 | "version": 3 191 | }, 192 | "file_extension": ".py", 193 | "mimetype": "text/x-python", 194 | "name": "python", 195 | "nbconvert_exporter": "python", 196 | "pygments_lexer": "ipython3", 197 | "version": "3.5.1" 198 | } 199 | }, 200 | "nbformat": 4, 201 | "nbformat_minor": 0 202 | } 203 | -------------------------------------------------------------------------------- /The Zen of Python.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "slideshow": { 7 | "slide_type": "slide" 8 | } 9 | }, 10 | "source": [ 11 | "Zen of Python\n", 12 | "===\n", 13 | "The Python community is incredibly large and diverse. People are using Python in science, in medicine, in robotics, on the internet, and in any other field you can imagine. This diverse group of thinkers has developed a collective mindset about how programs should be written. If you want to understand Python and the community of Python programmers, it is a good idea to learn the ways Python programmers think.\n", 14 | "\n", 15 | "You can easily see a set of guiding principles that is written right into the language:" 16 | ] 17 | }, 18 | { 19 | "cell_type": "code", 20 | "execution_count": 1, 21 | "metadata": { 22 | "collapsed": false, 23 | "slideshow": { 24 | "slide_type": "subslide" 25 | } 26 | }, 27 | "outputs": [ 28 | { 29 | "name": "stdout", 30 | "output_type": "stream", 31 | "text": [ 32 | "The Zen of Python, by Tim Peters\n", 33 | "\n", 34 | "Beautiful is better than ugly.\n", 35 | "Explicit is better than implicit.\n", 36 | "Simple is better than complex.\n", 37 | "Complex is better than complicated.\n", 38 | "Flat is better than nested.\n", 39 | "Sparse is better than dense.\n", 40 | "Readability counts.\n", 41 | "Special cases aren't special enough to break the rules.\n", 42 | "Although practicality beats purity.\n", 43 | "Errors should never pass silently.\n", 44 | "Unless explicitly silenced.\n", 45 | "In the face of ambiguity, refuse the temptation to guess.\n", 46 | "There should be one-- and preferably only one --obvious way to do it.\n", 47 | "Although that way may not be obvious at first unless you're Dutch.\n", 48 | "Now is better than never.\n", 49 | "Although never is often better than *right* now.\n", 50 | "If the implementation is hard to explain, it's a bad idea.\n", 51 | "If the implementation is easy to explain, it may be a good idea.\n", 52 | "Namespaces are one honking great idea -- let's do more of those!\n" 53 | ] 54 | } 55 | ], 56 | "source": [ 57 | "import this" 58 | ] 59 | }, 60 | { 61 | "cell_type": "markdown", 62 | "metadata": { 63 | "slideshow": { 64 | "slide_type": "subslide" 65 | } 66 | }, 67 | "source": [ 68 | "There is a lot here. Let's just take a few lines, and see what they mean for you as a new programmer." 69 | ] 70 | }, 71 | { 72 | "cell_type": "markdown", 73 | "metadata": { 74 | "slideshow": { 75 | "slide_type": "fragment" 76 | } 77 | }, 78 | "source": [ 79 | "**Beautiful is better than ugly.**\n", 80 | "\n", 81 | "Python programmers recognize that good code can actually be beautiful. If you come up with a particularly elegant or efficient way to solve a problem, especially a difficult problem, other Python programmers will respect your work and may even call it beautiful. There is beauty in high-level technical work." 82 | ] 83 | }, 84 | { 85 | "cell_type": "markdown", 86 | "metadata": { 87 | "slideshow": { 88 | "slide_type": "fragment" 89 | } 90 | }, 91 | "source": [ 92 | "**Explicit is better than implicit.**\n", 93 | "\n", 94 | "It is better to be clear about what you are doing, than come up with some shorter way to do something that is difficult to understand." 95 | ] 96 | }, 97 | { 98 | "cell_type": "markdown", 99 | "metadata": { 100 | "slideshow": { 101 | "slide_type": "subslide" 102 | } 103 | }, 104 | "source": [ 105 | "**Simple is better than complex.**\n", 106 | "**Complex is better than complicated.**\n", 107 | "\n", 108 | "Keep your code simple whenever possible, but recognize that we sometimes take on really difficult problems for which there are no easy solutions. In those cases, accept the complexity but avoid complication." 109 | ] 110 | }, 111 | { 112 | "cell_type": "markdown", 113 | "metadata": { 114 | "slideshow": { 115 | "slide_type": "fragment" 116 | } 117 | }, 118 | "source": [ 119 | "**Readability counts.**\n", 120 | "\n", 121 | "There are very few interesting and useful programs these days that are written and maintained entirely by one person. Write your code in a way that others can read it as easily as possible, and in a way that you will be able to read and understand it 6 months from now. This includes writing good comments in your code." 122 | ] 123 | }, 124 | { 125 | "cell_type": "markdown", 126 | "metadata": { 127 | "slideshow": { 128 | "slide_type": "subslide" 129 | } 130 | }, 131 | "source": [ 132 | "**There should be one-- and preferably only one --obvious way to do it.**\n", 133 | "\n", 134 | "There are many ways to solve most problems that come up in programming. However, most problems have a standard, well-established approach. Save complexity for when it is needed, and solve problems in the most straightforward way possible." 135 | ] 136 | }, 137 | { 138 | "cell_type": "markdown", 139 | "metadata": { 140 | "slideshow": { 141 | "slide_type": "fragment" 142 | } 143 | }, 144 | "source": [ 145 | "**Now is better than never.**\n", 146 | "\n", 147 | "No one ever writes perfect code. If you have an idea you want to implement it, write some code that works. Release it, let it be used by others, and then steadily improve it." 148 | ] 149 | } 150 | ], 151 | "metadata": { 152 | "kernelspec": { 153 | "display_name": "Python 3", 154 | "language": "python", 155 | "name": "python3" 156 | }, 157 | "language_info": { 158 | "codemirror_mode": { 159 | "name": "ipython", 160 | "version": 3 161 | }, 162 | "file_extension": ".py", 163 | "mimetype": "text/x-python", 164 | "name": "python", 165 | "nbconvert_exporter": "python", 166 | "pygments_lexer": "ipython3", 167 | "version": "3.5.1" 168 | } 169 | }, 170 | "nbformat": 4, 171 | "nbformat_minor": 0 172 | } 173 | -------------------------------------------------------------------------------- /data/data.txt: -------------------------------------------------------------------------------- 1 | bob,devel,50000 2 | sue,music,60000 3 | ann,devel,40000 4 | tim,admin,30000 5 | kim,devel,60000 -------------------------------------------------------------------------------- /data/data2.txt: -------------------------------------------------------------------------------- 1 | bob,developer,80000 2 | sue,music,90000 3 | ann,manager,80000 -------------------------------------------------------------------------------- /data/dbase1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leriomaggio/python-in-a-notebook/ac68538f9a251c56256dd1f126f65534aec3bc9c/data/dbase1 -------------------------------------------------------------------------------- /data/elderlyHeightWeight.csv: -------------------------------------------------------------------------------- 1 | Gender Age body wt ht 2 | F 77 63.8 155.5 3 | F 80 56.4 160.5 4 | F 76 55.2 159.5 5 | F 77 58.5 151 6 | F 82 64 165.5 7 | F 78 51.6 167 8 | F 85 54.6 154 9 | F 83 71 153 10 | M 79 75.5 171 11 | M 75 83.9 178.5 12 | M 79 75.7 167 13 | M 84 72.5 171.5 14 | M 76 56.2 167 15 | M 80 73.4 168.5 16 | M 75 67.7 174.5 17 | M 75 93 168 18 | M 78 95.6 168 19 | M 80 75.6 183.5 20 | -------------------------------------------------------------------------------- /data/male_data.tsv: -------------------------------------------------------------------------------- 1 | M 79 75.5 171 2 | M 75 83.9 178.5 3 | M 79 75.7 167 4 | M 84 72.5 171.5 5 | M 76 56.2 167 6 | M 80 73.4 168.5 7 | M 75 67.7 174.5 8 | M 75 93 168 9 | M 78 95.6 168 10 | M 80 75.6 183.5 11 | -------------------------------------------------------------------------------- /data/new_data.csv: -------------------------------------------------------------------------------- 1 | Gender Age body wt ht ht_m 2 | F 77 63.8 155.5 1.555 3 | F 80 56.4 160.5 1.605 4 | F 76 55.2 159.5 1.595 5 | F 77 58.5 151 1.51 6 | F 82 64 165.5 1.655 7 | F 78 51.6 167 1.67 8 | F 85 54.6 154 1.54 9 | F 83 71 153 1.53 10 | M 79 75.5 171 1.71 11 | M 75 83.9 178.5 1.785 12 | M 79 75.7 167 1.67 13 | M 84 72.5 171.5 1.715 14 | M 76 56.2 167 1.67 15 | M 80 73.4 168.5 1.685 16 | M 75 67.7 174.5 1.745 17 | M 75 93 168 1.68 18 | M 78 95.6 168 1.68 19 | M 80 75.6 183.5 1.835 20 | -------------------------------------------------------------------------------- /data/test.txt: -------------------------------------------------------------------------------- 1 | Line 0 2 | Line 1 3 | Line 2 4 | Line 3 5 | Line 4 6 | Line 5 7 | Line 6 8 | Line 7 9 | Line 8 10 | Line 9 11 | -------------------------------------------------------------------------------- /data/testdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leriomaggio/python-in-a-notebook/ac68538f9a251c56256dd1f126f65534aec3bc9c/data/testdb -------------------------------------------------------------------------------- /files/example.css: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /files/images/command_mode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leriomaggio/python-in-a-notebook/ac68538f9a251c56256dd1f126f65534aec3bc9c/files/images/command_mode.png -------------------------------------------------------------------------------- /files/images/edit_mode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leriomaggio/python-in-a-notebook/ac68538f9a251c56256dd1f126f65534aec3bc9c/files/images/edit_mode.png -------------------------------------------------------------------------------- /files/images/menubar_toolbar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leriomaggio/python-in-a-notebook/ac68538f9a251c56256dd1f126f65534aec3bc9c/files/images/menubar_toolbar.png -------------------------------------------------------------------------------- /files/makedicts.py: -------------------------------------------------------------------------------- 1 | """ 2 | convert list of row tuples to list of row dicts with field name keys 3 | """ 4 | import sqlite3 5 | 6 | def makedicts(cursor, query, params=()): 7 | cursor.execute(query, params) 8 | colnames = [desc[0] for desc in cursor.description] 9 | rowdicts = [dict(zip(colnames, row)) for row in cursor.fetchall()] 10 | return rowdicts 11 | 12 | conn = sqlite3.connect('data/dbase1') 13 | cursor = conn.cursor() 14 | query = 'select name, pay from people where pay < ?' 15 | lowpay = makedicts(cursor, query, [70000]) 16 | for rec in lowpay: 17 | print(rec) 18 | -------------------------------------------------------------------------------- /multiplying.py: -------------------------------------------------------------------------------- 1 | # Save as multiplying.py 2 | 3 | def double(x): 4 | return 2*x 5 | 6 | def triple(x): 7 | return 3*x 8 | 9 | def quadruple(x): 10 | return 4*x 11 | -------------------------------------------------------------------------------- /rocket.py: -------------------------------------------------------------------------------- 1 | from math import sqrt 2 | 3 | class Rocket(): 4 | # Rocket simulates a rocket ship for a game, 5 | # or a physics simulation. 6 | 7 | def __init__(self, x=0, y=0): 8 | # Each rocket has an (x,y) position. 9 | self.x = x 10 | self.y = y 11 | 12 | def move_rocket(self, x_increment=0, y_increment=1): 13 | # Move the rocket according to the paremeters given. 14 | # Default behavior is to move the rocket up one unit. 15 | self.x += x_increment 16 | self.y += y_increment 17 | 18 | def get_distance(self, other_rocket): 19 | # Calculates the distance from this rocket to another rocket, 20 | # and returns that value. 21 | distance = sqrt((self.x-other_rocket.x)**2+(self.y-other_rocket.y)**2) 22 | return distance 23 | 24 | 25 | class Shuttle(Rocket): 26 | # Shuttle simulates a space shuttle, which is really 27 | # just a reusable rocket. 28 | 29 | def __init__(self, x=0, y=0, flights_completed=0): 30 | super().__init__(x, y) 31 | self.flights_completed = flights_completed 32 | --------------------------------------------------------------------------------