functional python webinar from october 22nd, 2014
DESCRIPTION
Slides from my free functional Python webinar, given on October 22nd, 2014. Discussion included functional programming as a perspective, passing functions as data, and writing programs that take functions as parameters. Includes (at the end) a coupon for my new ebook, Practice Makes Python.TRANSCRIPT
![Page 2: Functional Python Webinar from October 22nd, 2014](https://reader034.vdocuments.site/reader034/viewer/2022051612/54c551564a7959cc6a8b473b/html5/thumbnails/2.jpg)
Who am I?• Programmer, consultant, developer, trainer
• Long-time Python (+Ruby) user
• Linux Journal columnist
• Author Practice Makes Python!
• PhD in Learning Sciences from Northwestern
• Read (lots) more at http://lerner.co.il/
2
![Page 3: Functional Python Webinar from October 22nd, 2014](https://reader034.vdocuments.site/reader034/viewer/2022051612/54c551564a7959cc6a8b473b/html5/thumbnails/3.jpg)
![Page 4: Functional Python Webinar from October 22nd, 2014](https://reader034.vdocuments.site/reader034/viewer/2022051612/54c551564a7959cc6a8b473b/html5/thumbnails/4.jpg)
Functional programming• A different way of thinking about programming
• A different way of writing programs
• A different way of approaching problems
• Often provides new, clean, elegant solutions…
• … but again, it requires that you think about things very differently.
4
![Page 5: Functional Python Webinar from October 22nd, 2014](https://reader034.vdocuments.site/reader034/viewer/2022051612/54c551564a7959cc6a8b473b/html5/thumbnails/5.jpg)
5
Function
Input
Output
… and if you can avoid internal state, even better!
No external state changes in this function…
![Page 6: Functional Python Webinar from October 22nd, 2014](https://reader034.vdocuments.site/reader034/viewer/2022051612/54c551564a7959cc6a8b473b/html5/thumbnails/6.jpg)
Why work this way?• Simpler functions — easier to write and maintain
• Easer to test functions, and predict their results
• Easier to combine functions in new, different ways
• You can split work across threads, processors, or even machines without any ill effects
• Certain things can be expressed easily, elegantly
6
![Page 7: Functional Python Webinar from October 22nd, 2014](https://reader034.vdocuments.site/reader034/viewer/2022051612/54c551564a7959cc6a8b473b/html5/thumbnails/7.jpg)
The FP perspective
7
f1 f2 f3 f4 f5Input Output
![Page 8: Functional Python Webinar from October 22nd, 2014](https://reader034.vdocuments.site/reader034/viewer/2022051612/54c551564a7959cc6a8b473b/html5/thumbnails/8.jpg)
OO or functional?
• Python supports both styles
• It’s common to mix them in one program
• My current approach: Use objects in general, but functional techniques inside of methods
8
![Page 9: Functional Python Webinar from October 22nd, 2014](https://reader034.vdocuments.site/reader034/viewer/2022051612/54c551564a7959cc6a8b473b/html5/thumbnails/9.jpg)
Sequences and iterables• There are three built-in sequences in Python:
strings, tuples, and lists
• Many other objects are "iterable," meaning that you can stick them into a "for" loop and get one item at a time
• Examples: files and dicts
• This discussion mainly has to do with iterables
9
![Page 10: Functional Python Webinar from October 22nd, 2014](https://reader034.vdocuments.site/reader034/viewer/2022051612/54c551564a7959cc6a8b473b/html5/thumbnails/10.jpg)
Where are iterables?• Strings, lists, and tuples (obviously)
• Dicts, sets, and files
• Complex data structures: Lists of lists, lists of dicts, dicts of dicts (and others)
• Results from database queries
• Information from a network feed
• Many, many objects return iterables
10
![Page 11: Functional Python Webinar from October 22nd, 2014](https://reader034.vdocuments.site/reader034/viewer/2022051612/54c551564a7959cc6a8b473b/html5/thumbnails/11.jpg)
Transformation• You often want to turn one iterable into another
• For example, you might want to turn the list
[0,1,2,3,4] # range(5)
• into the list
[0,1,4,9,16]
• We can transform the first list into the other by applying a Python function.
11
![Page 12: Functional Python Webinar from October 22nd, 2014](https://reader034.vdocuments.site/reader034/viewer/2022051612/54c551564a7959cc6a8b473b/html5/thumbnails/12.jpg)
12
def square(x): return x*x
Each list item
New list item
![Page 13: Functional Python Webinar from October 22nd, 2014](https://reader034.vdocuments.site/reader034/viewer/2022051612/54c551564a7959cc6a8b473b/html5/thumbnails/13.jpg)
The usual solution>>>> input = range(5)
>>>> def square(x):
return x*x
>>> output = [ ]
>>> for x in input:
output.append(square(x))
>>> output
[0, 1, 4, 9, 16]
13
![Page 14: Functional Python Webinar from October 22nd, 2014](https://reader034.vdocuments.site/reader034/viewer/2022051612/54c551564a7959cc6a8b473b/html5/thumbnails/14.jpg)
What's wrong with this?• Nothing is wrong.
• But functional programming looks at this, and says:
• Why create a new variable ("output")?
• Why are you building it, one step at a time?
• Why are you modifying the state of "output"?
• Why do it in such a clumsy way?
14
![Page 15: Functional Python Webinar from October 22nd, 2014](https://reader034.vdocuments.site/reader034/viewer/2022051612/54c551564a7959cc6a8b473b/html5/thumbnails/15.jpg)
The elegant way
"I want to apply my function, square, to each and every element of the input list, and get a list back."
15
![Page 16: Functional Python Webinar from October 22nd, 2014](https://reader034.vdocuments.site/reader034/viewer/2022051612/54c551564a7959cc6a8b473b/html5/thumbnails/16.jpg)
16
def square(x): return x*x
Input list
Output list
![Page 17: Functional Python Webinar from October 22nd, 2014](https://reader034.vdocuments.site/reader034/viewer/2022051612/54c551564a7959cc6a8b473b/html5/thumbnails/17.jpg)
List comprehensions
• In Python, we do this with a "list comprehension":
[square(x) for x in range(5)]
• Or if you prefer:
[x*x for x in range(5)]
17
![Page 18: Functional Python Webinar from October 22nd, 2014](https://reader034.vdocuments.site/reader034/viewer/2022051612/54c551564a7959cc6a8b473b/html5/thumbnails/18.jpg)
Ints to strings• I can't say
', '.join(range(5))
• because str.join's input must contain strings.
• Solution:
', '.join([str(x) for x in range(5)])
18
![Page 19: Functional Python Webinar from October 22nd, 2014](https://reader034.vdocuments.site/reader034/viewer/2022051612/54c551564a7959cc6a8b473b/html5/thumbnails/19.jpg)
Lowercase all words• I can transform a sentence into all lowercase:
words = 'This is a sentence for my Python class'.split()
[word.lower() for word in words]
• Or even:
' '.join([word.lower() for word in words])
19
![Page 20: Functional Python Webinar from October 22nd, 2014](https://reader034.vdocuments.site/reader034/viewer/2022051612/54c551564a7959cc6a8b473b/html5/thumbnails/20.jpg)
Filenames to files• I can get a list of filenames from os.listdir:
os.listdir('/etc')
• I can get a file object for each of these:
[open('/etc/' + filename)
for filename in os.listdir('/etc')]
20
![Page 21: Functional Python Webinar from October 22nd, 2014](https://reader034.vdocuments.site/reader034/viewer/2022051612/54c551564a7959cc6a8b473b/html5/thumbnails/21.jpg)
File contents
• If I want to get the names of users on my Unix system, I can say
[ line.split(":")[0]
for line in open('/etc/passwd') ]
21
![Page 22: Functional Python Webinar from October 22nd, 2014](https://reader034.vdocuments.site/reader034/viewer/2022051612/54c551564a7959cc6a8b473b/html5/thumbnails/22.jpg)
Filtering
• If I want to get the names of users on my Unix system, I can say
[ line.split(":")[0]
for line in open('/etc/passwd')
if line[0] != '#' ]
22
![Page 23: Functional Python Webinar from October 22nd, 2014](https://reader034.vdocuments.site/reader034/viewer/2022051612/54c551564a7959cc6a8b473b/html5/thumbnails/23.jpg)
Pig Latin!def plword(word):
vowels = 'aeiou'
if word[0] in vowels:
return word + 'way'
else:
return word[1:] + word[0] + 'ay'
23
![Page 24: Functional Python Webinar from October 22nd, 2014](https://reader034.vdocuments.site/reader034/viewer/2022051612/54c551564a7959cc6a8b473b/html5/thumbnails/24.jpg)
Translation
' '.join([plword(word)
for word in open('column-215') ])
24
![Page 25: Functional Python Webinar from October 22nd, 2014](https://reader034.vdocuments.site/reader034/viewer/2022051612/54c551564a7959cc6a8b473b/html5/thumbnails/25.jpg)
Bottom line• Comprehensions are Python's answer to the
traditional functions "map" and "filter".
• Once you start to think in terms of "mapping" one sequence to another, you'll see this pattern everywhere.
• You'll reduce the number of assignments you make. Your programs will be shorter and easier to understand. And you'll be able to stack these manipulations, without worrying about side effects.
25
![Page 26: Functional Python Webinar from October 22nd, 2014](https://reader034.vdocuments.site/reader034/viewer/2022051612/54c551564a7959cc6a8b473b/html5/thumbnails/26.jpg)
Functions
• Where are the functions in functional programming?
• Let's write some functions! Let's use some functions!
26
![Page 27: Functional Python Webinar from October 22nd, 2014](https://reader034.vdocuments.site/reader034/viewer/2022051612/54c551564a7959cc6a8b473b/html5/thumbnails/27.jpg)
Calling functions• We call functions in Python with ()
• No parentheses — no function call! x = len('abc')
type(x)
int
x = len
type(x)
builtin_function_or_method
27
![Page 28: Functional Python Webinar from October 22nd, 2014](https://reader034.vdocuments.site/reader034/viewer/2022051612/54c551564a7959cc6a8b473b/html5/thumbnails/28.jpg)
Parentheses• In Python, something that can be executed with
parentheses is known as "callable".
• 'a'() will result in an error, that a string isn't "callable."
• Normally, we say that functions and classes are callable. How do we know? They have a __call__ attribute!
28
![Page 29: Functional Python Webinar from October 22nd, 2014](https://reader034.vdocuments.site/reader034/viewer/2022051612/54c551564a7959cc6a8b473b/html5/thumbnails/29.jpg)
Dispatch table
def foo(): return "foo"
def bar(): return "bar"
d = {'foo':foo, 'bar':bar}
29
![Page 30: Functional Python Webinar from October 22nd, 2014](https://reader034.vdocuments.site/reader034/viewer/2022051612/54c551564a7959cc6a8b473b/html5/thumbnails/30.jpg)
Sorting
• We know that we can use list.sort to sort a list:
words= 'This is a sentence for my online Python class'.split()
words.sort()
30
![Page 31: Functional Python Webinar from October 22nd, 2014](https://reader034.vdocuments.site/reader034/viewer/2022051612/54c551564a7959cc6a8b473b/html5/thumbnails/31.jpg)
Changing sort's behavior• The optional "key" parameter lets you pass a
function that changes sort's behavior
• Define a function, and pass it to "key".
• Or use an existing function:
words.sort(key=str.lower)
words.sort(key=len)
31
![Page 32: Functional Python Webinar from October 22nd, 2014](https://reader034.vdocuments.site/reader034/viewer/2022051612/54c551564a7959cc6a8b473b/html5/thumbnails/32.jpg)
The real lesson: You can do it, too!
• Take a function as a parameter
• Invoke the function within your function
• Now you have a more generic function, whose behavior can be modified!
32
![Page 33: Functional Python Webinar from October 22nd, 2014](https://reader034.vdocuments.site/reader034/viewer/2022051612/54c551564a7959cc6a8b473b/html5/thumbnails/33.jpg)
33
Function
Input 1
Output
Use input 2
input 2
![Page 34: Functional Python Webinar from October 22nd, 2014](https://reader034.vdocuments.site/reader034/viewer/2022051612/54c551564a7959cc6a8b473b/html5/thumbnails/34.jpg)
Example
• Let's implement transform_values!
>>> d = {'a':1, 'b':2, 'c':3}
>>> transform_values(lambda x: x*x, d)
{'a': 1, 'b': 4, 'c': 9}
34
![Page 35: Functional Python Webinar from October 22nd, 2014](https://reader034.vdocuments.site/reader034/viewer/2022051612/54c551564a7959cc6a8b473b/html5/thumbnails/35.jpg)
Summary• Functions are data, too! Treating them as such
makes your programs more flexible, generic, and easy to understand
• Python's comprehensions are a modern version of classic "map" and "filter" functions.
• Composing functions isn't the only solution, but it's a really flexible and useful one
• It becomes easier with practice!
35
![Page 36: Functional Python Webinar from October 22nd, 2014](https://reader034.vdocuments.site/reader034/viewer/2022051612/54c551564a7959cc6a8b473b/html5/thumbnails/36.jpg)
Questions? Comments? And remember…
• Early-bird discount on my book!
• http://lerner.co.il/practice-makes-python
• Use the WEBINAR coupon code for 10% off!
• Courses are at http://lerner.co.il/courses
• Contact me: [email protected]
• Follow me: @reuvenmlerner
36