Skip to content

Instantly share code, notes, and snippets.

@anandology
Last active December 31, 2015 05:09
Show Gist options
  • Save anandology/7939444 to your computer and use it in GitHub Desktop.
Save anandology/7939444 to your computer and use it in GitHub Desktop.
Advanced Python TrainingDecember 13-14, 2013Global Analytics -- http://nbviewer.ipython.org/gist/anandology/7939444
Display the source blob
Display the rendered blob
Raw
{
"metadata": {
"name": ""
},
"nbformat": 3,
"nbformat_minor": 0,
"worksheets": [
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Advanced Python Training - Day 1\n",
"December 13-14, 2013<br/>\n",
"Global Analytics"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"def f(a, x=[]):\n",
" x.append(a)\n",
" return x\n"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 1
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"f(0, [1, 2])"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 2,
"text": [
"[1, 2, 0]"
]
}
],
"prompt_number": 2
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"f(1)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 3,
"text": [
"[1]"
]
}
],
"prompt_number": 3
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"f(2)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 4,
"text": [
"[1, 2]"
]
}
],
"prompt_number": 4
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Functions in detail**"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"def square(x):\n",
" return x*x\n",
"\n",
"print square(4)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"16\n"
]
}
],
"prompt_number": 5
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"f = square"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 6
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"f"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 7,
"text": [
"<function __main__.square>"
]
}
],
"prompt_number": 7
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"f(4)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 8,
"text": [
"16"
]
}
],
"prompt_number": 8
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"def sum_of_squares(x, y):\n",
" return square(x) + square(y)\n",
"\n",
"print sum_of_squares(3, 4)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"25\n"
]
}
],
"prompt_number": 9
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"def cube(x): return x*x*x\n",
"\n",
"def sum_of_cubes(x, y):\n",
" return cube(x) + cube(y)\n",
"\n",
"print sum_of_cubes(3, 4)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"91\n"
]
}
],
"prompt_number": 10
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"def sumof(f, x, y):\n",
" return f(x) + f(y)\n",
"\n",
"print sumof(square, 3, 4)\n",
"print sumof(cube, 3, 4)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"25\n",
"91\n"
]
}
],
"prompt_number": 11
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"names = [\"C\", \"c++\", \"Python\", \"perl\", \"Haskell\", \"java\"]\n",
"sorted(names)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 13,
"text": [
"['C', 'Haskell', 'Python', 'c++', 'java', 'perl']"
]
}
],
"prompt_number": 13
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"sorted(names, key=len)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 14,
"text": [
"['C', 'c++', 'perl', 'java', 'Python', 'Haskell']"
]
}
],
"prompt_number": 14
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Problem** Write a function `isorted` to sort given names without considering the case.\n",
"\n",
" >>> isorted([\"C\", \"Python\", \"c++\", \"java\", \"Haskell\"])\n",
" [\"C\", \"c++\", \"Haskell\", \"java\", \"Python\"]"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"def lower(s):\n",
" return s.lower()\n",
"\n",
"def isorted(values):\n",
" #return sorted(values, key=lower)\n",
" return sorted(values, key=lambda s: s.lower())\n",
"\n",
"isorted([\"C\", \"Python\", \"c++\", \"java\", \"Haskell\"])\n",
" "
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 17,
"text": [
"['C', 'c++', 'Haskell', 'java', 'Python']"
]
}
],
"prompt_number": 17
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"min(names)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 18,
"text": [
"'C'"
]
}
],
"prompt_number": 18
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"max(names)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 19,
"text": [
"'perl'"
]
}
],
"prompt_number": 19
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"max(names, key=len)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 20,
"text": [
"'Haskell'"
]
}
],
"prompt_number": 20
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Problem** Write a function `maximum` that works like built-in `max` function. It should take an optional keyword argument `key`, when supplied should use `key(x)` and `key(y)` for comparing values `x` and `y`.\n",
"\n",
" >>> maximum([\"Python\", \"Haskell\"])\n",
" 'Python'\n",
" >>> maximum([\"Python\", \"Haskell\"], key=len)\n",
" 'Haskell'"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"def maximum(values, key=None):\n",
" if key is None:\n",
" key = lambda x:x\n",
" max = values[0]\n",
" for v in values:\n",
" if key(v) > key(max):\n",
" max = v\n",
" return max\n",
"\n"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 21
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Example: json_encode**"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"import json\n",
"print json.dumps({\"x\": 1, \"y\": [2, 3, \"hello\", {\"z\": 4}], \"a\": True})"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"{\"y\": [2, 3, \"hello\", {\"z\": 4}], \"x\": 1, \"a\": true}\n"
]
}
],
"prompt_number": 23
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"def json_encode(data):\n",
" if isinstance(data, str):\n",
" return '\"' + data + '\"'\n",
" elif isinstance(data, int):\n",
" return str(data)\n",
" elif isinstance(data, list):\n",
" x = [json_encode(d) for d in data]\n",
" return \"[\" + \", \".join(x) + \"]\"\n",
" \n",
"print json_encode(1)\n",
"print json_encode(\"hello\")\n",
"print json_encode([1, 2, \"hello\", [\"foo\", \"bar\", 3]])"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"1\n",
"\"hello\"\n",
"[1, 2, \"hello\", [\"foo\", \"bar\", 3]]\n"
]
}
],
"prompt_number": 29
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Closures - Inner Functions**"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"def make_adder(x):\n",
" def adder(y):\n",
" return x + y\n",
" return adder\n",
"\n",
"add5 = make_adder(5)\n",
"print add5(3)\n",
"\n",
"add4 = make_adder(4)\n",
"print add4(3)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"8\n",
"7\n"
]
}
],
"prompt_number": 30
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"\"hello\".center(40)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 34,
"text": [
"' hello '"
]
}
],
"prompt_number": 34
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Problem** Write a function make_centeralign, that takes width as argument and returns a new function that takes a string as argument and center align that.\n",
"\n",
" >>> center20 = make_centeralign(20)\n",
" >>> center20('helloworld')\n",
" ' helloworld '"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Functions with variable number of arguments**"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"max(1, 2, 3, 4)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 36,
"text": [
"4"
]
}
],
"prompt_number": 36
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"**Problem** write a function `add` that takes variable number of arguments and computes their sum.\n",
"\n",
" >>> add(1, 2, 3, 4)\n",
" 10\n",
" >>> add(1, 2, 3)\n",
" 6"
],
"language": "python",
"metadata": {},
"outputs": []
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"def add(*args):\n",
" print \"args =\", args\n",
" return sum(args)\n",
"\n",
"print add(1, 2, 3, 4)\n",
"print add(1, 2, 3)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"args = (1, 2, 3, 4)\n",
"10\n",
"args = (1, 2, 3)\n",
"6\n"
]
}
],
"prompt_number": 38
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"def log(level, *args):\n",
" message = \" \".join([str(a) for a in args])\n",
" print \"[%s] %s\" % (level, message)\n",
" \n",
"log(\"INFO\", \"hello world\")\n",
"log(\"DEBUG\", \"square\", 4)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"[INFO] hello world\n",
"[DEBUG] square 4\n"
]
}
],
"prompt_number": 40
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"def info(*args):\n",
" log(\"INFO\", *args)\n",
" \n",
"info(\"hello\", \"world\")"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"[INFO] hello world\n"
]
}
],
"prompt_number": 41
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"def add(x, y):\n",
" return x + y"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 42
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"func = add\n",
"args = [2, 3]\n",
"print func(*args)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"5\n"
]
}
],
"prompt_number": 43
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"max(3, 4, *args)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 44,
"text": [
"4"
]
}
],
"prompt_number": 44
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"def diff(x, y):\n",
" return x - y\n",
"\n",
"print diff(5, 3)\n",
"print diff(5, y=3)\n",
"print diff(x=5, y=3)\n",
"print diff(y=3, x=5)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"2\n",
"2\n",
"2\n",
"2\n"
]
}
],
"prompt_number": 45
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"def mydict(**foo):\n",
" return foo\n",
"\n",
"print mydict(a=1, b=2)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"{'a': 1, 'b': 2}\n"
]
}
],
"prompt_number": 46
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"def render_template(name, **kwargs):\n",
" print \"rendering template %s using %s\" % (name, kwargs)"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 47
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"render_template(\"a.html\", x=1, y=2)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"rendering template a.html using {'y': 2, 'x': 1}\n"
]
}
],
"prompt_number": 48
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Decorators"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"def square(x):\n",
" print \"square\", x\n",
" value = x*x\n",
" print value\n",
" return value\n",
"\n",
"def sum_of_squares(x, y):\n",
" print \"sum_of_squares\", x, y\n",
" return square(x) + square(y)\n",
"\n",
"print sum_of_squares(3, 4)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"sum_of_squares 3 4\n",
"square 3\n",
"9\n",
"square 4\n",
"16\n",
"25\n"
]
}
],
"prompt_number": 52
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"%%file trace1.py\n",
"import os\n",
"\n",
"level = 0\n",
"\n",
"def log(*args):\n",
" if os.getenv(\"DEBUG\"):\n",
" print \" \".join([str(a) for a in args])\n",
"\n",
"def trace(f):\n",
" def g(*args):\n",
" global level\n",
" log(\"| \" * level + \"|--\", f.__name__, args)\n",
" level += 1 \n",
" value = f(*args)\n",
" level -= 1 \n",
" log(\"| \" * level + \"|--\", \"returned\", value)\n",
" return value\n",
" return g"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"Overwriting trace1.py\n"
]
}
],
"prompt_number": 87
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"%%file sumofsquares.py\n",
"from trace1 import trace\n",
"\n",
"@trace\n",
"def square(x):\n",
" return x*x\n",
"\n",
"@trace\n",
"def sum_of_squares(x, y):\n",
" return square(x) + square(y)\n",
"\n",
"#square = trace(square)\n",
"#sum_of_squares = trace(sum_of_squares)\n",
"\n",
"print sum_of_squares(3, 4)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"Overwriting sumofsquares.py\n"
]
}
],
"prompt_number": 93
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"!DEBUG=true python sumofsquares.py"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"|-- sum_of_squares (3, 4)\r\n",
"| |-- square (3,)\r\n",
"| |-- returned 9\r\n",
"| |-- square (4,)\r\n",
"| |-- returned 16\r\n",
"|-- returned 25\r\n",
"25\r\n"
]
}
],
"prompt_number": 96
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"%%file fib1.py\n",
"\n",
"from trace1 import trace\n",
"\n",
"def fib(n):\n",
" if n == 0 or n == 1:\n",
" return 1\n",
" else:\n",
" return fib(n-1) + fib(n-2)\n",
" \n",
"fib = trace(fib)\n",
"print fib(4)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"Overwriting fib1.py\n"
]
}
],
"prompt_number": 95
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"!DEBUG=true python fib1.py"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"|-- fib (4,)\r\n",
"| |-- fib (3,)\r\n",
"| | |-- fib (2,)\r\n",
"| | | |-- fib (1,)\r\n",
"| | | |-- returned 1\r\n",
"| | | |-- fib (0,)\r\n",
"| | | |-- returned 1\r\n",
"| | |-- returned 2\r\n",
"| | |-- fib (1,)\r\n",
"| | |-- returned 1\r\n",
"| |-- returned 3\r\n",
"| |-- fib (2,)\r\n",
"| | |-- fib (1,)\r\n",
"| | |-- returned 1\r\n",
"| | |-- fib (0,)\r\n",
"| | |-- returned 1\r\n",
"| |-- returned 2\r\n",
"|-- returned 5\r\n",
"5\r\n"
]
}
],
"prompt_number": 92
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Problem** Write a decorator function `logtime` to print the amount of time a function is taken to execute.\n",
"\n",
" @logtime\n",
" def timepass(n):\n",
" result = 0\n",
" for i in range(n):\n",
" for j in range(i):\n",
" result += i*j\n",
" return result \n",
" \n",
" print timepass(100)\n",
" # timepass(100) took 0.01 seconds"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"import time\n",
"t1 = time.time()\n",
"for i in range(1000000): \n",
" pass\n",
"t2 = time.time()\n",
"print t2-t1"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"0.115938901901\n"
]
}
],
"prompt_number": 97
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"%%file logtime.py\n",
"import time\n",
"\n",
"def logtime(f):\n",
" def g(*args):\n",
" t1 = time.time()\n",
" result = f(*args)\n",
" t2 = time.time()\n",
" print \"%s%s took %.3f seconds\" % (f.__name__, args, t2-t1)\n",
" return result\n",
" return g\n"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"Overwriting logtime.py\n"
]
}
],
"prompt_number": 104
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"%%file fib0.py\n",
"\n",
"from trace1 import trace\n",
"\n",
"@trace\n",
"def fib(n):\n",
" if n == 0 or n == 1:\n",
" return 1\n",
" else:\n",
" return fib(n-1) + fib(n-2)\n",
"\n",
"if __name__ == \"__main__\": \n",
" import sys\n",
" fib(int(sys.argv[1]))"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"Overwriting fib0.py\n"
]
}
],
"prompt_number": 131
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"!DEBUG=1 time python fib0.py 5"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"|-- fib (5,)\r\n",
"| |-- fib (4,)\r\n",
"| | |-- fib (3,)\r\n",
"| | | |-- fib (2,)\r\n",
"| | | | |-- fib (1,)\r\n",
"| | | | |-- returned 1\r\n",
"| | | | |-- fib (0,)\r\n",
"| | | | |-- returned 1\r\n",
"| | | |-- returned 2\r\n",
"| | | |-- fib (1,)\r\n",
"| | | |-- returned 1\r\n",
"| | |-- returned 3\r\n",
"| | |-- fib (2,)\r\n",
"| | | |-- fib (1,)\r\n",
"| | | |-- returned 1\r\n",
"| | | |-- fib (0,)\r\n",
"| | | |-- returned 1\r\n",
"| | |-- returned 2\r\n",
"| |-- returned 5\r\n",
"| |-- fib (3,)\r\n",
"| | |-- fib (2,)\r\n",
"| | | |-- fib (1,)\r\n",
"| | | |-- returned 1\r\n",
"| | | |-- fib (0,)\r\n",
"| | | |-- returned 1\r\n",
"| | |-- returned 2\r\n",
"| | |-- fib (1,)\r\n",
"| | |-- returned 1\r\n",
"| |-- returned 3\r\n",
"|-- returned 8\r\n"
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
" 0.01 real 0.01 user 0.00 sys\r\n"
]
}
],
"prompt_number": 135
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"%%file memoize.py\n",
"\n",
"def memoize(f):\n",
" cache = {}\n",
" def g(*args):\n",
" if args not in cache:\n",
" cache[args] = f(*args)\n",
" return cache[args]\n",
" return g\n",
"\n"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"Writing memoize.py\n"
]
}
],
"prompt_number": 120
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"%%file fib2.py\n",
"\n",
"from trace1 import trace\n",
"from memoize import memoize\n",
"\n",
"@memoize\n",
"@trace\n",
"def fib(n):\n",
" if n == 0 or n == 1:\n",
" return 1\n",
" else:\n",
" return fib(n-1) + fib(n-2)\n",
"\n",
"if __name__ == \"__main__\": \n",
" import sys\n",
" fib(int(sys.argv[1]))"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"Overwriting fib2.py\n"
]
}
],
"prompt_number": 128
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"!DEBUG=1 python fib2.py 5"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"|-- fib (5,)\r\n",
"| |-- fib (4,)\r\n",
"| | |-- fib (3,)\r\n",
"| | | |-- fib (2,)\r\n",
"| | | | |-- fib (1,)\r\n",
"| | | | |-- returned 1\r\n",
"| | | | |-- fib (0,)\r\n",
"| | | | |-- returned 1\r\n",
"| | | |-- returned 2\r\n",
"| | |-- returned 3\r\n",
"| |-- returned 5\r\n",
"|-- returned 8\r\n"
]
}
],
"prompt_number": 139
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Problem** write a decorator function `with_retries` that retries the function 5 times before giving up.\n",
"\n",
" @with_retries\n",
" def wget(url):\n",
" return urllib2.urlopen(url).read()\n",
" \n",
" wget(\"http://google.com/no-such-page\")\n",
" \n",
"should print something like:\n",
"\n",
" Error Not Found, retrying (1)...\n",
" Error Not Found, retrying (2)...\n",
" Error Not Found, retrying (3)...\n",
" Error Not Found, retrying (4)...\n",
" Error Not Found, retrying (5)...\n",
" Giving up."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"How about passing the number of attempts as argument to `with_retries`? May be another optional `sleeptime` between retries? \n",
"\n",
" @with_retries(attempts=5, sleeptime=5)\n",
" def wget(url):\n",
" return urllib2.urlopen(url).read()\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Lets look at expressions in Python a bit.\n",
"\n",
" (1 + 2) * 3 \n",
"1+2 is evaluated and added to 3\n",
" \n",
" f(x) + 3 \n",
"f(x) is evaluated and added to 3\n",
" \n",
" f(g(x)) \n",
"g(x) is evaulated first and the value is passed to f\n",
"\n",
"It is same as:\n",
" \n",
" tmp = g(x)\n",
" f(tmp)\n",
" \n",
"Similarly\n",
"\n",
" @foo(x)\n",
" def f():\n",
" ...\n",
"is same as:\n",
"\n",
" decor = foo(x)\n",
" @decor\n",
" def f():\n",
" ...\n",
" \n",
"Which is same as:\n",
"\n",
" decor = foo(x)\n",
" def f():\n",
" ...\n",
" f = decor(f)"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"%%file retries.py\n",
"import urllib2\n",
"import time\n",
"\n",
"def with_retries(attempts=5, sleeptime=0):\n",
" def decorator(f):\n",
" def g(*args):\n",
" for i in range(attempts):\n",
" try:\n",
" return f(*args)\n",
" except Exception, e:\n",
" print \"Error %s, retrying... (%d)\" % (e, i+1) \n",
" if sleeptime:\n",
" time.sleep(sleeptime)\n",
" print \"Giving up.\"\n",
" return g\n",
" return decorator\n",
"\n",
"@with_retries(attempts=5, sleeptime=0.1)\n",
"def wget(url):\n",
" return urllib2.urlopen(url).read()\n",
"\n",
"if __name__ == \"__main__\":\n",
" wget(\"http://google.com/no-such-page\")\n",
" "
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"Overwriting retries.py\n"
]
}
],
"prompt_number": 144
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"!python retries.py"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"Error HTTP Error 404: Not Found, retrying... (1)\r\n"
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"Error HTTP Error 404: Not Found, retrying... (2)\r\n"
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"Error HTTP Error 404: Not Found, retrying... (3)\r\n"
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"Error HTTP Error 404: Not Found, retrying... (4)\r\n"
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"Error HTTP Error 404: Not Found, retrying... (5)\r\n"
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"Giving up.\r\n"
]
}
],
"prompt_number": 145
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"A trick to make it look simpler."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"%%file retries2.py\n",
"import urllib2\n",
"import time\n",
"\n",
"def with_retries(f=None, attempts=5, sleeptime=0):\n",
" print \"with_retries\", f, attempts, sleeptime\n",
" if f is None:\n",
" return lambda f: with_retries(f, attempts, sleeptime)\n",
"\n",
" print \"defining g\" \n",
" def g(*args):\n",
" for i in range(attempts):\n",
" try:\n",
" return f(*args)\n",
" except Exception, e:\n",
" print \"Error %s, retrying... (%d)\" % (e, i+1) \n",
" if sleeptime:\n",
" time.sleep(sleeptime)\n",
" print \"Giving up.\"\n",
" return g\n",
"\n",
"@with_retries(attempts=5, sleeptime=0.1)\n",
"def wget(url):\n",
" return urllib2.urlopen(url).read()\n",
"\n",
"if __name__ == \"__main__\":\n",
" wget(\"http://google.com/no-such-page\")\n",
" "
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"Writing retries2.py\n"
]
}
],
"prompt_number": 146
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"!python retries2.py"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"with_retries None 5 0.1\r\n",
"with_retries <function wget at 0x1005d8b18> 5 0.1\r\n",
"defining g\r\n"
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"Error HTTP Error 404: Not Found, retrying... (1)\r\n"
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"Error HTTP Error 404: Not Found, retrying... (2)\r\n"
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"Error HTTP Error 404: Not Found, retrying... (3)\r\n"
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"Error HTTP Error 404: Not Found, retrying... (4)\r\n"
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"Error HTTP Error 404: Not Found, retrying... (5)\r\n"
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"Giving up.\r\n"
]
}
],
"prompt_number": 147
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Problem** Write a decorator `ignore_exception` that takes exception type as argument and ignores if that exception is raised by the function being decorated. (The new function should return `None` in case of exception).\n",
"\n",
" @ignore_exception(IOError)\n",
" def readfile(filename):\n",
" return open(filename).read()\n",
" "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Minor issues**"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"def debug(f):\n",
" def g(*a):\n",
" print f.__name__, a\n",
" return f(*a)\n",
" return g\n",
"\n",
"def square1(x):\n",
" \"\"\"Computes square of a number.\"\"\"\n",
" return x*x\n",
"\n",
"@debug\n",
"def square2(x):\n",
" \"\"\"Computes square of a number.\"\"\"\n",
" return x*x\n",
"\n",
"print square1\n",
"print square2"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"<function square1 at 0x1023a3140>\n",
"<function g at 0x103f1a578>\n"
]
}
],
"prompt_number": 148
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"help(square1)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"Help on function square1 in module __main__:\n",
"\n",
"square1(x)\n",
" Computes square of a number.\n",
"\n"
]
}
],
"prompt_number": 149
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"help(square2)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"Help on function g in module __main__:\n",
"\n",
"g(*a)\n",
"\n"
]
}
],
"prompt_number": 150
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The `functools.wraps` functions fixes that."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"import functools\n",
"\n",
"def debug(f):\n",
" @functools.wraps(f)\n",
" def g(*a):\n",
" print f.__name__, a\n",
" return f(*a)\n",
" return g\n",
"\n",
"\n",
"@debug\n",
"def square3(x):\n",
" \"\"\"Computes square of a number.\"\"\"\n",
" return x*x\n",
"\n",
"print square1\n",
"print square2\n",
"print square3\n",
"help(square3)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"<function square1 at 0x1023a3140>\n",
"<function g at 0x103f1a578>\n",
"<function square3 at 0x103f1a758>\n",
"Help on function square3 in module __main__:\n",
"\n",
"square3(*a)\n",
" Computes square of a number.\n",
"\n"
]
}
],
"prompt_number": 155
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Classes"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"class Foo:\n",
" x = 1\n",
"\n",
"f1 = Foo()\n",
"f2 = Foo()\n",
"print Foo.x, f1.x, f2.x"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"1 1 1\n"
]
}
],
"prompt_number": 156
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"f2.x = 2\n",
"print Foo.x, f1.x, f2.x"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"1 1 2\n"
]
}
],
"prompt_number": 157
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"Foo.x = 3\n",
"print Foo.x, f1.x, f2.x"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"3 3 2\n"
]
}
],
"prompt_number": 158
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"How does Python stores default values for functions?"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"def incr(x, amount=1):\n",
" return x+amount"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 159
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"incr"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 160,
"text": [
"<function __main__.incr>"
]
}
],
"prompt_number": 160
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"dir(incr)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 161,
"text": [
"['__call__',\n",
" '__class__',\n",
" '__closure__',\n",
" '__code__',\n",
" '__defaults__',\n",
" '__delattr__',\n",
" '__dict__',\n",
" '__doc__',\n",
" '__format__',\n",
" '__get__',\n",
" '__getattribute__',\n",
" '__globals__',\n",
" '__hash__',\n",
" '__init__',\n",
" '__module__',\n",
" '__name__',\n",
" '__new__',\n",
" '__reduce__',\n",
" '__reduce_ex__',\n",
" '__repr__',\n",
" '__setattr__',\n",
" '__sizeof__',\n",
" '__str__',\n",
" '__subclasshook__',\n",
" 'func_closure',\n",
" 'func_code',\n",
" 'func_defaults',\n",
" 'func_dict',\n",
" 'func_doc',\n",
" 'func_globals',\n",
" 'func_name']"
]
}
],
"prompt_number": 161
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"incr.__defaults__"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 162,
"text": [
"(1,)"
]
}
],
"prompt_number": 162
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"incr.__defaults__ = (5,)"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 163
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"incr(4)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 164,
"text": [
"9"
]
}
],
"prompt_number": 164
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"incr.__name__"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 165,
"text": [
"'incr'"
]
}
],
"prompt_number": 165
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"incr.__name__ = \"not_incr\""
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 166
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"incr"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 167,
"text": [
"<function __main__.not_incr>"
]
}
],
"prompt_number": 167
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"%%file numbers.txt\n",
"1 one\n",
"2 two\n",
"3 three\n",
"4 four\n",
"5 five\n"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"Overwriting numbers.txt\n"
]
}
],
"prompt_number": 170
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"def wordcount(fileobj):\n",
" lc = len(fileobj.readlines())\n",
" fileobj.seek(0)\n",
" wc = len(fileobj.read().split())\n",
" fileobj.seek(0) \n",
" cc = len(fileobj.read())\n",
" print lc, wc, cc\n",
" \n",
"print wordcount(open('numbers.txt'))"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"5 10 33\n",
"None\n"
]
}
],
"prompt_number": 172
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"class FakeFile:\n",
" def __init__(self, lines):\n",
" self.lines = lines\n",
" \n",
" def readlines(self):\n",
" return self.lines\n",
" \n",
" def read(self):\n",
" return \"\".join(self.lines)\n",
" \n",
" def seek(self, pos):\n",
" pass\n",
" \n",
"ff = FakeFile([\"one\\n\", \"two\\n\", \"three\\n\", \"four \\n\"]) \n",
" "
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 173
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"wordcount(ff)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"4 4 20\n"
]
}
],
"prompt_number": 174
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Problem** Write a class UpperCaseFile that takes a file object as argument and behaves like a file, but returns all the contents in uppercase.\n",
"\n",
" f = UpperCaseFile(open(\"numbers.txt\"))\n",
" f.readline() # should return \"1 ONE\\n\""
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Special class methods**"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"class Point:\n",
" def __init__(self, x, y):\n",
" self.x = x\n",
" self.y = y\n",
" \n",
" def __str__(self):\n",
" return \"(%s, %s)\" % (self.x, self.y)"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 178
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"p1 = Point(1, 2)\n",
"p2 = Point(3, 4)"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 179
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"print p1"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"(1, 2)\n"
]
}
],
"prompt_number": 180
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"print [p1, p2]"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"[<__main__.Point instance at 0x103f3f320>, <__main__.Point instance at 0x103f3f200>]\n"
]
}
],
"prompt_number": 181
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"print [1, \"1\"]"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"[1, '1']\n"
]
}
],
"prompt_number": 182
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"print str(1)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"1\n"
]
}
],
"prompt_number": 183
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"print str('1')"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"1\n"
]
}
],
"prompt_number": 184
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"print repr(1), repr('1')"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"1 '1'\n"
]
}
],
"prompt_number": 185
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"class Point2:\n",
" def __init__(self, x, y):\n",
" self.x = x\n",
" self.y = y\n",
" \n",
" def __str__(self):\n",
" return \"(%s, %s)\" % (self.x, self.y)\n",
" \n",
" def __repr__(self):\n",
" return \"Point(%s, %s)\" % (self.x, self.y)\n",
" \n",
"p1 = Point2(1, 2)\n",
"p2 = Point2(3, 4)\n",
"print p1, p2\n",
"print [p1, p2]"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"(1, 2) (3, 4)\n",
"[Point(1, 2), Point(3, 4)]\n"
]
}
],
"prompt_number": 187
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Adding support for +** "
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"x = 1\n",
"y = 2\n",
"print x+y"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"3\n"
]
}
],
"prompt_number": 189
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"x.__add__(y)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 190,
"text": [
"3"
]
}
],
"prompt_number": 190
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"class Point3:\n",
" def __init__(self, x, y):\n",
" self.x = x\n",
" self.y = y\n",
" \n",
" def __add__(self, p):\n",
" return Point3(self.x+p.x, self.y+p.y)\n",
" \n",
" def __str__(self):\n",
" return \"(%s, %s)\" % (self.x, self.y)\n",
" \n",
" def __repr__(self):\n",
" return \"Point(%s, %s)\" % (self.x, self.y)\n",
" \n",
"p1 = Point3(1, 2)\n",
"p2 = Point3(3, 4)\n",
"print p1, p2\n",
"print [p1, p2]\n",
"print p1+p2"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"(1, 2) (3, 4)\n",
"[Point(1, 2), Point(3, 4)]\n",
"(4, 6)\n"
]
}
],
"prompt_number": 192
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"What happens when we call a function?\n",
"\n",
" square(5)"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"square.__call__(5)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 193,
"text": [
"25"
]
}
],
"prompt_number": 193
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"x = [1, 2, 3, 4]\n",
"x[3]"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 194,
"text": [
"4"
]
}
],
"prompt_number": 194
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"x.__getitem__(3)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 195,
"text": [
"4"
]
}
],
"prompt_number": 195
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"class Adder:\n",
" def __init__(self, x):\n",
" self.x = x\n",
" \n",
" def __call__(self, y):\n",
" return self.x + y\n",
"\n",
"add5 = Adder(5)\n",
"print add5(4)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"9\n"
]
}
],
"prompt_number": 196
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Implement `logtime` decorator as a class with `__call__` method."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Remember that, the following:\n",
"\n",
" @logtime\n",
" def timepass():\n",
" ...\n",
" \n",
" print timepass()\n",
"\n",
"is equivalant to:\n",
"\n",
" def timepass():\n",
" ...\n",
" \n",
" timepass = logtime(timepass)\n",
" \n",
" print timepass()\n",
" \n",
"So, the constructor of logtime class get the function as argument."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [],
"language": "python",
"metadata": {},
"outputs": []
}
],
"metadata": {}
}
]
}
Display the source blob
Display the rendered blob
Raw
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment