Created
May 25, 2013 11:36
-
-
Save anandology/5648789 to your computer and use it in GitHub Desktop.
Notes from Advanced Python Workshop.
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
{ | |
"metadata": { | |
"name": "2 - Functional Programming (Advanced Python Workshop)" | |
}, | |
"nbformat": 3, | |
"nbformat_minor": 0, | |
"worksheets": [ | |
{ | |
"cells": [ | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"# Functional Programming" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"## Variable arguments and Keyword arguments" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"max(1, 2, 3, 4)" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "pyout", | |
"prompt_number": 3, | |
"text": [ | |
"4" | |
] | |
} | |
], | |
"prompt_number": 3 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"dict(a=1, b=2)" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "pyout", | |
"prompt_number": 4, | |
"text": [ | |
"{'a': 1, 'b': 2}" | |
] | |
} | |
], | |
"prompt_number": 4 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"def add(*args): \n", | |
" return sum(args)\n", | |
"\n", | |
"print add(1, 2, 3, 4)" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"10\n" | |
] | |
} | |
], | |
"prompt_number": 5 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"def mydict(**kwargs):\n", | |
" return kwargs\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": 6 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"def render_tag(tagname, **attrs):\n", | |
" pairs = [\"%s=%s\" % (k,v) for k, v in attrs.items()]\n", | |
" return \"<%s %s/>\" % (tagname, \" \".join(pairs))\n", | |
"\n", | |
"render_tag(\"input\", type=\"text\", name=\"x\", id=\"x\")" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "pyout", | |
"prompt_number": 10, | |
"text": [ | |
"'<input type=text name=x id=x/>'" | |
] | |
} | |
], | |
"prompt_number": 10 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"numbers = [1, 2, 3, 4]\n", | |
"print add(*numbers)" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"10\n" | |
] | |
} | |
], | |
"prompt_number": 11 | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"**Problem:** Write a function `call_func(f, *args, **kwargs)`, that calls the given function f with args and kwargs.\n", | |
"\n", | |
" def square(x): \n", | |
" return x*x\n", | |
" print call_func(square, 2)\n", | |
" print call_func(square, x=2)\n", | |
"\n", | |
" def add(a, b): \n", | |
" return a + b\n", | |
" print call_func(add, 2, 3)\n", | |
"\n", | |
" print call_func(max, 2, 3, 4, 5, 6, 7)\n", | |
" print call_func(dict, a=1, b=2, c=3)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"def add(a, b): return a+b\n", | |
"args=[1]\n", | |
"kwargs={\"b\": 2}\n", | |
"\n", | |
"print add(*args, **kwargs)" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"3\n" | |
] | |
} | |
], | |
"prompt_number": 14 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"def call_fun(f, *args, **kwargs):\n", | |
" return f(*args, **kwargs)" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 15 | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"## Back to Decorators " | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"import time\n", | |
"def timeit(f):\n", | |
" def g():\n", | |
" t0 = time.time()\n", | |
" value = f()\n", | |
" t1 = time.time()\n", | |
" print \"took %f seconds\" % (t1-t0)\n", | |
" return value\n", | |
" return g\n", | |
"\n", | |
"def timepass():\n", | |
" for i in range(10000):\n", | |
" for j in range(1000):\n", | |
" x = i*j\n", | |
" return 0\n", | |
"\n", | |
"def timepass2(n):\n", | |
" for i in range(n):\n", | |
" for j in range(1000):\n", | |
" x = i*j\n", | |
" return 0\n", | |
"\n", | |
"\n", | |
"timepass = timeit(timepass)\n", | |
"print timepass()\n", | |
"\n", | |
"import urllib\n", | |
"@timeit\n", | |
"def wget(url):\n", | |
" return urllib.urlopen(url).read()\n", | |
"\n", | |
"x = wget(\"http://python.org\")\n" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"ename": "TypeError", | |
"evalue": "g() takes no arguments (1 given)", | |
"output_type": "pyerr", | |
"traceback": [ | |
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", | |
"\u001b[0;32m<ipython-input-21-868cc2b3e2d9>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[1;32m 30\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0murllib\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0murlopen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0murl\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mread\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 31\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 32\u001b[0;31m \u001b[0mx\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mwget\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"http://python.org\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", | |
"\u001b[0;31mTypeError\u001b[0m: g() takes no arguments (1 given)" | |
] | |
}, | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"took 0.772692 seconds\n", | |
"0\n" | |
] | |
} | |
], | |
"prompt_number": 21 | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"**Problem:** Write a decorator `vectorize`, that takes a function working on single value and make it work on a list.\n", | |
"\n", | |
" @vectorize\n", | |
" def square(x):\n", | |
" return x*x\n", | |
"\n", | |
" print square([1, 2, 3, 4]) # should print [1, 4, 9, 16]" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"### Example: Web Framework" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"%%file bicycle.py\n", | |
"mapping = []\n", | |
"before_hooks = []\n", | |
"\n", | |
"def request(url):\n", | |
" for path, func in mapping:\n", | |
" if path == url:\n", | |
" for h in before_hooks:\n", | |
" h(url)\n", | |
" return func()\n", | |
" \n", | |
" return \"404 - Not Found\"\n", | |
" \n", | |
"def route(path):\n", | |
" def decorator(f):\n", | |
" mapping.append((path, f))\n", | |
" return f\n", | |
" return decorator\n", | |
"\n", | |
"def before_request(f):\n", | |
" before_hooks.append(f)\n", | |
" return f" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"Overwriting bicycle.py\n" | |
] | |
} | |
], | |
"prompt_number": 6 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"from bicycle import route, request, before_request\n", | |
"import time\n", | |
"\n", | |
"@route(\"/hello\")\n", | |
"def hello():\n", | |
" return \"Hello, world\"\n", | |
"\n", | |
"@route(\"/bye\")\n", | |
"def bye():\n", | |
" return \"Goodbye\"\n", | |
"\n", | |
"@before_request\n", | |
"def log(url):\n", | |
" print time.asctime(), url\n", | |
"\n", | |
"if __name__ == \"__main__\":\n", | |
" print \"MAIN\"\n", | |
" print request(\"/hello\") # should print \"Hello, world\"\n", | |
" print request(\"/bye\")\n", | |
" print request(\"/foo\")" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"MAIN\n", | |
"Sat May 25 10:53:05 2013 /hello\n", | |
"Hello, world\n", | |
"Sat May 25 10:53:05 2013 /bye\n", | |
"Goodbye\n", | |
"404 - Not Found\n" | |
] | |
} | |
], | |
"prompt_number": 8 | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"### Example: writing command line apps using decorators" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"%%file command0.py\n", | |
"def command(f):\n", | |
" def g(filenames, **kw):\n", | |
" lines = readfiles(filenames)\n", | |
" #lines = (outline for line in lines \n", | |
" # for outline in f(line, **kw))\n", | |
" lines = generate_output(f, lines, **kwargs)\n", | |
" printlines(lines)\n", | |
" return g\n", | |
"\n", | |
"def generate_output(f, lines, **kwargs):\n", | |
" for line in lines:\n", | |
" for outline in f(line, **kwargs):\n", | |
" yield outline\n", | |
"\n", | |
"def readfiles(filenames):\n", | |
" for f in filenames:\n", | |
" for line in open(f):\n", | |
" yield line\n", | |
"\n", | |
"def printlines(lines):\n", | |
" for line in lines:\n", | |
" print line.strip(\"\\n\")" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"Overwriting command0.py\n" | |
] | |
} | |
], | |
"prompt_number": 44 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"%%file uppercase.py\n", | |
"from command0 import command\n", | |
"\n", | |
"@command\n", | |
"def uppercase(line):\n", | |
" yield line.upper()\n", | |
"\n", | |
"if __name__ == \"__main__\":\n", | |
" import sys\n", | |
" uppercase(sys.argv[1:])" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"Overwriting uppercase.py\n" | |
] | |
} | |
], | |
"prompt_number": 36 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"!python uppercase.py uppercase.py" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"FROM COMMAND0 IMPORT COMMAND\r\n", | |
"\r\n", | |
"@COMMAND\r\n", | |
"DEF UPPERCASE(LINE):\r\n", | |
" YIELD LINE.UPPER()\r\n", | |
"\r\n", | |
"IF __NAME__ == \"__MAIN__\":\r\n", | |
" IMPORT SYS\r\n", | |
" UPPERCASE(SYS.ARGV[1:])\r\n" | |
] | |
} | |
], | |
"prompt_number": 37 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"%%file grep.py\n", | |
"from command0 import command\n", | |
"\n", | |
"@command\n", | |
"def grep(line, pattern):\n", | |
" if pattern in line:\n", | |
" yield line\n", | |
" \n", | |
"if __name__ == \"__main__\":\n", | |
" import sys\n", | |
" pattern = sys.argv[1]\n", | |
" filenames = sys.argv[2:]\n", | |
" grep(filenames, pattern=pattern)\n" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"Overwriting grep.py\n" | |
] | |
} | |
], | |
"prompt_number": 38 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"!python grep.py def grep.py" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"def grep(line, pattern):\r\n" | |
] | |
} | |
], | |
"prompt_number": 39 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"%%file twice.py\n", | |
"from command0 import command\n", | |
"\n", | |
"@command\n", | |
"def twice(line):\n", | |
" yield line\n", | |
" yield line\n", | |
" \n", | |
"if __name__ == \"__main__\":\n", | |
" import sys\n", | |
" twice(sys.argv[1:])" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"Overwriting twice.py\n" | |
] | |
} | |
], | |
"prompt_number": 42 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"!python twice.py twice.py" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"from command0 import command\r\n", | |
"from command0 import command\r\n", | |
"\r\n", | |
"\r\n", | |
"@command\r\n", | |
"@command\r\n", | |
"def twice(line):\r\n", | |
"def twice(line):\r\n", | |
" yield line\r\n", | |
" yield line\r\n", | |
" yield line\r\n", | |
" yield line\r\n", | |
" \r\n", | |
" \r\n", | |
"if __name__ == \"__main__\":\r\n", | |
"if __name__ == \"__main__\":\r\n", | |
" import sys\r\n", | |
" import sys\r\n", | |
" twice(sys.argv[1:])\r\n", | |
" twice(sys.argv[1:])\r\n" | |
] | |
} | |
], | |
"prompt_number": 43 | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"### `exec` and `eval`" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"code = \"x = 1\"\n", | |
"exec(code)\n", | |
"print x" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"1\n" | |
] | |
} | |
], | |
"prompt_number": 45 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"eval(\"1 + 2\")" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "pyout", | |
"prompt_number": 46, | |
"text": [ | |
"3" | |
] | |
} | |
], | |
"prompt_number": 46 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"env = {\"x\": 2}\n", | |
"eval(\"x + 2\", env)" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "pyout", | |
"prompt_number": 47, | |
"text": [ | |
"4" | |
] | |
} | |
], | |
"prompt_number": 47 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [] | |
} | |
], | |
"metadata": {} | |
} | |
] | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment