Skip to content

Commit 8947b52

Browse files
committed
updated session 8 and 9
1 parent 1a690fb commit 8947b52

File tree

3 files changed

+155
-249
lines changed

3 files changed

+155
-249
lines changed
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
.. _extra_topics:
2+
3+
************
4+
Extra Topics
5+
************
6+
7+
Here are some extra topics that we didn't have time for in the regular class sessions:
8+
9+
==============================
10+
Closures and function Currying
11+
==============================
12+
13+
Defining specialized functions on the fly
14+
15+
Closures
16+
--------
17+
18+
"Closures" and "Currying" are cool CS terms for what is really just defining functions on the fly.
19+
20+
you can find a "proper" definition here:
21+
22+
https://en.wikipedia.org/wiki/Closure_(computer_programming)
23+
24+
but I even have trouble following that.
25+
26+
So let's go straight to an example:
27+
28+
.. nextslide::
29+
30+
.. code-block:: python
31+
32+
def counter(start_at=0):
33+
count = [start_at]
34+
def incr():
35+
count[0] += 1
36+
return count[0]
37+
return incr
38+
39+
What's going on here?
40+
41+
We have stored the ``start_at`` value in a list.
42+
43+
Then defined a function, ``incr`` that adds one to the value in the list, and returns that value.
44+
45+
[ Quiz: why is it: ``count = [start_at]``, rather than just ``count=start_at`` ]
46+
47+
.. nextslide::
48+
49+
So what type of object do you get when you call ``counter()``?
50+
51+
.. code-block:: ipython
52+
53+
In [37]: c = counter(start_at=5)
54+
55+
In [38]: type(c)
56+
Out[38]: function
57+
58+
So we get a function back -- makes sense. The ``def`` defines a function, and that function is what's getting returned.
59+
60+
Being a function, we can, of course, call it:
61+
62+
.. code-block:: ipython
63+
64+
In [39]: c()
65+
Out[39]: 6
66+
67+
In [40]: c()
68+
Out[40]: 7
69+
70+
Each time is it called, it increments the value by one.
71+
72+
.. nextslide::
73+
74+
But what happens if we call ``counter()`` multiple times?
75+
76+
.. code-block:: ipython
77+
78+
In [41]: c1 = counter(5)
79+
80+
In [42]: c2 = counter(10)
81+
82+
In [43]: c1()
83+
Out[43]: 6
84+
85+
In [44]: c2()
86+
Out[44]: 11
87+
88+
So each time ``counter()`` is called, a new function is created. And that function has its own copy of the ``count`` object. This is what makes in a "closure" -- it carries with it the scope in which is was created.
89+
90+
the returned ``incr`` function is a "curried" function -- a function with some parameters pre-specified.
91+
92+
``functools.partial``
93+
---------------------
94+
95+
The ``functools`` module in the standard library provides utilities for working with functions:
96+
97+
https://docs.python.org/3.5/library/functools.html
98+
99+
Creating a curried function turns out to be common enough that the ``functools.partial`` function provides an optimized way to do it:
100+
101+
What functools.partial does is:
102+
103+
* Makes a new version of a function with one or more arguments already filled in.
104+
* The new version of a function documents itself.
105+
106+
Example:
107+
108+
.. code-block:: python
109+
110+
def power(base, exponent):
111+
"""returns based raised to the give exponent"""
112+
return base ** exponent
113+
114+
Simple enough. but what if we wanted a specialized ``square`` and ``cube`` function?
115+
116+
We can use ``functools.partial`` to *partially* evaluate the function, giving us a specialized version:
117+
118+
square = partial(power, exponent=2)
119+
cube = partial(power, exponent=3)
120+
121+
Reading:
122+
--------
123+
124+
http://www.pydanny.com/python-partials-are-fun.html
125+
126+
https://pymotw.com/3/functools/
127+
128+
http://www.programiz.com/python-programming/closure
129+
130+
https://www.clear.rice.edu/comp130/12spring/curry/
131+

slides_sources/source/session08.rst

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -713,7 +713,7 @@ Look up the special methods you need and define them.
713713
There's more to read about the details of implementing these methods:
714714

715715
* https://docs.python.org/3.5/reference/datamodel.html#special-method-names
716-
* http://www.rafekettler.com/magicmethods.html
716+
* https://github.com/RafeKettler/magicmethods/blob/master/magicmethods.markdown
717717

718718
===
719719
LAB
@@ -854,7 +854,7 @@ https://docs.python.org/3/reference/datamodel.html#emulating-container-types
854854

855855
and
856856

857-
http://www.rafekettler.com/magicmethods.html#sequence
857+
https://github.com/RafeKettler/magicmethods/blob/master/magicmethods.markdown#sequence
858858

859859
The key ones are:
860860

@@ -916,8 +916,6 @@ http://www.blog.pythonlibrary.org/2015/10/28/python-101-lambda-basics/
916916

917917
https://pythonconquerstheuniverse.wordpress.com/2011/08/29/lambda_tutorial/
918918

919-
Functions as Objects.
920-
921919

922920
.. rst-class:: left
923921

0 commit comments

Comments
 (0)