Commit aacb7519 authored by Ben Glocker's avatar Ben Glocker
Browse files

intro notebook

parents
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Introduction to Python for Algorithms 202"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"by *James Booth* and *Ghislain Antony Vaillant*"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Disclaimer"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This notebook is by no means a comprehensive introduction to the Python programming language. It covers the essential language features required to implement, test and validate the Algorithms 202 courseworks. It is strongly advised to complement this tutorial with additional reading such as the [official Python documentation](https://docs.python.org/3/), [Python 101](https://leanpub.com/python_101) or the excellent [Hitchhiker's guide to Python](http://docs.python-guide.org/en/latest/)."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Getting set up"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"To use this notebook, you'll first need to install miniconda. To get set up you can follow the start of the [instructions given here for Windows, OS X, and Linux](http://www.menpo.org/installation/). Only go as far as 'Setting Up A Fresh Environment' then jump back here to install the stuff we need (not menpo).\n",
"\n",
"- Create a Python environment with all the code we need in it\n",
"\n",
"```\n",
"> conda create -n algo202 python=3 pip setuptools wheel matplotlib jupyter\n",
"```\n",
"- Activate the environment. On OS X/Linux, simply run:\n",
"```\n",
"> source activate algo202\n",
"```\n",
"on Windows:\n",
"```\n",
"> activate algo202\n",
"```\n",
"- Finally install the line_profiler tool (you can read more about that at our [blog post](http://www.menpo.org/blog/2014/05/line_profiler_ipython/))\n",
"```\n",
"(algo202) > pip install line_profiler\n",
"```\n",
"- Now we are all set up. In the future you only need to reactivate the environment to get to work. To run this notebook, launch a Jupyter notebook server, and browse to this downloaded file\n",
"```\n",
"(algo202) > jupyter notebook\n",
"```\n",
"- To navigate through the notebook, have a look at this [cheatsheet](https://www.cheatography.com/weidadeyue/cheat-sheets/jupyter-notebook/)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Language basics"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Syntax and features"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Hello world"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(\"Hello, world!\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Built-in [functions](https://docs.python.org/3/library/functions.html)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(\"Hello, world!\")\n",
"print(\"Hello,\", \"world!\")\n",
"print(\"{}, {}!\".format(\"Hello\", \"world\"))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"help(print)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"type(1.0)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"assert(2 % 2 == 0)\n",
"#assert(2 / 2 == 0)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Built-in [types](https://docs.python.org/3/library/stdtypes.html)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Booleans\n",
"B = True\n",
"print(type(B))\n",
"\n",
"# Numeric types\n",
"N = 1\n",
"print(type(N))\n",
"\n",
"N = 1.0\n",
"print(type(N))\n",
"\n",
"N = 1j\n",
"print(type(N))\n",
"\n",
"# Strings\n",
"N = \"Hello, word\"\n",
"print(type(N))\n",
"\n",
"# Lists\n",
"L = [False, 1.0, \"Hello\"]\n",
"print(type(L))\n",
"\n",
"# Ranges\n",
"R = range(10)\n",
"print(type(R))\n",
"\n",
"# None\n",
"print(type(None))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Dynamic typing"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"x = 3 # Defines a binding a variable named \"x\",\n",
" # to an object of type integer with value 3.\n",
"print('x is of type {} with value {}'.format(type(x), x))\n",
"\n",
"x = 2.0 # Redefine the binding between \"x\" and an\n",
" # object of type float with value 2.0.\n",
"print('x is of type {} with value {}'.format(type(x), x))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Strong typing"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(1 + '2') # What is the intent here? \n",
" # \"Explicit is better than implicit.\""
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(str(1) + '2') # String concatenation.\n",
"print(1 + int('2')) # Integer summation."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Variables and scopes"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"a = 0\n",
"\n",
"if False:\n",
" b = 1\n",
"\n",
"def my_function(c):\n",
" d = 3\n",
" print(a) # a is global\n",
" print(b) # b is global\n",
" print(c) # c is local\n",
" print(d) # d is local\n",
"\n",
"my_function(2)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Control flow"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### `if` statements"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"# simple branching\n",
"if condition:\n",
" do_something()\n",
"\n",
"# 2-way branching\n",
"if condition:\n",
" do_something()\n",
"else:\n",
" do_other_thing()\n",
"\n",
"# switch-case style\n",
"if condition:\n",
" do_something()\n",
"elif other_condition:\n",
" do_other_thing()\n",
"else:\n",
" do_default_thing()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### `while` statements"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"# loop until\n",
"while condition:\n",
" do_something()\n",
"\n",
"# loop until with break clause\n",
"while condition:\n",
" do_something()\n",
" if specific_condition:\n",
" break # exit while loop regardless\n",
" do_other_thing()\n",
"\n",
"# loop until with break clause\n",
"while condition:\n",
" do_something()\n",
" if specific_condition:\n",
" continue # loop-back regardless\n",
" do_other_thing()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### `for` statements"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"for n in range(10):\n",
" print(n)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"numbers = [1, 2, 3]\n",
"for number in numbers:\n",
" print(number)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"ingredients = ['carrots', 'leeks', 'potatoes']\n",
"for index, ingredient in enumerate(ingredients):\n",
" print(index, ingredient)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Data structures"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Common concepts"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# literals\n",
"vowels = ['a', 'e', 'i', 'o', 'u', 'y']\n",
"print('vowels: {}'.format(vowels))\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# indexing\n",
"print('the first vowel is: ' + vowels[0])\n",
"print('the last vowel is: ' + vowels[-1])\n",
"print('the second-to-last vowel is: ' + vowels[-2])"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# slicing\n",
"print('first three: {}'.format(vowels[:3]))\n",
"print('last two: {}'.format(vowels[-2:]))\n",
"print('middle ones: {}'.format(vowels[1:-1]))\n",
"print('one each two: {}'.format(vowels[::2]))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# iteration\n",
"for vowel in vowels:\n",
" print(vowel.upper())"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# enumeration\n",
"for index, vowel in enumerate(vowels):\n",
" print(\"vowel {} is {}\".format(1+index, vowel))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Immutable sequences"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"vowels = ('a', 'e', 'i', 'o', 'u', 'y')\n",
"print(type(vowels))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"vowels[1] = 'b'"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Mutable sequences"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"vowels = ['a', 'e', 'i', 'o', 'u', 'y']\n",
"print(type(vowels))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"vowels[1] = 'b'\n",
"print(vowels)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Dictionaries"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# build using literal construct: {k1: v1, k2:v2}\n",
"D = {\"one\": 1, \n",
" \"two\": 2, \n",
" \"three\": 3}\n",
"\n",
"print('D: {}'.format(D))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# indexing\n",
"print(D[\"one\"])\n",
"print(D[\"two\"])\n",
"print(D[\"three\"])"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# iterating\n",
"for item in D.items():\n",
" print(item)\n",
"\n",
"for key in D.keys():\n",
" print(key)\n",
"\n",
"for value in D.values():\n",
" print(value)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Functions"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"# Standard definiton\n",
"def my_function(arg1, arg2):\n",
" # Do something with arg1, arg2\n",
" # ...\n",
" return result"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Lambda definition\n",
"x_power_x = lambda x: x**x\n",
"print(x_power_x(2))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Application: Complexity analysis of bubble sort"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Implementation"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def bubble_sort(L):\n",
" \"\"\"\n",
" Sorts the input list inplace using a deterministic version of the bubble sort algorithm [1].\n",
" \n",
" [1] https://en.wikipedia.org/wiki/Bubble_sort\n",
" \"\"\"\n",
" max_pass = len(L) - 1\n",
" for pass_num in range(max_pass):\n",
" for i in range(max_pass-pass_num):\n",
" if L[i+1] < L[i]:\n",
" L[i], L[i+1] = L[i+1], L[i]\n",
" return L\n",
"\n",
"\n",
"def my_sorted(iterable):\n",
" \"\"\"\n",
" Returns the sorted elements of the iterable as a list.\n",
" \"\"\"\n",
" return bubble_sort(list(iterable))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Unit testing"
]
},
{
"cell_type": "code",
"execution_count": null,