Heads up! To view this whole video, sign in with your Courses Plus account or enroll in your free 7-day trial. Sign In Enroll
Preview
Start a free Courses trial
to watch this video
Kenneth Love provides a quick overview and introduction to the world of functional programming and how to use it in Python.
You can access the files used in this workshop on GitHub
[MUSIC]
0:00
How many of you.
0:04
So, a lot of you do Python.
How many of you have done
0:05
functional programming in Python,
JavaScript, any language that supports it,
0:07
which is most of them?
0:11
Some of you?
0:13
All right.
So,
0:14
functional programming is a fun little
area.
0:15
So the basic idea is that you do all of
your computing,
0:21
all your programming just by evaluating
functions.
0:24
So you always have expressions like this
thing is equal to that thing.
0:28
Thank you.
0:34
And it really helps when firs, functions
are first class citizens of the language,
0:37
which means you can pass functions around.
0:41
Ooh.
0:44
So you can send functions to other
functions.
0:46
You can make a variable just equal to a
function, and
0:49
then call that thing over and over again.
0:52
You can do all that fun stuff.
0:54
All of this applies to Python, which is
great.
0:56
Another rule for functional programming.
1:00
And this is one we're gonna bring up a
lot,
1:03
is that functions shouldn't have side
effects.
1:04
So if I run a function with the same data,
1:07
I should get the exact same output every
single time.
1:10
That seems kinda obvious, but let's talk
about it.
1:15
So in Python, if I do this.
1:19
What is the list that I passed then on the
outside?
1:23
Right, I had a list and I passed it in,
yeah?
1:26
Let's just do it.
[BLANK_AUDIO]
1:29
All right.
1:32
[SOUND] So we're in Python.
1:33
[BLANK_AUDIO]
1:38
42, 28, 1, 105 and 2.
1:42
All right, messy list, yeah?
1:49
[SOUND] Now cheating.
1:51
All right, so there's my function.
1:58
If I call reverse list, and I pass in a.
2:00
What'd I get back?
2:04
>> [INAUDIBLE]
>> Right.
2:05
So now what is A?
2:10
Is it my old list or is it the reversed
list?
2:12
>> [INAUDIBLE]
>> Nope.
2:15
This function has a side effect, because
this function calls list.reverse,
2:19
which reverses list in place, because
lists are mutable.
2:23
You don't want that.
2:27
You don't want side effects.
2:28
'Kay.
2:30
So.
2:32
Eww.
2:34
>> [LAUGH].
2:35
>> Because we don't want side effects.
2:35
So we're gonna talk about addressing side
effects in a moment.
2:38
But we'll go through some more bullet
points here.
2:41
Functions should also be limited in their
scope and their functionality.
2:44
You wanna write small little functions.
2:46
Lots of them.
2:48
But they're really small.
2:49
Right?
They just do a little bit.
2:50
For instance, this is very ew.
2:51
Let's look at this and we'll see part of
why it's bad too.
2:58
So we taken a list, we reversed the list,
we swapped the first and
3:01
last items of the list, we stick a thing
into the list.
3:05
If it's a string, then we reverse the
first thing that's in the list.
3:08
Or sorry, if the first thing in the list
is a string,
3:13
we reverse the first thing in the list.
3:15
Otherwise if it's a number, then we int
divide it by 2,
3:17
and then we eventually return the list.
3:21
This is horrible, it does a lot of stuff.
3:23
It doesn't have any side effects though.
3:25
Which is nice and weird but it's still
ugly.
3:29
So we can break it apart into nice, small
functions, right?
3:33
Cuz we want them to be limited in what
they do.
3:36
Small scopes, small amounts of
functionality.
3:38
This isn't necessarily better cuz it's
still doing really ugly stuff down
3:41
there on the bottom but it's better.
3:44
Cuz it's small.
3:48
Right?
3:49
Okay, last thing and we'll get to some
code.
3:51
Well, almost last thing.
3:55
It's great if functions can chain.
3:58
So if I can multiple functions that always
give me back more data,
4:00
I can put those functions inside of each
other,
4:04
and I can do a whole lot of stuff in one
line that's all very explicit, but
4:05
it's not scattered out doing crazy weird
stuff in each function.
4:10
Okay, so that means we're gonna use return
a lot, way more than you may be expecting.
4:15
And, like we said before with the
list.reverse, we don't want mutations,
4:22
we don't want to return like, things that
have been mutated.
4:27
Okay, we get some chaining-friendly things
from Python, yay.
4:32
So let's start with map.
4:37
Anybody heard of map?
4:39
Few people.
Anybody want to tell me what map does?
4:41
Without reading this!
4:45
I know it's already up there, but without
reading it what does map do?
4:46
So what map does [LAUGH] map takes a
function.
4:49
Map is a function, it takes a function.
4:53
And then it takes an iterable.
4:54
And map runs that function on everything
that's in the iterable.
4:56
And gives us back a new iterable, right?
5:00
So, if I have a function that turns
numbers, turns things into strings.
5:05
Right?
5:12
It's really annoying that I can't Cmd+Tab
from there.
5:14
All right.
5:17
You've all seen str, right?
5:18
The string class?
5:20
And if I do str and a number, I get back a
string of the number.
5:22
Yeah?
5:26
Nothing crazy there?
5:27
'Kay.
5:28
So if I send in the string function to
map.
5:30
You know, hold on.
5:33
There we go.
5:35
If I send in the string function to map
and I give it a list of numbers.
5:37
Thanks Python 3 for making me look silly.
5:45
I get back this map object which is a
generator.
5:48
All right, there we go.
5:50
I get back a list of strings of numbers.
5:52
So really handy if I want to make sure
everything in here's a string.
5:55
Make sure this is all strings, right?
5:57
So all I've done is I applied the string
function to everything that's in the list.
6:01
All right.
6:06
We could do the opposite of that.
6:08
[BLANK_AUDIO]
6:09
Now we see how well I can, [SOUND] wow.
6:14
>> [INAUDIBLE] [SOUND].
6:18
>> There we go.
And
6:19
now we got ints instead of strings, 'kay?
6:20
We're gonna do some crazier stuff with map
in a moment.
6:24
But, that's the idea of map.
6:26
Run a function over everything that's in a
list, or a dict, or a tuple, or whatever.
6:28
Okay.
6:37
Filter is our next one.
6:37
How many of you have messed with filter?
6:38
Nah, a couple people.
6:41
All right.
6:41
So filter is a handy way of saying, make
sure all this stuff is true.
6:43
Or is like I want it to be.
6:47
So, ignore the or none for right now.
6:49
If we pass a function into filter, that
function must return true or false.
6:52
For everything that's in the iterable, we
run that function.
6:58
If that function gives back true, that
thing that was in the iterable gets kept.
7:02
If it returns false that thing is
discarded.
7:06
'Kay?
7:10
So if I'm like, I've got a list of people
and
7:10
I wanna make sure all these people are 21
or over.
7:12
They'll have an age attribute.
7:15
I can write a function that checks the
age.
7:16
Make sure the age is 21 or up.
7:19
And if it is, returns true, otherwise
returns false.
7:21
All right?
7:23
So a quick easy way to filter through a
bunch of people.
7:24
The none is a fun little shortcut.
7:28
You just pass none instead of a function,
7:30
it only returns things in the iterable
that are truthy in Python.
7:32
So no zeroes, no empty strings, no empty
lists, nothing like that.
7:36
But you'll get back all of your lists
that, or
7:40
all of your strings that actually have
content.
7:41
All of your numbers that are not zero.
7:43
All that kind of stuff.
7:47
We'll do a lot of stuff with filter too.
7:48
And our last one we're gonna talk about is
reduce.
7:51
Reduce is a little weird, compared to
filter and map.
7:54
Reduce always gives you back just one
thing.
7:58
And the function always takes two
arguments.
8:02
So what it does, is for
8:06
the first two items in the iterable, it
runs the function with them.
8:06
Takes whatever the answer to that function
is, runs it against the third item in
8:09
the iterable and so on, until there's just
one answer that comes out.
8:13
So if my function just adds two numbers
together, I pass it a big list,
8:18
I get the sum of the list.
8:22
If it multiplies things together, I get
the product of the list.
8:24
All right?
8:28
We'll do stuff with reduce as well.
8:29
That's enough talk.
8:32
so.
8:35
Let's go do stuff.
8:38
All right.
8:40
Wow, I got a lot of things open.
8:41
[SOUND] So, there was a GitHub repo that
had these three files over here,
8:42
test_filter, test_map, and test_reduce in
it.
8:48
And we can test all of those at once by
running python unittest.
8:53
All of our tests pass.
9:00
Because we ran 15 tests and we had 15
failures.
9:01
So lets fix that.
9:04
So which one do you want to do first,
filter, map, or reduce?
9:04
>> I don't care, we can do any of them.
9:09
>> Filter, map and reduce?
9:13
All right, lets do filter.
9:13
I'm going to close this one.
9:18
And all right, there we go.
9:21
So we just have Emacs.
9:22
Yes, Emacs.
9:26
I think I was on vim the last time I
presented up here.
9:26
All right, so we got a bunch of stuff up
here.
9:30
We've got some nums, we got the states, we
got some some values,
9:33
we got a bunch of strings, and then we've
got this string of numbers.
9:35
Which this is a generator pattern.
9:40
I talked about how filter gives us back
generators.
9:42
We're not gonna worry about what
generators are.
9:44
Just, yeah.
9:47
That's why it's a stream instead of like
number_list.
9:48
And then we have this word_list function
that opens up
9:52
my dictionary that's built into my
computer.
9:55
And gives me back all of the words that
are in that dictionary.
9:58
Which is a lot of words.
10:02
>> [LAUGH]
>> Safe enough for this.
10:03
All right, so then we've got some tests.
10:07
So let's look here at our first test.
10:09
Our first test is positive numbers, so I
wanna make sure that all
10:11
of the numbers that are in this positive
numbers variable, are greater than or
10:16
equal to zero.
10:20
So no negative numbers.
10:21
'Kay, but if I look at nums I got a
negative two in there.
10:25
And I want to get rid of that.
10:29
And I'm going to be, somewhat obtuse and
not just use remove.
10:31
So let's write this.
10:37
So positive numbers has to equal
something.
10:40
So filter, there's gonna be a function and
there's gonna be nums right?
10:45
So, I want interaction on this by the way,
you can all yell out things at me.
10:52
And I will ignore the things I don't like.
10:57
So, we need to write a function that only
gives us back the numbers that
10:58
are greater than zero.
11:02
So what are we gonna call it?
11:03
Anybody?
11:05
How about positives?
11:06
Yeah, does that work?
11:10
Okay, and it needs to take a single item,
so it's gonna take a num.
11:11
Or an nu.
11:15
Okay, inside of this function how do we
check the numbers greater than zero?
11:17
Or greater than negative one, rather.
11:22
Return num greater than or equal to zero.
11:25
Does that work?
11:28
Good for everybody?
11:31
'Kay?
11:34
That's it.
That's my entire function.
11:36
All I'm doing is making sure that number's
bigger than that.
11:38
And in here I have to tell it what
function to run.
11:42
All right, I'll scroll that up a little.
11:46
As much as I can since I'm at the bottom
of my file.
11:49
So all we're doing is we're using filter.
11:54
We're using our positive function we just
wrote.
11:56
And we're using our nums list that's up at
the top.
11:58
'Kay?
12:03
Shall we see if it works?
12:05
Yay.
12:16
It does.
Cuz we only have six errors out of
12:16
seven tests.
12:18
So we got that one to work.
12:19
Somewhere up here will be a little sign
that says it worked.
12:22
Yeah, there's our dot.
12:24
The rest are all e's.
12:25
All right that's our way we're gonna do
this, this whole TDD thing so.
12:28
Let's go to another one, yeah?
12:35
[BLANK_AUDIO]
12:36
Okay, our next test is no non-zero
numbers.
12:38
So all the numbers that are not zero.
12:43
So short cut on this one, anybody tell me
the short cut real quick?
12:45
We talked about what filter does.
12:48
>> [INAUDIBLE].
12:50
>> Right.
12:53
So, non_zero_numbers is what we have to
call this.
12:54
So, filter None and nums, right?
13:00
Cuz zero is falsey thanks to the glory of
Python.
13:04
Sorry for things like, flashing up there,
my, my Emacs likes to do a lot of things.
13:11
All right.
13:17
I also think it's kinda cool that I wrote
way more lines of code for
13:18
tests than I have to write for solving
this.
13:21
And we're gonna make it even shorter by
the end if we get to lambdas.
13:24
So, yay.
13:26
Or list comprehensions.
13:28
All right, let's see if that passes.
13:30
It does.
Five errors, not seven.
13:33
All right.
13:36
What's our third one?
13:38
No vowels in one word.
13:42
So I got a word.
13:46
My word is California.
13:47
I don't want there to be any vowels in it.
13:50
So vowel is my variable here.
13:55
Sorry let me find my word back up here
again.
14:05
State, that's my word.
14:07
Okay so what function would I write?
14:11
[BLANK_AUDIO]
14:14
Actually that's not gonna be a word that
comes in.
14:22
Gonna be a letter.
14:24
Because when we look at a word as an
interval we just get the letters.
14:26
Right?
14:30
So how do we get rid of the vowels?
14:32
If letter in aeiou, actually
14:35
we'll do it easier, not in [NOISE].
14:41
Or return true, either way.
14:48
Returning the letter is truthy, returning
true is very truthy, because it's true.
14:53
All right, and then no vowels.
14:58
All right.
15:06
See if it works.
15:07
Oh, it didn't work.
15:09
Why didn't that work?
15:10
No_vowel_word.
15:13
That's what I'm supposed to call it?
15:17
No_vowel_word.
15:19
Wow, I picked weird variable names.
15:25
Still didn't work.
15:29
[BLANK_AUDIO]
15:30
Okay, I'm gonna cheat for a second.
15:39
[BLANK_AUDIO]
15:40
no_vowel_word.
15:49
Oh, that's right.
15:52
I gotta pass in an actual word.
15:53
All right.
15:54
Okay.
15:56
[BLANK_AUDIO]
15:56
I apologize.
16:08
I wrote these like late one afternoon.
16:09
So, some of them are gonna make a lot more
sense than others.
16:12
There we go, four errors.
16:16
Okay, I'll go back to how I did that one.
16:17
So what we did was we just joined all the
letters together.
16:19
Cuz we get back this list-like object from
the filter.
16:22
So we just joined them all back together
into one word.
16:28
Just to make sure it was a word.
16:31
I probably shoulda left it as a list but
whatever.
16:34
It works.
16:38
Okay so we call a filter with no vowels on
our state name lower cased.
16:44
Right, and then that gives us back this
list-like object and
16:50
so we join it back together with no
spaces.
16:55
So that it's a string again instead of
this list-like object.
16:58
That's only cuz of how the test was
written that we have to do that.
17:05
If the test wasn't written to where
17:08
it's calling this .lower, then it wouldn't
have had to do that.
17:14
But it's okay.
[COUGH]
17:19
[BLANK_AUDIO]
17:21
Cool, okay any questions at this point?
17:27
We've done three things for filter.
17:30
Everybody feeling okay with filter?
17:34
All right, you want me to leave the rest
for you to do later, and
17:36
we can go onto map.
17:39
Let's do one more filter.
17:43
All right, that was awfully quiet.
17:45
[LAUGH] Let's skip the no false-y cuz
that's pretty easy.
17:47
What I got here?
17:53
Only modulo three?
17:55
Only words over ten characters.
17:56
That'll be a fun one.
17:58
All right, so, I got my word list here,
right?
17:59
All these words.
18:06
Tons and tons of words.
18:08
In fact if we do ipython from test_filter
import as let's do import test_filter.
18:11
We get back this generator.
18:26
[SOUND] Wait I need two of those.
18:27
[BLANK_AUDIO]
18:30
Len list.
18:33
So we get back 235,000 words.
18:36
I only want the ones that are over ten
characters.
18:37
All right?
18:41
That's easy, right?
18:42
How hard is it to, to only have words over
ten characters?
18:44
'Kay.
So let's do that.
18:48
>> Can you show what you had [INAUDIBLE]
last one?
18:50
>> Yup.
18:53
That right there.
[BLANK_AUDIO]
18:55
I will make all of the answers available
at the end as well.
19:01
I'll set up a, a branch on the repo that's
answers, and
19:05
that'll have the completed ones.
19:07
[BLANK_AUDIO]
19:09
Just in case anything gets missed.
19:12
All right so let's start ten letter words.
19:17
And I actually had to do this several
times to make sure that like ten letter
19:20
words was still something feasible.
19:23
Cuz I started at like eight and it was
still like 10,000 words.
19:25
And that was just stupid.
19:28
okay.
19:31
So ten_letter_words has to be words that
are ten letters or more.
19:31
So let's do like word_length for our
function.
19:37
And then we're gonna pass in word_list.
19:41
All right.
19:46
So help me write word_length.
19:47
It's gonna get a word, what do I wanna
send back?
19:53
[BLANK_AUDIO]
19:57
So return, len word greater than or equal
to 10.
20:04
>> So you're changing [UNKNOWN] cuz if
it's only words over 10 characters.
20:11
>> [INAUDIBLE]
Characters.
20:16
>> yeah.
Good catch.
20:21
Bonus points.
20:24
All right so, our word length just says,
20:27
hey is this word more than ten letters
long or equal to ten letters.
20:31
We could have also just done greater than
9.
20:38
Since words always have whole numbers, for
20:42
their length, you can't have a half a
letter.
20:44
Give that a try.
20:48
Only three problems, yay.
20:53
All right.
20:55
I'll go back to this in case anybody
missed word length, or 10 letter words.
20:57
This filter make sense?
21:03
You get a pretty good idea of how filter
works.
21:04
It's just for truthy things, right?
21:06
[COUGH].
21:08
>> Inside of, now we say, well,
21:09
my memory works, maybe Craig can remind me
itertools, I think.
21:12
There's filter false.
21:15
Is that itertools or functools?
21:17
One of those two, either inside of
itertools or
21:19
functools, there's filter false, which is
the opposite of filter.
21:22
So, filter only gives you back truthy
things,
21:25
filter false only gives you back falsey
things.
21:28
So depending on what your scenario is.
21:32
It's really not that hard to swap a
Boolean,
21:34
when you're writing filter stuff and just,
make it work the other way.
21:35
But, if you just can't do that for some
reason, [UNKNOWN] does exist.
21:39
And it's pretty cool.
21:43
Works exact same way.
21:45
There's tons of cool stuff in functools
and itertools yeah.
21:47
We'll eventually teach them, cuz I like
them.
21:52
Okay, so let's move on, let's do map.
21:55
All right, I think maps actually are
little bit simpler.
21:58
But, that's cool, alright, so we've got a
bunch of numbers again.
21:59
We've got numbers from one to 20.
22:05
We've got some time zone strings, how many
of you watched the dates and time scores.
22:07
Couple, all right, it's not the most
exciting course.
22:13
And we've got a format string that we're
gonna put stuff into and
22:17
we have some dictionaries that we're going
to put into that format string.
22:21
Alright, so the first thing I want is I
want to
22:27
get back the double of all of my numbers.
22:30
So I've got all these numbers, I want to
double them all.
22:34
So instead of one, I want two, instead of
two, I want four, that kinda thing, right?
22:36
And we're gonna put those in a variable
called double_nums cuz, creative.
22:41
Double_nums = map, something against nums.
22:47
All right.
This should be an easy function to write.
22:54
How do we double numbers?
22:55
[BLANK_AUDIO]
22:57
So we'll return num times 2.
23:02
[BLANK_AUDIO]
23:04
All right.
23:09
So double num, so we're just gonna run
map.
23:10
And I'm gonna pass it doubler,
23:12
which is our function that returns number
times 2 for each of the numbers.
23:14
All right?
23:17
[SOUND] Let's do another one before we
before we test this.
23:19
Let's do the half numbers, cuz that's,
that's the same idea, right?
23:23
[SOUND] So we've got half nums, and it's
gonna be, we'll say, halver.
23:26
Halfer?
23:33
>> [LAUGH].
23:35
>> Whatever it would be.
23:36
[LAUGH] naming things is one of the hard
problems in computer science.
23:37
[BLANK_AUDIO]
23:41
All right, and this would return num
divided by 2.
23:45
Right?
23:48
So double nums we're multiplying by 2,
half nums we're dividing by 2.
23:51
Really straightforward, yeah?
23:55
Okay?
23:59
By the way, I like map.
24:01
Map is just like, oh yeah.
24:02
[NOISE] Obviously that's the one I'm gonna
do.
24:03
So five tests, only three of them failed.
24:05
So the time zones, the num strings, and
the format strings are all bad still.
24:07
Let's fix those.
24:13
All right.
24:14
Num strings looks pretty easy.
24:16
Num strings actually looks insanely easy,
because all we're wanting to do is
24:17
make each of our numbers a string.
24:24
I did this one like 15 minute ago.
24:29
Remember what it was?
24:31
All right, we're just gonna
24:32
pass our string function, or our string
class that acts like a function or other.
24:38
And we give it to the, the nums variable,
all right?
24:43
And the the nice thing about this is since
there's no side effects,
24:48
our nums never changes, right?
24:51
We can do all sorts of stuff to nums,
24:53
we can do anything we want, and nums is
never gonna change.
24:55
That's really good because if I'm getting
data from a source like say, Twitter.
24:59
And I wanna parse this data repeatedly.
25:03
If I go and change it, I'm never really
sure what state its in.
25:05
But if I'm always just processing it from
its raw state,
25:09
then I know what state its in.
25:12
Its in the state that Twitter gave it to
me.
25:14
So I don't have to deal with, okay let's
make sure that this thing is still there.
25:16
Or, make sure that I didn't rename this
part or whatever.
25:20
All right [SOUND] yay.
25:23
All right.
25:27
So, we just have two more.
25:28
You wanna solve these?
25:29
Let's solve these.
25:31
Which one do you wanna do first?
25:33
Do you wanna do time zones?
25:34
Whoo, time zones.
25:35
Or do you [LAUGH] wanna do the string
formatting?
25:37
>> [SOUND] Time zones.
25:41
>> Time zones, all right, time zones.
25:43
Time zones.
25:47
Map.
25:49
[SOUND] And, what did I call that thing up
there?
25:50
Time zone strings.
25:58
All right.
26:00
So what our test is wanting.
26:05
Where is it?
There's what are test is wanting.
26:09
Are test wants all of the, we want a
datetime.tzinfo instance, for
26:11
each of the timezones that are there.
26:17
So, actually forgot how I did that one.
26:19
I've been doing way too much time on stuff
lately.
26:25
I used pytz, of course, which is why pytz
is imported.
26:29
All right.
So, let's make a method,
26:33
[SOUND] that makes timezones for us.
26:41
All right, if you haven't watched the
course,
26:50
you may not know how to do this one, or if
you haven't played with pytz yourself.
26:52
So, all we want to do is we want to
26:56
return pytz.timezone [SOUND] with the name
that was passed in
26:59
[BLANK_AUDIO]
27:04
That makes sense?
27:14
We got the names, we're just generating
all these timezones.
27:15
All right?
27:17
All right.
27:19
Let's see if that one passes, and then
we're gonna hopefully make it simpler.
27:20
Air pass all right.
27:26
So, we know that map calls a function on
everything.
27:27
What do we pass in, right?
27:33
So, I should be able to do,
27:35
[SOUND] pytz.timezone because that's a
function, right?
27:37
It generates a time zone or
27:42
a tz info thing, we really don't want to
go into what timezones are.
27:44
So I should be able to just call that
method straight from there,
27:51
without having to use my time zoner.
27:53
Yep, I can.
27:56
So, I don't even have to write this code,
that's useless code.
27:57
I wasted two whole lines and a blank
liner, too.
28:01
Don't waste lines of code, they're
precious.
28:06
Okay.
28:08
So, our last one is this format strings,
28:09
we've got the string up top, let's go look
at it.
28:13
This format string, that it has a couple
of named placeholders.
28:17
One of them's called name, the other is
called thing.
28:21
It's a very creative sentence.
28:24
And then we have these dictionaries, that
have keys and values in them.
28:27
We're gonna put those into the string.
28:31
Yeah?
28:35
All right.
28:36
So, we actually have to write code for
this one.
28:38
What's this supposed to be?
28:42
Statements, map let's do formatter.
28:44
And we want to pass in here, is the
dictionaries.
28:52
Cuz that's what we're gonna loop through,
all these dictionaries.
28:56
[NOISE].
28:59
[BLANK_AUDIO]
29:06
See how hard it is naming things, I can't
even come up with a good variable name.
29:10
All right trying to get this so you can
see more.
29:15
So what we wanna do is we wanna return
format-string.format and
29:19
we're gonna pass in the values as keyword
arguments.
29:27
Is the star star surprising and new to
anybody?
29:30
All right.
So, star star is really cool in Python.
29:34
It turns a dictionary, into keyword
arguments.
29:36
So, normally it have like, key colon value
in your dictionary.
29:39
In your function call, you now have key
equals value.
29:43
So, you don't have to find those values
yourself,
29:47
you don't have to deal with reformatting
stuff in whatever weird way.
29:49
You don't have to do, like, you know,
29:53
my_dict(key)=my_dict(value) when you're
filling something
29:55
out, because that would be really annoying
and take forever.
30:04
So the star star turns that into keyword
arguments, which is really handy.
30:10
All right.
30:15
So, we call formatter on our bunch of
dictionaries.
30:16
That in turn has whatever value comes in,
or
30:21
sets the value since the dictionary with
multiple values, right?
30:25
We send into our format strings format
function, method.
30:28
Yay, all the tests pass.
30:32
All right, are there any questions about
map?
30:38
Is map weird or confusing to anybody?
30:40
It's a little strange so if you have
questions, feel free to ask.
30:42
No?
Everybody's good?
30:47
All right.
30:48
You had your chance.
30:50
Now we're going on to reduce.
30:51
All right.
30:54
So, reduce.
30:55
The refresher takes a function, applies
that function to the first two items in
30:57
an interval, takes that result and applies
it to the third item, fourth, fifth,
31:01
sixth, so on, so we end up with only one
item at the end.
31:06
'Kay?
31:11
And it looks like I left the functions in
there.
31:17
So, that's handy.
31:20
All right.
31:21
[LAUGH] So, we wanna add some numbers.
31:22
so, add nums is reduced.
31:25
Which I imported, yay.
31:31
And our function is going to be
add_two_nums.
31:34
And we're going to pass it nums.
31:37
So what does add_two_nums do?
31:38
It adds two numbers.
31:40
This is probably the worst example I have
tonight,
31:42
because you should really just do the sum
function with this, instead of reduce and
31:45
a function that adds numbers together.
31:51
But regardless, it's there, you get the
idea of how it works.
31:54
All right.
31:59
Let's do multiply numbers as well.
32:01
So, this should be multiply nums.
32:04
We're gonna write a call reduce,
32:05
multiply two nums, and our nums.
32:15
So multiply two nums, as you can probably
guess, multiplies two numbers together.
32:18
So again, instead of the sum of the
product, we get the, or sum of the list,
32:24
we get the product of the list.
32:28
This isn't one that's built in as far as I
know.
32:30
So, you'd have to write this one.
32:33
>> [INAUDIBLE].
32:35
>> There, not for
32:40
multiplying a list as it is there is a
built in way to solve this problem without
32:42
having to write a function though, and we
can talk about that in a minute.
32:47
It's a really cool library called
Operator,
32:51
that's part of the standard library.
32:53
That has tons and tons of stuff in it, but
one of the cool things it
32:55
has is a function called mul that
multiplies two numbers together.
32:58
So you just use operator mul, instead of
writing multiply two nums.
33:02
All right and then let's solve longest.
33:08
[SOUND] And what did I call it?
33:16
Did I call it states?
33:20
I did.
33:21
[BLANK_AUDIO]
33:22
Okay.
33:26
So we'll look at this one.
33:27
It takes two strings.
33:28
Yeah?
Two strings.
33:31
And it returns if one is bigger than two,
33:33
then it returns one, otherwise it returns
two.
33:36
There's another way of doing this too,
33:39
but we'll talk about that later if we have
time.
33:41
All right, so
33:45
we used three already written functions,
but this should solve our tests.
33:46
We're good.
33:56
There's our tests.
33:57
All right, any questions about reduce?
34:00
Does that one make sense?
34:04
Function that rates over sets of things.
34:09
Gives you back one final answer.
34:12
What was that?
34:13
Oh, work they were just doing?
34:15
Yeah, so, we have two strings that come
in,
34:18
which we're creatively calling string one
and string two.
34:21
We're checking to see if the length of
string one is greater than the length of
34:26
string two.
34:30
And if it is then we send back string one.
34:31
If it's not, which means that string two
must be longer or
34:34
they're equal, which I've made sure they
weren't then it returns string two.
34:37
Yeah, so the first time through it's gonna
have Ohio and Alaska.
34:46
So which one's longer?
34:51
Alaska, so the next time though,
34:53
Alaska becomes state one, and California
comes in.
34:55
So, which one's longer?
34:59
California.
35:00
So, state one becomes California, state
two becomes Oklahoma.
35:02
California is still longer so, there's
nothing else to take as another argument,
35:06
so it says okay, California's your answer.
35:11
And sends that back.
35:13
So this works with a lot of things.
35:16
If you're like hey, I've got, again, maybe
all these people, I need to know
35:17
which one's been employed the longest, and
they all have, you know, start date.
35:20
Make a date time from when they got
started,
35:24
subtract it from now, you find out hey,
this dude's been here for
35:26
10 years and this women's been here for
12, so she's got seniority.
35:30
Reduce is actually a lot more handy than
filter or
35:36
map, but it's one that you won't see used
as often, which is weird.
35:38
So, lets see what's next in my key note.
35:43
[NOISE] More blank slides, functions to
know and love.
35:46
I don't want to cover every single of
these, but
35:51
if you look through the tests you'll see
some of these used.
35:53
These are functions that come up pretty
often and
35:57
functional programming in python.
35:59
So the first two are related, max and min.
36:01
Max gives back the biggest of the things
that are sent in,
36:05
min gives back the smallest of the things
that are sent in.
36:07
So, your state names you should be able to
do max and min on those.
36:10
Although that may do alphabetical sorting,
I don't remember.
36:14
We can test it later.
36:17
Any and all are related.
36:18
Any takes an iterable, and it gives you
back a true,
36:21
if any of the things in the interable are
true.
36:24
So, it can have 1,000 false things and one
true thing, and it'll come back as true.
36:27
Cuz at least one of those things is, is
true, right.
36:32
All is kind of the exact opposite of that,
36:35
it will only tell you true if every single
thing in there is true.
36:37
You'll see me use all a lot in the tests.
36:42
And if you could see your code challenge
tests, you'll see all used a lot,
36:44
because I love all.
36:47
All's especially great if you put
conditions inside of there.
36:50
So, your list items are like, x is 5 or x
is less than 2.
36:53
Those are gonna evaluated as the true or
false.
36:58
And then reversed takes an irritable and
37:01
you remember how we did list dot reverse
and we got, the list reversed in place.
37:03
So reversed will actually send you back a
new list,
37:08
that has been reversed from the old list.
37:11
So, it doesn't overwrite your old one.
37:14
Cuz we don't wanna mutate things.
37:16
And then sorted is the same idea, instead
of calling list.sort you
37:18
can use sorted on a list and you get back
a sorted version of the list.
37:23
Sorted has some other stuff you can add to
it, to change how it sorts.
37:27
But that is beyond tonight.
37:31
We will end up covering all of this stuff
at some point so, yeah.
37:34
[INAUDIBLE]
It'll do a natural sort.
37:39
okay.
First, let me repeat that.
37:46
[LAUGH] since [UNKNOWN] pointed that out.
37:48
so, if you don't provide a way to sort, to
sort it, what does it do?
37:51
So it does a natural sort.
37:56
And what a natural sort is, is kind of how
you think of things as being sorted.
37:58
So, like, numbers will come first, and
then characters.
38:02
Right?
I may have that backwards.
38:05
I'm pretty sure that's right.
38:07
So you'd get,
38:09
you know, numbers one through ten, or
whatever your order is, yeah?
38:10
And then you'd get your words and they
would be sorted alphabetically.
38:14
>> So [INAUDIBLE]
38:17
>> I think caps may come first, but I
don't remember.
38:21
So all these things you can play with.
38:23
Sorted is pretty handy on its own.
38:27
Once you start writing the sorting
functions that it expects,
38:30
it opens up like whole new worlds.
38:33
Cuz you can just sort by crazy,
38:35
like I wanna sort by these five nested
attributes, and it'll handle it for you.
38:37
What else is in here?
38:45
Questions, we'll come back to that one,
cuz it hasn't been that long.
38:46
Okay.
38:51
Let's talk about lambdas.
38:52
Anybody use lambdas?
38:54
You have, probably.
38:56
Who's written anonymous functions in
Javascript?
38:57
Where you just pass function into
something, those are lambdas.
39:00
They just don't call them a cool name.
39:02
okay.
39:05
So let's go write a lambda real quick.
39:06
So we'll have nums, I'll again make it a
list of one through 20.
39:11
All right.
39:17
So, nums is just some numbers, right?
39:19
And we had earlier, we had this map and
39:24
we had a doubler function when we passed
the nums, right?
39:27
You remember doing that?
39:30
All right, I don't wanna write doubler,
because I'm lazy.
39:32
All right, so nums I still have,
39:35
I don't wanna write doubler, so I'm gonna
write map.
39:39
I'm going to write the word lambda, which
I have a really hard time typing so
39:44
tell me if I misspell it.
39:47
So lambda is an ominous function.
39:49
Functions take arguments, right?
39:50
So after we say lambda which says give me
an ominous function we can tell it
39:53
what arguments that function is going to
take.
39:57
So.
39:59
>> Doesn't matter, I'm gonna call it num.
40:00
Okay.
40:04
And we do a colon, cuz it's a function, it
starts with a colon.
40:05
And the weird thing with lambdas and
40:08
Python is you can't press return, so they
all have to fit on one line.
40:11
There's a cheat around that, but don't
worry about that for right now.
40:15
You're new to lambdas, just write them
like they are.
40:18
And then they have an implicit return,
40:21
they automatically return whatever they
calculate.
40:23
So we're just gonna do num times 2, 'kay.
40:26
That's my function.
40:30
This lambda thing, all it does is return
num times 2.
40:32
Then I pass in nums.
40:37
And I'm gonna make this a list so that
you'll be able to
40:40
see the numbers instead of seeing a map
object, which will make no sense.
40:44
Yay!
40:50
So I don't have to write functions if I
don't want to.
40:51
As long as it's something short.
40:53
I mean, if you were doing all sorts of
complex stuff, you obviously probably
40:55
don't wanna use lambda's, unless you can
break it up into a lot of little steps.
41:00
But if you're just doing something short
and quick, lambdas are amazing.
41:04
So what that means [SOUND] is we
41:10
can do all of these without functions.
41:15
So let's solve solve this modulo three
one,
41:22
modulo_three_nums is gonna be a filter,
and we're doing it with nums.
41:27
All right, so I have a lambda, right?
41:36
And it takes a number, and
41:41
I'm gonna return if that number modulo 3
is equal to 0, 'kay.
41:43
Cuz modulo is weird as Dave can tell you.
41:51
And we have to make sure that it's equal
to zero, all right.
41:53
Now, we'll, we'll see if anybody gets
this.
41:58
You should.
42:04
Why do I have to make sure that it's equal
to 0, instead of just doing modulo three?
42:05
Because if I just do modulo three, I get
back either a number or I get back zero.
42:10
Right?
42:15
So on ones where it actually is modulo
three, I'd get back zero, which is falsy.
42:18
Which would make filter not included.
42:23
So that's what we have to do the, is equal
to zero, so we get back true.
42:25
It's a weird one but it works.
42:30
And it makes sense sorta.
42:33
Lambdas in their very simple, simple
sense.
42:36
Anybody completely lost on lambdas?
42:40
There's all sorts of crazy ways you can
break them,
42:41
but we're not gonna worry about those
right now.
42:44
And then you can break Python using
lambdas too which is really fun.
42:48
I'll show you how to do that in a minute
if you want.
42:53
All right, so that was in filter.
42:55
Let's run that.
42:56
All right.
42:58
So we just have two wrong ones now instead
of three.
43:00
We had three wrong ones before, just two
now.
43:03
All right.
43:05
That is lambda.
43:09
Let's do lambda inside of one of our maps
as well, oh we already did a doubler.
43:12
[NOISE] so we can do it here too.
43:18
So we've got lambda, and we've got values.
43:24
I'm actually just basically copying what
happened up there in formatter,
43:28
format_string.format (**values).
43:31
All right.
43:38
It's literally the exact same code I just
write,
43:40
I just wrote lambda instead of def
formatter(values) return.
43:43
So I saved what, 30 characters?
43:48
But if I'm only ever using this once or
maybe I'm assigning my map
43:51
to something else somehow so that it can
be called multiple times with multiple
43:57
values then you know, I save myself a
decent amount of typing.
43:59
Let's make sure that still passes.
44:05
[SOUND] It does, yay!
44:06
And then, I guess the last thing, before
we do question.
44:10
Actually, we'll go ahead and do questions.
44:16
I'll leave list comprehensions for another
time.
44:18
But before we do questions, I've got one
other thing that's important.
44:20
So if you want help, if you're like,
44:23
Python's really cool, but some of the
stuff is confusing.
44:25
There are two awesome groups here in
Portland.
44:28
One of them is the PyLadies.
44:30
Yeah, PyLadies.
44:33
They meet like 8,000 times a week.
44:36
It, seriously their, their meetings are
crazy.
44:39
But they're an awesome group of women
beginner all the way up to expert.
44:43
Great group if you need help and are of
the womanly persuasion.
44:48
And then every Monday night,
44:53
there's a thing that they call the Python
Flying Circus.
44:54
This happens over at the Code Guild
headquarters, which I can never
44:56
remember the street they're on, I think
it's Water, or Paper, or some other noun.
45:01
But if you join the PDX Python group,
45:06
which is our general Python thing, you'll
get tons of meetups.
45:08
But they meet up every single Monday night
and it's pretty awesome.
45:11
You show up, if you've got questions
they've got mentors.
45:15
If you want to mentor people, they've got
questions.
45:17
awesome, awesome group to hang out with.
45:21
All right, so now I'll go back to my
questions slide, just so it looks cool.
45:24
Anybody have questions about functional
programming in Python?
45:29
Yes.
>> [INAUDIBLE] How do I make my lambdas on
45:31
two lines?
45:35
>> How do you make lambdas on two lines or
more?
45:36
But that's cheating.
45:38
>> [INAUDIBLE]
>> All right.
45:39
So I'll show you a couple of fun things
with lambdas.
45:44
Cuz I like lambdas.
45:47
I think lambdas are really cool.
45:47
But I don't like a couple of the rules
about lambdas.
45:49
One of which is they're temporary, they're
anonymous.
45:51
The other which is they can't be on
multiple lines.
45:55
And the third of which is they don't give
me any help.
45:56
So let's solve those in not that order.
45:58
So multiple lines.
46:01
map, sorry, list map.
46:04
[NOISE] There we go
46:09
I'll eventually get
46:14
enough parenthesis.
46:20
You make it a container.
46:27
It's a hack but it works.
46:30
If you find that you're constantly writing
lambdas that are three, four,
46:32
five lines long, just write a function.
46:36
Don't, don't mess with lambdas like that.
46:39
It's just, it's really not worth it.
46:41
Cuz at some point you're gonna forget that
open parenthesis and
46:42
then, you're just lost.
46:45
So let's talk about breaking lambdas,
46:48
cuz lambdas, that lambda doesn't really
exist, right?
46:49
I mean it's, it's there but it only exists
so long as map is running.
46:53
But if I've written a really cool lambda
and
46:56
I wanna have it around for a long time, I
can just name it.
46:57
[NOISE] So now I can do.
47:03
[NOISE]
47:08
Yeah.
47:13
So now doubler exists.
47:20
It's not a real function and
47:22
it's not really a lambda, it's just a
thing that's there.
47:23
Cuz if I do like type doubler.
47:27
I mean it's a function, it is,
47:30
because lambda's are functions, but yeah,
it's not really a function anymore.
47:34
Yes?
>> So then like,
47:39
what's the advantage then, you don't have
to type return, is that?
47:40
>> So the advantage to lambdas is, yeah,
you don't have to type return.
47:45
And if it's something you're just doing
once, it's,
47:48
seems kinda silly to go write a two line
function if you don't have to.
47:53
If I'm only ever gonna do with once,
47:57
why am I wasting memory holding on to a
function?
47:59
Why am I wasting lines of code by writing
the function?
48:01
>> So in the case of like [INAUDIBLE]
would that make sense
48:04
[INAUDIBLE] inside that function to like,
scope it or whatever?
48:09
>> The naming like this, right at the
doubler equals?
48:17
>> Like if you want to use the same lambda
more than once [INAUDIBLE].
48:20
>> So the question is, does the naming
only make sense if
48:23
you need to use it more than once in a
function?
48:26
Yeah, pretty much.
48:29
It's, I, I, I know I'm gonna need to do
this a couple of times I don't
48:30
wanna write it over again.
48:34
And for some reason I'm opposed to nested
functions, so I named my lambda.
48:35
So then, the other thing with breaking
lambdas.
48:41
If I do help on the doubler.
48:44
I, of course don't get anything because
it's just a lambda but meta programming.
48:48
So doubler.doc equals doubles numbers.
48:53
And now I can do, help(doubler) and I get
hey, it doubles numbers.
48:59
But it's still a lambda.
49:03
It still doesn't really know what's going
on, but it's a lambda and it's there.
49:05
You're not supposed to do these things to
lambdas, don't,
49:09
don't do these things to lambdas.
49:10
But lambdas like all functions in Python
they can do star args, they can do
49:13
star star kwargs they can they are
functions for all intents and purposes.
49:16
They just can't have returns in them or
new lines in them.
49:20
Like one of these.
49:30
That's just me not counting parentheses
correctly.
49:31
And then Python going, hey you missed a
parenthesis.
49:33
Yeah, it's, I do that a lot.
49:36
I love having syntax highlighting in
browsers [LAUGH] or editors.
49:39
Cuz, yeah.
49:43
All right.
49:45
Anybody else?
49:46
Any other questions or problems with
functional programming?
49:47
Yeah, Portia.
49:51
>> This is more of a high level question.
49:52
>> Okay.
49:54
>> What problem is functional programming
solving like,
49:55
what convenience is it bringing to the
program?
49:58
>> Okay.
So
50:01
what convenience, what problem does
functional programming address?
50:02
So functional programming isn't like a
panacea, right,
50:06
just like object oriented programming
isn't.
50:11
Object oriented programming will not be
applicable in
50:12
every single scenario that you find
yourself in.
50:16
And functional programming won't either,
but you can often do
50:18
things a lot faster and cleaner using a
functional approach than you can in
50:22
writing a class or, well a class, yeah
writing, you know, creating objects.
50:26
Or writing a function that maybe does all
this work in one function.
50:32
And then you have to remember that is does
all that stuff and,
50:36
what if something changes?
50:38
What if I no longer wanna do that step, I
have to go edit this thing.
50:40
Functional programming, that mentality
where you're writing things very small and
50:44
reusable, you get to the point where, if
you're always writing like that,
50:48
editing your approaches to code becomes a
lot simpler.
50:53
I just take out one function call.
50:55
Or I go change this one function, and I
don't have to worry about
50:57
what happens elsewhere, because, you know,
I'm paying attention to this one thing.
51:02
So it's,
51:06
the benefit it gives is that things are in
smaller more digestible packages.
51:09
And, yeah, that's pretty much it, smaller
packages.
51:12
>> So I guess it prevents the programmer
from making a function and
51:18
having the function do like five or six
things.
51:21
>> Can prevent somebody from [LAUGH] yeah,
if if you have the the functional
51:25
programing mindset you're, you're used to
always creating these small little,
51:30
I mean they almost seem pointless these
little functions, cuz they're so tiny.
51:35
The ones that we wrote tonight are,
51:41
are very short, you'll ending up writing
ones that are five, ten lines long.
51:42
But they do one thing, one major thing,
right?
51:45
So it gets to where you stop trying to put
everything into classes that
51:49
you create for, just, I need a thing that
does a thing, right, so you build a class.
51:54
That works, but that's often way more
overhead mentally and in your program.
51:59
And it stops you from writing functions
that do 50 lines or a 100 lines of stuff.
52:04
Because you always break things up nice
and small.
52:10
[NOISE] I mean, I'm gonna pick on Chris.
52:13
He's always done object-oriented stuff and
when I first started learning
52:17
functional programming I'd be like, hey
try and do this thing!
52:20
And he'd start writing a class.
52:23
Which worked [LAUGH] and it does it.
52:24
But it's like that's not the approach.
52:28
>> What.
>> [LAUGH] Yes, that's why you're here.
52:31
All right, anybody else?
52:33
We're good?
52:38
All right, I will put the answers up in a
branch, I'll try to
52:39
make sure they all have lambda options and
stuff like that as well.
52:44
But, they, some of them may not.
52:47
And then, that's it.
52:49
That's our code.
52:50
[APPLAUSE]
52:51
You need to sign up for Treehouse in order to download course files.
Sign up