Last active
October 28, 2015 16:23
-
-
Save jailuthra/e254d53c22d51637b448 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"cells": [ | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"## Decorators and Functional Programming in Python\n", | |
"\n", | |
"Derived from the notebook: http://anandology.com/nb/2014/decorators-demystified/ (Was a workshop in Pycon India '14)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 1, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"16\n" | |
] | |
} | |
], | |
"source": [ | |
"def square(x):\n", | |
" return x*x\n", | |
"\n", | |
"print(square(4))\n" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 2, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"<function square at 0x7f8fdd684ae8>\n" | |
] | |
} | |
], | |
"source": [ | |
"print(square)\n" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 3, | |
"metadata": { | |
"collapsed": true | |
}, | |
"outputs": [], | |
"source": [ | |
"f = square" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 4, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"<function square at 0x7f8fdd684ae8>\n" | |
] | |
} | |
], | |
"source": [ | |
"print(f)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"They're called first-class objects" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 5, | |
"metadata": { | |
"collapsed": true | |
}, | |
"outputs": [], | |
"source": [ | |
"def sum_of_square(x, y):\n", | |
" return square(x) + square(y)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 6, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"25" | |
] | |
}, | |
"execution_count": 6, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"sum_of_square(3,4)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 7, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"13" | |
] | |
}, | |
"execution_count": 7, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"def sum_of(f, x, y):\n", | |
" return f(x) + f(y)\n", | |
"\n", | |
"sum_of(square, 2, 3)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 8, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"3" | |
] | |
}, | |
"execution_count": 8, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"def mod3(x):\n", | |
" return x % 3\n", | |
"\n", | |
"sum_of(mod3, 4, 5)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 9, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"3" | |
] | |
}, | |
"execution_count": 9, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"sum_of(lambda x: x %3, 4, 5)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 10, | |
"metadata": { | |
"collapsed": true | |
}, | |
"outputs": [], | |
"source": [ | |
"mod4 = lambda x: x % 4\n" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 11, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"1" | |
] | |
}, | |
"execution_count": 11, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"mod4(17)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 12, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"<function <lambda> at 0x7f8fdce3a158>\n" | |
] | |
} | |
], | |
"source": [ | |
"print(lambda x: x % 4)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 13, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"'Haskell'" | |
] | |
}, | |
"execution_count": 13, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"max([\"Python\", \"Haskell\"], key=len)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 14, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"<built-in function len>\n" | |
] | |
} | |
], | |
"source": [ | |
"print(len)\n" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 15, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"True\n", | |
"False\n" | |
] | |
} | |
], | |
"source": [ | |
"len(\"Python\")\n", | |
"print(\"python\" > \"haskell\")\n", | |
"print(len(\"python\") > len(\"haskell\"))" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 16, | |
"metadata": { | |
"collapsed": true | |
}, | |
"outputs": [], | |
"source": [ | |
"def incr(x, amount=1):\n", | |
" return x + amount" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 17, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"5" | |
] | |
}, | |
"execution_count": 17, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"incr(4)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 18, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"6" | |
] | |
}, | |
"execution_count": 18, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"incr(4, 2)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 19, | |
"metadata": { | |
"collapsed": true | |
}, | |
"outputs": [], | |
"source": [ | |
"def sub(x, y):\n", | |
" return x-y\n" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 20, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"-2" | |
] | |
}, | |
"execution_count": 20, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"sub(3, 5)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 21, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"-2" | |
] | |
}, | |
"execution_count": 21, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"sub(x=3, y=5)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 22, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"-2" | |
] | |
}, | |
"execution_count": 22, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"sub(y=5, x=3)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 23, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"5" | |
] | |
}, | |
"execution_count": 23, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"max(1,2,3,4,5)\n" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 24, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"(2, 3, 5)\n", | |
"(8, 1)\n" | |
] | |
} | |
], | |
"source": [ | |
"def f(*args):\n", | |
" print(args)\n", | |
" \n", | |
"f(2,3,5)\n", | |
"f(8,1)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 25, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [], | |
"source": [ | |
"def xprint(label, *args):\n", | |
" print(type(args))\n", | |
" for a in args:\n", | |
" print(label, a)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 26, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"<class 'tuple'>\n", | |
"Info 1\n", | |
"Info 2\n", | |
"Info 3\n" | |
] | |
} | |
], | |
"source": [ | |
"xprint(\"Info\", 1,2,3)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"\n", | |
"\n", | |
"**Problem** Implement a function maximum that takes 2 values x and y and a key function as argument and finds the maximum by comparing key(x) and key(y).\n", | |
"\n", | |
" >>> maximum(3, -4, abs)\n", | |
" -4\n", | |
" >>> maximum(\"Python\", \"Haskell\", len)\n", | |
" 'Haskell'\n", | |
" >>> maximum(\"java\", \"Python\", lambda s: s.lower())\n", | |
" 'Python'\n", | |
"\n", | |
"\n", | |
"\n", | |
"**Problem** Write a function strjoin that takes a separator as first argument followed by variable number of strings to join with that separator.\n", | |
"```\n", | |
">>> strjoin(\"-\", \"a\", \"b\", \"c\")\n", | |
"\"a-b-c\"\n", | |
"```\n" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 27, | |
"metadata": { | |
"collapsed": true | |
}, | |
"outputs": [], | |
"source": [ | |
"def maximum(*args, key=lambda x: x):\n", | |
" best = args[0]\n", | |
" for i in args:\n", | |
" if (key(i) > key(best)):\n", | |
" best = i\n", | |
" return best\n" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 28, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"'Haskell'" | |
] | |
}, | |
"execution_count": 28, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"maximum('aloo', 'python', 'z', 'Haskell', key=len)\n" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 29, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"'a-b-c'" | |
] | |
}, | |
"execution_count": 29, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"def strjoin(sep, *args):\n", | |
" return sep.join(args)\n", | |
"\n", | |
"strjoin(\"-\", \"a\", \"b\", \"c\")" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 30, | |
"metadata": { | |
"collapsed": true | |
}, | |
"outputs": [], | |
"source": [ | |
"# Just like variable args, you can have variable keword args too, just use ** instead of *\n", | |
"\n", | |
"def f(**kwargs):\n", | |
" print(kwargs)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 31, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"{'abcd': 3, 'y': 2, 'x': 1}\n" | |
] | |
} | |
], | |
"source": [ | |
"f(x=1, y=2, abcd=3)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 32, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"[2, 3, 4, 5]" | |
] | |
}, | |
"execution_count": 32, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"[int(x) for x in '2 3 4 5'.split()] # List comprehension" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 33, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"[('href', 'http://iiitd.ac.in'), ('title', 'IIIT-D')]" | |
] | |
}, | |
"execution_count": 33, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"[(k,v) for k, v in {'title': 'IIIT-D', 'href': 'http://iiitd.ac.in'}.items()]\n" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 34, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"'Hey jai'" | |
] | |
}, | |
"execution_count": 34, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"\"Hey %s\" % ('jai')" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"**Problem** Make a function `render_tag(tagname, **attrs)` that returns a html tag as a string\n", | |
"\n", | |
" >>> render_tag(\"a\", href=\"http://iiitd.ac.in\", title=\"IIIT-D\")\n", | |
" '<a href=\"http://iiitd.ac.in\", title=\"IIIT-D\">'" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 35, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [], | |
"source": [ | |
"def render_tag(tagname, **attrs):\n", | |
" pairs = ['%s=\"%s\"' % (k,v) for k, v in attrs.items()]\n", | |
" pairs_str = \" \".join(pairs)\n", | |
" return \"<%s %s>\" % (tagname, pairs_str)\n" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 36, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"'<a href=\"http://iiitd.ac.in\" title=\"IIIT-D\">'" | |
] | |
}, | |
"execution_count": 36, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"render_tag(\"a\", href=\"http://iiitd.ac.in\", title=\"IIIT-D\")" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 37, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [], | |
"source": [ | |
"# Currying\n", | |
"def make_adder(x):\n", | |
" def add(y):\n", | |
" return x + y\n", | |
" return add" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 38, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"7" | |
] | |
}, | |
"execution_count": 38, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"add5 = make_adder(5)\n", | |
"add5(2)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 39, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"13" | |
] | |
}, | |
"execution_count": 39, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"add6 = make_adder(6)\n", | |
"add6(7)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 40, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"13" | |
] | |
}, | |
"execution_count": 40, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"make_adder(8)(5)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"## Decorators" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 41, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"Overwriting trace0.py\n" | |
] | |
} | |
], | |
"source": [ | |
"%%file trace0.py\n", | |
"\n", | |
"def trace(f):\n", | |
" def wrapper(*args):\n", | |
" print(f.__name__, args)\n", | |
" return f(*args)\n", | |
" return wrapper" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 42, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"Overwriting sum.py\n" | |
] | |
} | |
], | |
"source": [ | |
"%%file sum.py\n", | |
"\n", | |
"from trace0 import trace\n", | |
"\n", | |
"@trace\n", | |
"def square(x):\n", | |
" # print(\"square\", x)a\n", | |
" return x*x\n", | |
"\n", | |
"#square = trace(square)\n", | |
"\n", | |
"@trace\n", | |
"def sum_of_squares(x, y):\n", | |
" # print(\"sum_of_squares\", x, y)\n", | |
" return square(x) + square(y)\n", | |
"\n", | |
"#sum_of_squares = trace(sum_of_squares)\n", | |
"\n", | |
"print(sum_of_squares(3,4))" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 43, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"sum_of_squares (3, 4)\r\n", | |
"square (3,)\r\n", | |
"square (4,)\r\n", | |
"25\r\n" | |
] | |
} | |
], | |
"source": [ | |
"!python sum.py" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 44, | |
"metadata": { | |
"collapsed": false, | |
"scrolled": true | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"Overwriting trace1.py\n" | |
] | |
} | |
], | |
"source": [ | |
"%%file trace1.py\n", | |
"\n", | |
"level = 0\n", | |
"\n", | |
"def trace(f):\n", | |
" def wrapper(*args):\n", | |
" global level\n", | |
" print(\"| \" * level + \"|--\", f.__name__, args)\n", | |
" \n", | |
" level += 1\n", | |
" result = f(*args)\n", | |
" level -= 1\n", | |
" \n", | |
" return result\n", | |
" return wrapper" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 45, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"Overwriting fibo.py\n" | |
] | |
} | |
], | |
"source": [ | |
"%%file fibo.py\n", | |
"\n", | |
"from trace1 import trace\n", | |
"from memoize import memoize\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", | |
"print(fib(7))" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 46, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"|-- fib (7,)\r\n", | |
"| |-- fib (6,)\r\n", | |
"| | |-- fib (5,)\r\n", | |
"| | | |-- fib (4,)\r\n", | |
"| | | | |-- fib (3,)\r\n", | |
"| | | | | |-- fib (2,)\r\n", | |
"| | | | | | |-- fib (1,)\r\n", | |
"| | | | | | |-- fib (0,)\r\n", | |
"| | | | | |-- fib (1,)\r\n", | |
"| | | | |-- fib (2,)\r\n", | |
"| | | | | |-- fib (1,)\r\n", | |
"| | | | | |-- fib (0,)\r\n", | |
"| | | |-- fib (3,)\r\n", | |
"| | | | |-- fib (2,)\r\n", | |
"| | | | | |-- fib (1,)\r\n", | |
"| | | | | |-- fib (0,)\r\n", | |
"| | | | |-- fib (1,)\r\n", | |
"| | |-- fib (4,)\r\n", | |
"| | | |-- fib (3,)\r\n", | |
"| | | | |-- fib (2,)\r\n", | |
"| | | | | |-- fib (1,)\r\n", | |
"| | | | | |-- fib (0,)\r\n", | |
"| | | | |-- fib (1,)\r\n", | |
"| | | |-- fib (2,)\r\n", | |
"| | | | |-- fib (1,)\r\n", | |
"| | | | |-- fib (0,)\r\n", | |
"| |-- fib (5,)\r\n", | |
"| | |-- fib (4,)\r\n", | |
"| | | |-- fib (3,)\r\n", | |
"| | | | |-- fib (2,)\r\n", | |
"| | | | | |-- fib (1,)\r\n", | |
"| | | | | |-- fib (0,)\r\n", | |
"| | | | |-- fib (1,)\r\n", | |
"| | | |-- fib (2,)\r\n", | |
"| | | | |-- fib (1,)\r\n", | |
"| | | | |-- fib (0,)\r\n", | |
"| | |-- fib (3,)\r\n", | |
"| | | |-- fib (2,)\r\n", | |
"| | | | |-- fib (1,)\r\n", | |
"| | | | |-- fib (0,)\r\n", | |
"| | | |-- fib (1,)\r\n", | |
"21\r\n" | |
] | |
} | |
], | |
"source": [ | |
"!python fibo.py" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 47, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"Overwriting memoize.py\n" | |
] | |
} | |
], | |
"source": [ | |
"%%file memoize.py\n", | |
"\n", | |
"def memoize(f):\n", | |
" \n", | |
" cache = {}\n", | |
" \n", | |
" def wrapper(*args):\n", | |
" if args not in cache:\n", | |
" cache[args] = f(*args)\n", | |
" return cache[args]\n", | |
" return wrapper" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 48, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"Overwriting fibo1.py\n" | |
] | |
} | |
], | |
"source": [ | |
"%%file fibo1.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", | |
"print(fib(7))" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 49, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"|-- fib (7,)\r\n", | |
"| |-- fib (6,)\r\n", | |
"| | |-- fib (5,)\r\n", | |
"| | | |-- fib (4,)\r\n", | |
"| | | | |-- fib (3,)\r\n", | |
"| | | | | |-- fib (2,)\r\n", | |
"| | | | | | |-- fib (1,)\r\n", | |
"| | | | | | |-- fib (0,)\r\n", | |
"21\r\n" | |
] | |
} | |
], | |
"source": [ | |
"!python fibo1.py" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"**Problem**\n", | |
"Write a function with_retries that continue to retry for 5 times if there is any exception raised in the function.\n", | |
"\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", | |
"\n", | |
"Should print:\n", | |
"\n", | |
"```\n", | |
"Failed to download, retrying...\n", | |
"Failed to download, retrying...\n", | |
"Failed to download, retrying...\n", | |
"Failed to download, retrying...\n", | |
"Failed to download, retrying...\n", | |
"Giving up!\n", | |
"```" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 50, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"Overwriting with_retries.py\n" | |
] | |
} | |
], | |
"source": [ | |
"%%file with_retries.py\n", | |
"\n", | |
"import urllib.request\n", | |
"\n", | |
"def with_retries(f, num):\n", | |
" def wrapper(*args):\n", | |
" for i in range(num):\n", | |
" try:\n", | |
" return f(*args)\n", | |
" except:\n", | |
" print(\"Failed\")\n", | |
" print(\"Given up!\")\n", | |
" return wrapper\n", | |
"\n", | |
"#@with_retries\n", | |
"def wget(url):\n", | |
" return urllib.request.urlopen(url)\n", | |
"\n", | |
"wget = with_retries(wget, 7)\n", | |
"x = wget(\"http://google.com/pageisnonexistent\")" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 51, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"Failed\n", | |
"Failed\n", | |
"Failed\n", | |
"Failed\n", | |
"Failed\n", | |
"Failed\n", | |
"Failed\n", | |
"Given up!\n" | |
] | |
} | |
], | |
"source": [ | |
"!python with_retries.py" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 52, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"Overwriting with_retries_adv.py\n" | |
] | |
} | |
], | |
"source": [ | |
"%%file with_retries_adv.py\n", | |
"\n", | |
"def with_retries(num):\n", | |
" def decor(f):\n", | |
" def wrapper(*args):\n", | |
" for i in range(num):\n", | |
" try:\n", | |
" return f(*args)\n", | |
" except:\n", | |
" print(\"failed\")\n", | |
" print(\"given up!\")\n", | |
" return wrapper\n", | |
" return decor\n", | |
"\n", | |
"@with_retries(3)\n", | |
"def wget(url):\n", | |
" return urllib.request.urlopen(url)\n", | |
"\n", | |
"# wget = with_retries(3)(wget)\n", | |
"\n", | |
"x = wget(\"http://google.com/pageisnonexistent\")" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 53, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"failed\r\n", | |
"failed\r\n", | |
"failed\r\n", | |
"given up!\r\n" | |
] | |
} | |
], | |
"source": [ | |
"!python with_retries_adv.py" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"## Web framework - JUG (nano flask)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 54, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"Overwriting jug.py\n" | |
] | |
} | |
], | |
"source": [ | |
"%%file jug.py\n", | |
"\n", | |
"mapping = []\n", | |
"\n", | |
"def route(path):\n", | |
" def decor(f):\n", | |
" mapping.append((path, f))\n", | |
" return decor\n", | |
"\n", | |
"def request(path):\n", | |
" for p, func in mapping:\n", | |
" if p == path:\n", | |
" return func()\n", | |
" return \"404\"\n", | |
"\n", | |
"def wsgifunc(env, start_response):\n", | |
" path = env['PATH_INFO']\n", | |
" start_response('200 OK', [(\"Content-Type\", \"text/plain\")])\n", | |
" return [request(path).encode('utf-8')]\n", | |
"\n", | |
"def run(port=8080):\n", | |
" from wsgiref.simple_server import make_server\n", | |
" server = make_server(\"0.0.0.0\", port, wsgifunc)\n", | |
" server.serve_forever()" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 55, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"Overwriting hello.py\n" | |
] | |
} | |
], | |
"source": [ | |
"%%file hello.py\n", | |
"\n", | |
"from jug import route\n", | |
"\n", | |
"@route('/hello')\n", | |
"def hello():\n", | |
" return \"Hello! :D\"\n", | |
"\n", | |
"@route('/bye')\n", | |
"def bye():\n", | |
" return \"Good bye!\"\n" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 56, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"Overwriting client.py\n" | |
] | |
} | |
], | |
"source": [ | |
"%%file client.py\n", | |
"import hello\n", | |
"from jug import request, run\n", | |
"import sys\n", | |
"\n", | |
"if \"--web\" in sys.argv:\n", | |
" run()\n", | |
"else:\n", | |
" print(request(\"/hello\"))\n", | |
" print(request(\"/bye\"))\n" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 57, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"Hello! :D\r\n", | |
"Good bye!\r\n" | |
] | |
} | |
], | |
"source": [ | |
"!python client.py" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 59, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"127.0.0.1 - - [28/Oct/2015 21:49:49] \"GET /hello HTTP/1.1\" 200 9\n", | |
"^CTraceback (most recent call last):\n", | |
" File \"client.py\", line 6, in <module>\n", | |
" run()\n", | |
" File \"/home/darkapex/decorators/jug.py\", line 23, in run\n", | |
" server.serve_forever()\n", | |
" File \"/usr/lib/python3.5/socketserver.py\", line 237, in serve_forever\n", | |
" ready = selector.select(poll_interval)\n", | |
" File \"/usr/lib/python3.5/selectors.py\", line 367, in select\n", | |
" fd_event_list = self._poll.poll(timeout)\n", | |
"KeyboardInterrupt\n", | |
"\n" | |
] | |
} | |
], | |
"source": [ | |
"!python client.py --web " | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": { | |
"collapsed": true | |
}, | |
"outputs": [], | |
"source": [] | |
} | |
], | |
"metadata": { | |
"kernelspec": { | |
"display_name": "Python 3", | |
"language": "python", | |
"name": "python3" | |
}, | |
"language_info": { | |
"codemirror_mode": { | |
"name": "ipython", | |
"version": 3 | |
}, | |
"file_extension": ".py", | |
"mimetype": "text/x-python", | |
"name": "python", | |
"nbconvert_exporter": "python", | |
"pygments_lexer": "ipython3", | |
"version": "3.5.0" | |
} | |
}, | |
"nbformat": 4, | |
"nbformat_minor": 0 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment