Last active
December 28, 2015 06:59
-
-
Save anandology/7460837 to your computer and use it in GitHub Desktop.
Advanced Python Workshop - Nov 2013
http://advancedpython.hasgeek.com/
This file contains hidden or 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
Notes from Advanced Python Workshop by Anand Chitipothu conducted on Nov 14-16, 2013 |
This file contains hidden or 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": "" | |
}, | |
"nbformat": 3, | |
"nbformat_minor": 0, | |
"worksheets": [ | |
{ | |
"cells": [ | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"# Advanced Python Workshop - Day 2\n", | |
"Nov 14, 2013<br/>\n", | |
"http://advancedpython.hasgeek.com/" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"## Pyhton Classes Explained\n", | |
"\n", | |
"http://anandology.com/apy/slides/classes.html" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"**Ducktyping**" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"%%file numbers.txt\n", | |
"one\n", | |
"two\n", | |
"three\n", | |
"four\n", | |
"five\n" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"Overwriting numbers.txt\n" | |
] | |
} | |
], | |
"prompt_number": 6 | |
}, | |
{ | |
"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", | |
" return lc, wc, cc\n", | |
"\n", | |
"print wordcount(open(\"numbers.txt\"))" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"(5, 5, 23)\n" | |
] | |
} | |
], | |
"prompt_number": 7 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"# Lets try with a fake file\n", | |
"\n", | |
"class FakeFile:\n", | |
" def readlines(self):\n", | |
" return [\"one\\n\", \"two\\n\", \"three\\n\", \"four\\n\", \"five\"]\n", | |
" def read(self):\n", | |
" return \"one\\ntwo\\nthree\\nfour\\nfive\"\n", | |
" def seek(self, pos):\n", | |
" pass\n", | |
" \n", | |
"print wordcount(FakeFile())" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"(5, 5, 23)\n" | |
] | |
} | |
], | |
"prompt_number": 8 | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"**Problem** Write a class `UpperCaseFile`, that takes a file object as argument and behaves like a file, but returns contents from the given file after converting them to upper case.\n", | |
"\n", | |
" f = UpperCaseFile(open(\"numbers.txt\"))\n", | |
" line = f.readline() # should give \"ONE\\n\"\n" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"**Special class methods**" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"class Person:\n", | |
" def __init__(self, name):\n", | |
" self.name = name\n", | |
" \n", | |
"p = Person(\"Joe\") \n", | |
"print p\n", | |
"print [p]\n", | |
"print p.name" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"<__main__.Person instance at 0x101b75a28>\n", | |
"[<__main__.Person instance at 0x101b75a28>]\n", | |
"Joe\n" | |
] | |
} | |
], | |
"prompt_number": 15 | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"What do we need to do to make it print better." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"class Person:\n", | |
" def __init__(self, name):\n", | |
" self.name = name\n", | |
"\n", | |
" def __str__(self):\n", | |
" return self.name\n", | |
" \n", | |
"p = Person(\"Joe\") \n", | |
"print p\n", | |
"print [p] \n", | |
"print str(p), repr(p)" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"Joe\n", | |
"[<__main__.Person instance at 0x101b75b90>]\n", | |
"Joe <__main__.Person instance at 0x101b75b90>\n" | |
] | |
} | |
], | |
"prompt_number": 18 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"print str(1), repr(1)" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"1 1\n" | |
] | |
} | |
], | |
"prompt_number": 19 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"print str(\"x\"), repr(\"x\")" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"x 'x'\n" | |
] | |
} | |
], | |
"prompt_number": 22 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"[1, \"x\"]" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"metadata": {}, | |
"output_type": "pyout", | |
"prompt_number": 23, | |
"text": [ | |
"[1, 'x']" | |
] | |
} | |
], | |
"prompt_number": 23 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"[1, \"2\", \"x\"]" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"metadata": {}, | |
"output_type": "pyout", | |
"prompt_number": 24, | |
"text": [ | |
"[1, '2', 'x']" | |
] | |
} | |
], | |
"prompt_number": 24 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"class Person:\n", | |
" def __init__(self, name):\n", | |
" self.name = name\n", | |
"\n", | |
" def __str__(self):\n", | |
" return self.name\n", | |
"\n", | |
" def __repr__(self):\n", | |
" return \"<Person: %r>\" % self.name\n", | |
" \n", | |
"p = Person(\"Joe\") \n", | |
"print p\n", | |
"print [p] \n", | |
"print str(p), repr(p)" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"Joe\n", | |
"[<Person: 'Joe'>]\n", | |
"Joe <Person: 'Joe'>\n" | |
] | |
} | |
], | |
"prompt_number": 25 | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"If you omit `__str__` and provide `__repr__`, the `__repr__` is used for `__str__`." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"class Person:\n", | |
" def __init__(self, name):\n", | |
" self.name = name\n", | |
"\n", | |
" def __repr__(self):\n", | |
" return \"<Person: %r>\" % self.name\n", | |
" \n", | |
"p = Person(\"Joe\") \n", | |
"print p\n", | |
"print [p] \n", | |
"print str(p), repr(p)" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"<Person: 'Joe'>\n", | |
"[<Person: 'Joe'>]\n", | |
"<Person: 'Joe'> <Person: 'Joe'>\n" | |
] | |
} | |
], | |
"prompt_number": 26 | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"Can we make our objects responds to operators like `+`, `-` etc?" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"x = 1\n", | |
"print x + 1" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"2\n" | |
] | |
} | |
], | |
"prompt_number": 27 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"print x.__add__(1)" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"2\n" | |
] | |
} | |
], | |
"prompt_number": 28 | |
}, | |
{ | |
"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 __add__(self, p):\n", | |
" return Point(self.x+p.x, self.y+p.y)\n", | |
" \n", | |
" def __repr__(self):\n", | |
" return \"Point(%d, %d)\" % (self.x, self.y)" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 31 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"p1 = Point(1, 2)\n", | |
"p2 = Point(4, 8)\n", | |
"\n", | |
"print p1+p2" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"Point(5, 10)\n" | |
] | |
} | |
], | |
"prompt_number": 32 | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"You can make your objects respond to all most all operators by implementing the required `__` method in the class." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"x = [1, 2]\n", | |
"print x[1]" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"2\n" | |
] | |
} | |
], | |
"prompt_number": 33 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"print x.__getitem__(1)" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"2\n" | |
] | |
} | |
], | |
"prompt_number": 34 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"x[1] = 4\n", | |
"print x" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"[1, 4]\n" | |
] | |
} | |
], | |
"prompt_number": 35 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"x.__setitem__(1, 8)\n", | |
"print x" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"[1, 8]\n" | |
] | |
} | |
], | |
"prompt_number": 37 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"type(1).__getitem__" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"ename": "AttributeError", | |
"evalue": "type object 'int' has no attribute '__getitem__'", | |
"output_type": "pyerr", | |
"traceback": [ | |
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[0;31mAttributeError\u001b[0m Traceback (most recent call last)", | |
"\u001b[0;32m<ipython-input-39-95b00c8355e7>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mtype\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m__getitem__\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", | |
"\u001b[0;31mAttributeError\u001b[0m: type object 'int' has no attribute '__getitem__'" | |
] | |
} | |
], | |
"prompt_number": 39 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"type(\"hello\").__getitem__" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"metadata": {}, | |
"output_type": "pyout", | |
"prompt_number": 40, | |
"text": [ | |
"<slot wrapper '__getitem__' of 'str' objects>" | |
] | |
} | |
], | |
"prompt_number": 40 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"def square(x): return x*x" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 41 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"print square(4)" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"16\n" | |
] | |
} | |
], | |
"prompt_number": 42 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"print square.__call__(4)" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"16\n" | |
] | |
} | |
], | |
"prompt_number": 43 | |
}, | |
{ | |
"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": 45 | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"**Problem** Implement the `debug` decorator that we did yesterday as a class with `__call__`." | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"# Iterators and Generators" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"We can use for statement with lists." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"for x in [1, 2, 3, 4]:\n", | |
" print x" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"1\n", | |
"2\n", | |
"3\n", | |
"4\n" | |
] | |
} | |
], | |
"prompt_number": 46 | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"with strings" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"for c in \"hello\":\n", | |
" print c" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"h\n", | |
"e\n", | |
"l\n", | |
"l\n", | |
"o\n" | |
] | |
} | |
], | |
"prompt_number": 47 | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"with dictionaries" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"for k in {\"x\": 1, \"y\": 2}:\n", | |
" print k" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"y\n", | |
"x\n" | |
] | |
} | |
], | |
"prompt_number": 48 | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"even with files" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"for line in open(\"numbers.txt\"):\n", | |
" print repr(line)" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"'one\\n'\n", | |
"'two\\n'\n", | |
"'three\\n'\n", | |
"'four\\n'\n", | |
"'five'\n" | |
] | |
} | |
], | |
"prompt_number": 50 | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"How does this work? Can we write our own class that works with for loop?" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"Also, there are other builtin functions that work with all these objects." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"min([1, 2, 3, 4])" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"metadata": {}, | |
"output_type": "pyout", | |
"prompt_number": 51, | |
"text": [ | |
"1" | |
] | |
} | |
], | |
"prompt_number": 51 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"min(\"hello\")" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"metadata": {}, | |
"output_type": "pyout", | |
"prompt_number": 52, | |
"text": [ | |
"'e'" | |
] | |
} | |
], | |
"prompt_number": 52 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"min({\"x\": 1, \"y\": 2, \"a\": 3})" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"metadata": {}, | |
"output_type": "pyout", | |
"prompt_number": 53, | |
"text": [ | |
"'a'" | |
] | |
} | |
], | |
"prompt_number": 53 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"min(open(\"numbers.txt\"))" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"metadata": {}, | |
"output_type": "pyout", | |
"prompt_number": 54, | |
"text": [ | |
"'five'" | |
] | |
} | |
], | |
"prompt_number": 54 | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"Lets investigate." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"x = [1, 2, 3, 4]" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 55 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"dir(x)" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"metadata": {}, | |
"output_type": "pyout", | |
"prompt_number": 56, | |
"text": [ | |
"['__add__',\n", | |
" '__class__',\n", | |
" '__contains__',\n", | |
" '__delattr__',\n", | |
" '__delitem__',\n", | |
" '__delslice__',\n", | |
" '__doc__',\n", | |
" '__eq__',\n", | |
" '__format__',\n", | |
" '__ge__',\n", | |
" '__getattribute__',\n", | |
" '__getitem__',\n", | |
" '__getslice__',\n", | |
" '__gt__',\n", | |
" '__hash__',\n", | |
" '__iadd__',\n", | |
" '__imul__',\n", | |
" '__init__',\n", | |
" '__iter__',\n", | |
" '__le__',\n", | |
" '__len__',\n", | |
" '__lt__',\n", | |
" '__mul__',\n", | |
" '__ne__',\n", | |
" '__new__',\n", | |
" '__reduce__',\n", | |
" '__reduce_ex__',\n", | |
" '__repr__',\n", | |
" '__reversed__',\n", | |
" '__rmul__',\n", | |
" '__setattr__',\n", | |
" '__setitem__',\n", | |
" '__setslice__',\n", | |
" '__sizeof__',\n", | |
" '__str__',\n", | |
" '__subclasshook__',\n", | |
" 'append',\n", | |
" 'count',\n", | |
" 'extend',\n", | |
" 'index',\n", | |
" 'insert',\n", | |
" 'pop',\n", | |
" 'remove',\n", | |
" 'reverse',\n", | |
" 'sort']" | |
] | |
} | |
], | |
"prompt_number": 56 | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"Iterator protocol binds all these." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"it = iter(x)" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 57 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"it.next()" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"metadata": {}, | |
"output_type": "pyout", | |
"prompt_number": 58, | |
"text": [ | |
"1" | |
] | |
} | |
], | |
"prompt_number": 58 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"it.next()" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"metadata": {}, | |
"output_type": "pyout", | |
"prompt_number": 59, | |
"text": [ | |
"2" | |
] | |
} | |
], | |
"prompt_number": 59 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"it.next()" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"metadata": {}, | |
"output_type": "pyout", | |
"prompt_number": 60, | |
"text": [ | |
"3" | |
] | |
} | |
], | |
"prompt_number": 60 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"it.next()" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"metadata": {}, | |
"output_type": "pyout", | |
"prompt_number": 61, | |
"text": [ | |
"4" | |
] | |
} | |
], | |
"prompt_number": 61 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"it.next()" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"ename": "StopIteration", | |
"evalue": "", | |
"output_type": "pyerr", | |
"traceback": [ | |
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[0;31mStopIteration\u001b[0m Traceback (most recent call last)", | |
"\u001b[0;32m<ipython-input-62-54f0920595b2>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mit\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mnext\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", | |
"\u001b[0;31mStopIteration\u001b[0m: " | |
] | |
} | |
], | |
"prompt_number": 62 | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"**Example: yrange**" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"class yrange:\n", | |
" def __init__(self, n):\n", | |
" print \"yrange.__init__\", n\n", | |
" self.n = n\n", | |
" self.i = 0\n", | |
" \n", | |
" def __iter__(self):\n", | |
" print \"yrange.__iter__\"\n", | |
" # This should return an object with next method\n", | |
" # In this example, the same object has the next method also\n", | |
" return self\n", | |
" \n", | |
" def next(self):\n", | |
" print \"yrange.next i =\", self.i\n", | |
" if self.i < self.n:\n", | |
" self.i += 1\n", | |
" return self.i - 1\n", | |
" raise StopIteration" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 6 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"for i in yrange(5):\n", | |
" print i" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"yrange.__init__ 5\n", | |
"yrange.__iter__\n", | |
"yrange.next i = 0\n", | |
"0\n", | |
"yrange.next i = 1\n", | |
"1\n", | |
"yrange.next i = 2\n", | |
"2\n", | |
"yrange.next i = 3\n", | |
"3\n", | |
"yrange.next i = 4\n", | |
"4\n", | |
"yrange.next i = 5\n" | |
] | |
} | |
], | |
"prompt_number": 4 | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"The for loop is equivalant to:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"y = yrange(5)\n", | |
"it = iter(y)\n", | |
"while True:\n", | |
" try:\n", | |
" i = it.next()\n", | |
" except StopIteration:\n", | |
" break\n", | |
" print i" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"yrange.__init__ 5\n", | |
"yrange.__iter__\n", | |
"yrange.next i = 0\n", | |
"0\n", | |
"yrange.next i = 1\n", | |
"1\n", | |
"yrange.next i = 2\n", | |
"2\n", | |
"yrange.next i = 3\n", | |
"3\n", | |
"yrange.next i = 4\n", | |
"4\n", | |
"yrange.next i = 5\n" | |
] | |
} | |
], | |
"prompt_number": 7 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"# lets see what a list returns on iter\n", | |
"iter([1, 2, 3])" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"metadata": {}, | |
"output_type": "pyout", | |
"prompt_number": 10, | |
"text": [ | |
"<listiterator at 0x101ba3a50>" | |
] | |
} | |
], | |
"prompt_number": 10 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"it = iter([1, 2, 3])\n", | |
"print it.next()\n", | |
"print it.next()\n", | |
"print it.next()" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"1\n", | |
"2\n", | |
"3\n" | |
] | |
} | |
], | |
"prompt_number": 13 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"print it.next()" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"ename": "StopIteration", | |
"evalue": "", | |
"output_type": "pyerr", | |
"traceback": [ | |
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[0;31mStopIteration\u001b[0m Traceback (most recent call last)", | |
"\u001b[0;32m<ipython-input-14-28de134fde97>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0;32mprint\u001b[0m \u001b[0mit\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mnext\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", | |
"\u001b[0;31mStopIteration\u001b[0m: " | |
] | |
} | |
], | |
"prompt_number": 14 | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"## Generators" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"def yrange(n):\n", | |
" i = 0\n", | |
" while i < n:\n", | |
" yield i\n", | |
" i += 1\n", | |
" \n", | |
"y = yrange(5)\n", | |
"print y\n", | |
"for i in y:\n", | |
" print i" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"<generator object yrange at 0x101b675a0>\n", | |
"0\n", | |
"1\n", | |
"2\n", | |
"3\n", | |
"4\n" | |
] | |
} | |
], | |
"prompt_number": 16 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"def yrange(n):\n", | |
" print \"begin yrange\", n\n", | |
" i = 0\n", | |
" while i < n:\n", | |
" print \"before yield. i =\", i\n", | |
" yield i\n", | |
" print \"after yield. i =\", i\n", | |
" i += 1\n", | |
" print \"end yrange\"" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 17 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"y = yrange(3)" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 19 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"y.next()" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"begin yrange 3\n", | |
"before yield. i = 0\n" | |
] | |
}, | |
{ | |
"metadata": {}, | |
"output_type": "pyout", | |
"prompt_number": 20, | |
"text": [ | |
"0" | |
] | |
} | |
], | |
"prompt_number": 20 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"y.next()" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"after yield. i = 0\n", | |
"before yield. i = 1\n" | |
] | |
}, | |
{ | |
"metadata": {}, | |
"output_type": "pyout", | |
"prompt_number": 21, | |
"text": [ | |
"1" | |
] | |
} | |
], | |
"prompt_number": 21 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"y.next()" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"after yield. i = 1\n", | |
"before yield. i = 2\n" | |
] | |
}, | |
{ | |
"metadata": {}, | |
"output_type": "pyout", | |
"prompt_number": 22, | |
"text": [ | |
"2" | |
] | |
} | |
], | |
"prompt_number": 22 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"y.next()" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"ename": "StopIteration", | |
"evalue": "", | |
"output_type": "pyerr", | |
"traceback": [ | |
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[0;31mStopIteration\u001b[0m Traceback (most recent call last)", | |
"\u001b[0;32m<ipython-input-23-75a92ee8313a>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0my\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mnext\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", | |
"\u001b[0;31mStopIteration\u001b[0m: " | |
] | |
}, | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"after yield. i = 2\n", | |
"end yrange\n" | |
] | |
} | |
], | |
"prompt_number": 23 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"def yrange(n):\n", | |
" i = 0\n", | |
" while i < n:\n", | |
" yield i\n", | |
" i += 1" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 27 | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"We can compute sum of first 1000 numbers without creating a list." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"sum(yrange(1000))" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"metadata": {}, | |
"output_type": "pyout", | |
"prompt_number": 28, | |
"text": [ | |
"499500" | |
] | |
} | |
], | |
"prompt_number": 28 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"def squares(numbers):\n", | |
" for n in numbers:\n", | |
" yield n*n" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 29 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"sum(squares(yrange(1000)))" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"metadata": {}, | |
"output_type": "pyout", | |
"prompt_number": 30, | |
"text": [ | |
"332833500" | |
] | |
} | |
], | |
"prompt_number": 30 | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"**Problem:** Write a generator function `to_int` that takes an iterator as argument and converts each element of the iterator to an integer.\n", | |
" \n", | |
" # Assuming num.txt has numbers from 1 to 10\n", | |
" >>> sum(to_int(open(\"num.txt\")))\n", | |
" 55\n", | |
" >>> sum(squares(to_int(open(\"num.txt\"))))\n", | |
" 385\n" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"**Problem:** Write a generator function `evens` that takes a iterable of numbers returns only the even ones.\n", | |
"\n", | |
" >>> list(evens(xrange(10)))\n", | |
" [0, 2, 4, 6, 8]\n", | |
" >>> sum(evens(xrange(10)))\n", | |
" 20 " | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"**Problem:** Write a function `iterjoin` that takes 2 iterable objects and returns an iterator over both of them.\n", | |
"\n", | |
" >>> list(iterjoin([1, 2], [3, 4]))\n", | |
" [1, 2, 3, 4]\n", | |
" >>> list(iterjoin([1, 2], \"xy\"))\n", | |
" [1, 2, 'x', 'y'] " | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"**Problem:** Write a function `iterappend` that takes an iterable and a value and returns an iterator with the value append at the end of given iterable.\n", | |
"\n", | |
" >>> list(iterappend(xrange(3), 'END'))\n", | |
" [0, 1, 2, 'END']\n", | |
" >>> sum(iterappend(xrange(3), 100))\n", | |
" 103\n", | |
" " | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"it = iter([1, 2, 3])" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 31 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"sum(it)" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"metadata": {}, | |
"output_type": "pyout", | |
"prompt_number": 32, | |
"text": [ | |
"6" | |
] | |
} | |
], | |
"prompt_number": 32 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"sum(it)" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"metadata": {}, | |
"output_type": "pyout", | |
"prompt_number": 33, | |
"text": [ | |
"0" | |
] | |
} | |
], | |
"prompt_number": 33 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"it.next()" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"ename": "StopIteration", | |
"evalue": "", | |
"output_type": "pyerr", | |
"traceback": [ | |
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[0;31mStopIteration\u001b[0m Traceback (most recent call last)", | |
"\u001b[0;32m<ipython-input-34-54f0920595b2>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mit\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mnext\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", | |
"\u001b[0;31mStopIteration\u001b[0m: " | |
] | |
} | |
], | |
"prompt_number": 34 | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"**Problem** Write a function `count` to count number of elements in an iteratable.\n", | |
"\n", | |
" >>> count(xrange(10))\n", | |
" >>> count(iterjoin(xrange(10), \"hello\"))\n", | |
" 15" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"**Problem** Write a fucntion `get_paragraphs` that takes an iter of lines and returns an iter of paragraphs.\n", | |
"\n", | |
"You can use http://anandology.com/tmp/sachin.txt as an input.\n", | |
"\n", | |
" >>> count(get_paragraphs(open(\"sachin.txt\")))\n", | |
" 13\n", | |
" >>> p1 = get_paragraphs(open(\"sachin.txt\")).next()\n", | |
" >>> len(p1)\n", | |
" 238\n", | |
" >>> p1[:10]\n", | |
" 'Sachin Ten'\n" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"def paragraphs(lines):\n", | |
" para = \"\"\n", | |
" for line in lines:\n", | |
" if line == \"\\n\":\n", | |
" # got an empty line, means end of a paragraph\n", | |
" yield para\n", | |
" # start a new para\n", | |
" para = \"\"\n", | |
" else:\n", | |
" # this line is also in the para started couple of lines before\n", | |
" para += line\n", | |
"\n", | |
"def count(it):\n", | |
" return sum([1 for x in it])\n", | |
" \n", | |
"print count(paragraphs(open(\"sachin.txt\"))) " | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"13\n" | |
] | |
} | |
], | |
"prompt_number": 36 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"paragraphs(open(\"sachin.txt\")).next()" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"metadata": {}, | |
"output_type": "pyout", | |
"prompt_number": 37, | |
"text": [ | |
"'Sachin Tendulkar on Friday ensured that it was a farewell that each and every\\nIndian will remember for posterity as the country\\xd5s greatest sporting icon\\ndelighted fans with a knock which exhibited just why he is the greatest of this\\nera.\\n'" | |
] | |
} | |
], | |
"prompt_number": 37 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"# longest para\n", | |
"max(paragraphs(open(\"sachin.txt\")), key=len)" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"metadata": {}, | |
"output_type": "pyout", | |
"prompt_number": 38, | |
"text": [ | |
"'Anjali was on her feet, mother Rajni was smiling, coach Ramakant Achrekar had a\\ntear in his eyes, brother Ajit was emotional and one of the ball-boys standing\\nat the boundary line called Arjun Tendulkar was certainly pleased at what he\\nsaw.\\n'" | |
] | |
} | |
], | |
"prompt_number": 38 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"# para with more number of words\n", | |
"max(paragraphs(open(\"sachin.txt\")), key=lambda para: len(para.split()))" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"metadata": {}, | |
"output_type": "pyout", | |
"prompt_number": 39, | |
"text": [ | |
"'A few overs later, Best had his hands on his knees, a signature of surrendering\\nto a genius. As he walked past Best, Tendulkar just patted his shoulders as if\\nto say \\xd2Come on young man. You will have better days but it\\xd5s my day today.\\xd3\\n'" | |
] | |
} | |
], | |
"prompt_number": 39 | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"**List Comprehensions**" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"[x*x for x in range(10)]" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"metadata": {}, | |
"output_type": "pyout", | |
"prompt_number": 40, | |
"text": [ | |
"[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]" | |
] | |
} | |
], | |
"prompt_number": 40 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"[x*x for x in range(10) if x % 2 == 0]" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"metadata": {}, | |
"output_type": "pyout", | |
"prompt_number": 41, | |
"text": [ | |
"[0, 4, 16, 36, 64]" | |
] | |
} | |
], | |
"prompt_number": 41 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"%%file a.csv\n", | |
"a,b,c\n", | |
"1,2,3\n", | |
"1,4,9" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"Writing a.csv\n" | |
] | |
} | |
], | |
"prompt_number": 42 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"[line for line in open(\"a.csv\")]" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"metadata": {}, | |
"output_type": "pyout", | |
"prompt_number": 43, | |
"text": [ | |
"['a,b,c\\n', '1,2,3\\n', '1,4,9']" | |
] | |
} | |
], | |
"prompt_number": 43 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"[line.strip(\"\\n\") for line in open(\"a.csv\")]" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"metadata": {}, | |
"output_type": "pyout", | |
"prompt_number": 44, | |
"text": [ | |
"['a,b,c', '1,2,3', '1,4,9']" | |
] | |
} | |
], | |
"prompt_number": 44 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"[line.strip(\"\\n\").split(\".\") for line in open(\"a.csv\")]" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"metadata": {}, | |
"output_type": "pyout", | |
"prompt_number": 45, | |
"text": [ | |
"[['a,b,c'], ['1,2,3'], ['1,4,9']]" | |
] | |
} | |
], | |
"prompt_number": 45 | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"**Generator Expressions**" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"def squares(it):\n", | |
" for x in it:\n", | |
" yield x*x\n", | |
" \n", | |
"print sum(squares(xrange(1000)))" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"332833500\n" | |
] | |
} | |
], | |
"prompt_number": 46 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"# same thing as list comprehension\n", | |
"print sum([x*x for x in xrange(1000)])" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"332833500\n" | |
] | |
} | |
], | |
"prompt_number": 47 | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"but that creates a new list. Not very efficient." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"print sum((x*x for x in xrange(1000)))" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"332833500\n" | |
] | |
} | |
], | |
"prompt_number": 48 | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"Just replacing `[` and `]` in list comprehension with `(` and `)` makes it a generator expression. A geneator expression is like a list comprehension, but returns a generator instead of a list." | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"And the parenthesis are optional when passed to a function with single argument." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"print sum(x*x for x in xrange(1000))" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"332833500\n" | |
] | |
} | |
], | |
"prompt_number": 49 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"def squares(it):\n", | |
" return (x*x for x in it)" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 50 | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"**Problem** Write function `evens` as using a generator expression. It should take an iter of numbers as arguments and return an iter of even numbers." | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"**Problem** Write a function `words` that takes an iter of lines and returns an iter of words.\n", | |
"\n", | |
" # word count\n", | |
" >>> count(words(open(\"numbers.txt\")))\n", | |
" \n", | |
" # longest word\n", | |
" >>> max(words(open(\"numbers.txt\"), key=len))\n", | |
" ..." | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"**Problem:** Write a function `take` that returns first n elements of an iterable as a list.\n", | |
"\n", | |
" >>> take(5, xrange(100))\n", | |
" [0, 1, 2, 3, 4]\n", | |
" >>> take(5, evens(xrange(100)))\n", | |
" [0, 2, 4, 6, 8] " | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"def itake(n, it):\n", | |
" it = iter(it)\n", | |
" for i in xrange(n):\n", | |
" yield it.next()\n", | |
"\n", | |
"def itake2(n, it):\n", | |
" it = iter(it)\n", | |
" return (it.next() for i in xrange(n))\n", | |
" \n", | |
"\n", | |
"def take(n, it):\n", | |
" return list(itake2(n, it))" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 55 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"print take(10, xrange(1000))" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]\n" | |
] | |
} | |
], | |
"prompt_number": 56 | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"There is `itertools` module which provides lot of utilities to work with iterators." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"import itertools\n", | |
"print list(itertools.islice(xrange(1000), 5))" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"[0, 1, 2, 3, 4]\n" | |
] | |
} | |
], | |
"prompt_number": 57 | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"Lets solve the words problem here." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"%%file words.py\n", | |
"\n", | |
"def words(lines):\n", | |
" return (w for line in lines for w in line.split())\n", | |
"\n", | |
"if __name__ == \"__main__\":\n", | |
" print max(words(open(\"sachin.txt\")), key=len)" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"Overwriting words.py\n" | |
] | |
} | |
], | |
"prompt_number": 60 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"!python words.py" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"international\r\n" | |
] | |
} | |
], | |
"prompt_number": 61 | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"What if we want to find longest word in a bunch of files, not just one file." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"%%file files.py\n", | |
"\"\"\"Finds files in matching given extension.\n", | |
"\"\"\"\n", | |
"import os\n", | |
"\n", | |
"def find(dir, extn):\n", | |
" for dirpath, dirnames, filenames in os.walk(dir):\n", | |
" for f in filenames:\n", | |
" if f.endswith(extn):\n", | |
" yield os.path.join(dirpath, f)\n", | |
"\n", | |
"def open_files(filenames):\n", | |
" \"\"\"Takes iter over filenames and return iter over file objects.\n", | |
" \"\"\"\n", | |
" return (open(f) for f in filenames)\n", | |
" \n", | |
"if __name__ == \"__main__\":\n", | |
" print list(find(\"..\", \".txt\"))" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"Overwriting files.py\n" | |
] | |
} | |
], | |
"prompt_number": 72 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"!python files.py" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"['../a.txt', '../notes/numbers.txt', '../notes/Readme.txt', '../notes/sachin.txt']\r\n" | |
] | |
} | |
], | |
"prompt_number": 71 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"%%file words2.py\n", | |
"from words import words\n", | |
"import files\n", | |
"\n", | |
"def joiniters(iters):\n", | |
" for it in iters:\n", | |
" for x in it:\n", | |
" yield x\n", | |
"\n", | |
"filenames = files.find(\"..\", \".txt\")\n", | |
"fileobjs = files.open_files(filenames)\n", | |
"lines = joiniters(fileobjs)\n", | |
"words = words(lines)\n", | |
"print max(words, key=len)" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"Writing words2.py\n" | |
] | |
} | |
], | |
"prompt_number": 73 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"!python words2.py" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"\"convert-fig1.tex\").\r\n" | |
] | |
} | |
], | |
"prompt_number": 74 | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"# Modules and Imports" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"%%file square.py\n", | |
"\n", | |
"def square(x):\n", | |
" return x*x\n", | |
"\n", | |
"if __name__ == \"__main__\":\n", | |
" # Run this block of code only when this file is executed as a script\n", | |
" # Don't run this when this file is imported as a module\n", | |
" print repr(__name__)\n", | |
" print square(10)" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"Overwriting square.py\n" | |
] | |
} | |
], | |
"prompt_number": 94 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"!python square.py" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"'__main__'\r\n", | |
"100\r\n" | |
] | |
} | |
], | |
"prompt_number": 95 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"%%file sum_of_squares.py\n", | |
"\n", | |
"print \"before import square\"\n", | |
"from square import square\n", | |
"print \"after import square\"\n", | |
"\n", | |
"def sum_of_squares(x, y):\n", | |
" return square(x) + square(y)\n", | |
"\n", | |
"if __name__ == \"__main__\":\n", | |
" print sum_of_squares(3, 4)" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"Overwriting sum_of_squares.py\n" | |
] | |
} | |
], | |
"prompt_number": 96 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"!python sum_of_squares.py" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"before import square\r\n", | |
"after import square\r\n", | |
"25\r\n" | |
] | |
} | |
], | |
"prompt_number": 97 | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"When you import a module, `__name__` will be set to the name of the module. When run as a script, it'll be set to `\"__main__\"`." | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"## Back to Classes" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"Lets try to model files and directories as Python objects." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"%%file fs.py\n", | |
"\"\"\"\n", | |
"Implement files and directories as Python objects.\n", | |
"\n", | |
"1. f.size - should give size of the file\n", | |
"2. f.name - should give the name\n", | |
"3. f.abspath - should give absolute path of the file\n", | |
"4. f.read() - should read all the contents of the file\n", | |
"5. f.parent - should give the parent directory\n", | |
"6. d['a.py'] - should give File object corresponding to a.py\n", | |
"7. len(d) - should tell how many files are there in that directory\n", | |
"8. d should support iteration\n", | |
"\n", | |
"Hints: see os and os.path modules\n", | |
"\"\"\"\n", | |
"import os.path\n", | |
"\n", | |
"class File:\n", | |
" def __init__(self, path):\n", | |
" self.path = path\n", | |
" \n", | |
" @property\n", | |
" def size(self):\n", | |
" return os.stat(self.path).st_size\n", | |
"\n", | |
"class Directory(File):\n", | |
" pass\n", | |
"\n", | |
"\n", | |
"if __name__ == \"__main__\":\n", | |
" f = File(\"/tmp/a.py\")\n", | |
" assert f.name == \"a.py\"\n", | |
" assert f.abspath == \"/tmp/a.py\" \n", | |
" assert isinstance(f.parent, Directory)\n", | |
" assert f.parent.path == '/tmp'" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"Overwriting fs.py\n" | |
] | |
} | |
], | |
"prompt_number": 104 | |
}, | |
{ | |
"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