1
1

00:00:00,150  -->  00:00:01,830
<v ->Hi guys, and welcome back.</v>
2

2

00:00:01,830  -->  00:00:03,510
In this video, we're going to learn about
3

3

00:00:03,510  -->  00:00:05,890
first-class functions.
4

4

00:00:05,890  -->  00:00:08,700
In first-class function, just means that functions
5

5

00:00:08,700  -->  00:00:09,920
are just variables.
6

6

00:00:09,920  -->  00:00:12,660
And you can pass them in as arguments to functions and use
7

7

00:00:12,660  -->  00:00:15,830
them in the same way you would use any other variable.
8

8

00:00:15,830  -->  00:00:16,730
Let's get started.
9

9

00:00:18,170  -->  00:00:21,460
Here we have a divide function that raises a zero division
10

10

00:00:21,460  -->  00:00:23,540
error if the divisor is zero.
11

11

00:00:23,540  -->  00:00:24,820
We've seen this before.
12

12

00:00:24,820  -->  00:00:28,390
And then we have a rather weird looking function.
13

13

00:00:28,390  -->  00:00:29,530
Calculate.
14

14

00:00:29,530  -->  00:00:33,480
That takes in any number of arguments and collects them
15

15

00:00:33,480  -->  00:00:35,370
into this value stopple.
16

16

00:00:35,370  -->  00:00:37,480
We've seen this before and if you can't remember how this
17

17

00:00:37,480  -->  00:00:41,640
works, please look at the unpacking arguments lecture.
18

18

00:00:41,640  -->  00:00:46,310
Then it also takes a mandatory key word argument parameter.
19

19

00:00:46,310  -->  00:00:48,130
So that is operator.
20

20

00:00:48,130  -->  00:00:53,130
And then what it does, is it calls the operator function
21

21

00:00:53,320  -->  00:00:55,680
with the values.
22

22

00:00:55,680  -->  00:00:57,310
That's kinda weird.
23

23

00:00:57,310  -->  00:01:00,470
How does that work? How does it know it is a function?
24

24

00:01:00,470  -->  00:01:02,740
Well, the simple answer is, it doesn't.
25

25

00:01:02,740  -->  00:01:05,660
However, because we've got these brackets after the
26

26

00:01:05,660  -->  00:01:09,840
variable name, this here must be a function,
27

27

00:01:09,840  -->  00:01:12,920
since that is the syntax for calling a function.
28

28

00:01:12,920  -->  00:01:16,160
No where calling this operator variable as a function
29

29

00:01:16,160  -->  00:01:20,330
with the values passed in as individual argument.
30

30

00:01:20,330  -->  00:01:23,430
How would we use this calculate function?
31

31

00:01:23,430  -->  00:01:27,300
You could do something like result equal calculate
32

32

00:01:27,300  -->  00:01:28,930
and then notice that calculate takes in
33

33

00:01:28,930  -->  00:01:30,810
any number of arguments.
34

34

00:01:30,810  -->  00:01:33,600
So we're gonna type twenty and four
35

35

00:01:33,600  -->  00:01:36,570
and then were gonna type operator equals
36

36

00:01:36,570  -->  00:01:38,900
the divide function.
37

37

00:01:38,900  -->  00:01:43,120
But this will pass in the divide function
38

38

00:01:43,120  -->  00:01:44,940
as the operator
39

39

00:01:44,940  -->  00:01:48,910
and then we will only call it when we reach line nine.
40

40

00:01:48,910  -->  00:01:52,250
Notice that this divide function is not called here,
41

41

00:01:52,250  -->  00:01:54,470
it is only used as a value.
42

42

00:01:54,470  -->  00:01:56,360
If you wanted to call this function,
43

43

00:01:56,360  -->  00:01:58,160
you always have to put the brackets at the end.
44

44

00:01:58,160  -->  00:02:00,440
That's how you call a function in Python.
45

45

00:02:00,440  -->  00:02:04,970
So by not putting the brackets, you are passing in the value
46

46

00:02:04,970  -->  00:02:08,800
to which this name divide refers to, which is the function,
47

47

00:02:08,800  -->  00:02:11,200
as the value for this parameter.
48

48

00:02:11,200  -->  00:02:13,820
So the operator parameter now has the same value
49

49

00:02:13,820  -->  00:02:15,340
as the divide variable.
50

50

00:02:15,340  -->  00:02:17,740
They are both this function here.
51

51

00:02:17,740  -->  00:02:20,960
So you can call it as a function, passing in the values
52

52

00:02:20,960  -->  00:02:24,130
as individual values so that will give you twenty for the
53

53

00:02:24,130  -->  00:02:27,150
dividend and four for the divisor.
54

54

00:02:27,150  -->  00:02:30,380
This here is an example of using a first-class function
55

55

00:02:30,380  -->  00:02:33,160
because you can see that you can pass it in as an argument
56

56

00:02:33,160  -->  00:02:34,423
to another function.
57

57

00:02:35,500  -->  00:02:38,630
Functions in Python are just variables that happen to be
58

58

00:02:38,630  -->  00:02:42,290
callable. You can call them with the brackets at the end.
59

59

00:02:42,290  -->  00:02:44,170
But they're no different than any other value
60

60

00:02:44,170  -->  00:02:45,043
other than that.
61

61

00:02:46,540  -->  00:02:48,860
So now you can print the result if you like,
62

62

00:02:48,860  -->  00:02:51,410
and you'll see that that has [inaudible] called
63

63

00:02:51,410  -->  00:02:53,433
the divide function. And you get 5.0.
64

64

00:02:54,400  -->  00:02:56,700
If you change this to a zero though,
65

65

00:02:56,700  -->  00:03:00,280
you will end up with trace back because you tried to
66

66

00:03:00,280  -->  00:03:01,720
divide by zero.
67

67

00:03:01,720  -->  00:03:04,210
Something important that will be a little bit of problem in
68

68

00:03:04,210  -->  00:03:06,710
this code is that the calculate function
69

69

00:03:06,710  -->  00:03:08,670
takes in any number of values.
70

70

00:03:08,670  -->  00:03:11,490
But this operator expects two values.
71

71

00:03:11,490  -->  00:03:14,580
So if you put anymore, then you will also get an error.
72

72

00:03:14,580  -->  00:03:16,640
Because now you're gonna pass in too
73

73

00:03:16,640  -->  00:03:17,960
many positional arguments.
74

74

00:03:17,960  -->  00:03:20,290
See divide takes two positional arguments
75

75

00:03:20,290  -->  00:03:21,850
but three were given.
76

76

00:03:21,850  -->  00:03:24,400
So that is a small problem with this code here.
77

77

00:03:24,400  -->  00:03:26,340
But anyway the point of it was to show you
78

78

00:03:26,340  -->  00:03:27,950
how first-class functions work.
79

79

00:03:27,950  -->  00:03:30,060
Let's do another example.
80

80

00:03:30,060  -->  00:03:33,430
I'm going to define a search function that takes in
81

81

00:03:33,430  -->  00:03:35,943
a sequence of things to search through.
82

82

00:03:37,290  -->  00:03:40,880
It will also take what you expect to find
83

83

00:03:40,880  -->  00:03:44,460
and finally it will also take a function that will be used
84

84

00:03:44,460  -->  00:03:47,450
to extract information from each item in the sequence,
85

85

00:03:47,450  -->  00:03:49,400
match it against the expected value,
86

86

00:03:49,400  -->  00:03:51,313
and see if we find what we wanted.
87

87

00:03:52,270  -->  00:03:55,700
So we will iterate over the sequence,
88

88

00:03:55,700  -->  00:04:00,700
then we will run the finder function on the element
89

89

00:04:01,230  -->  00:04:04,210
and see if it is equal to the expected value.
90

90

00:04:04,210  -->  00:04:06,350
And if it is, we will return the element
91

91

00:04:06,350  -->  00:04:08,833
otherwise we will raise a runtime error,
92

92

00:04:10,000  -->  00:04:11,740
saying something like,
93

93

00:04:11,740  -->  00:04:15,383
could not find an element with expected.
94

94

00:04:17,040  -->  00:04:20,040
So this is a little bit of a confusing function there
95

95

00:04:20,040  -->  00:04:22,120
because it uses some parameters together with
96

96

00:04:22,120  -->  00:04:24,460
other parameters to find a third parameter.
97

97

00:04:24,460  -->  00:04:27,890
So a little bit weird but lets say now we have a list of
98

98

00:04:27,890  -->  00:04:32,890
friends and we want to find out which friend is called
99

99

00:04:33,080  -->  00:04:36,170
Bob Smith. Which here doesn't doesn't exist.
100

100

00:04:36,170  -->  00:04:39,890
The first thing we have to do is we have define a function
101

101

00:04:39,890  -->  00:04:42,980
that will run on one of these dictionary's,
102

102

00:04:42,980  -->  00:04:45,110
and give us back the name.
103

103

00:04:45,110  -->  00:04:47,620
So we will say, get friend name,
104

104

00:04:47,620  -->  00:04:50,630
and we will make it take one parameter
105

105

00:04:50,630  -->  00:04:53,690
and we'll say return friend, name.
106

106

00:04:53,690  -->  00:04:57,690
So here we have a function that, if we run it on an element
107

107

00:04:57,690  -->  00:05:01,330
in this sequence, we give us back the name property
108

108

00:05:01,330  -->  00:05:02,370
of that element.
109

109

00:05:02,370  -->  00:05:06,200
Be that what it may, remember this may fail if the element
110

110

00:05:06,200  -->  00:05:08,090
doesn't have a name property.
111

111

00:05:08,090  -->  00:05:11,670
Then we're going to print out the search,
112

112

00:05:11,670  -->  00:05:13,480
which is this function up here.
113

113

00:05:13,480  -->  00:05:16,120
We're gonna pass in the friends as our sequence
114

114

00:05:16,120  -->  00:05:18,790
so this search function is going to iterate
115

115

00:05:18,790  -->  00:05:20,223
over our friends.
116

116

00:05:21,210  -->  00:05:25,130
Then we're going to look for, Bob Smith.
117

117

00:05:25,130  -->  00:05:28,300
And finally how we're going to extract that value
118

118

00:05:28,300  -->  00:05:31,080
from each element is going to be by the
119

119

00:05:31,080  -->  00:05:33,663
get friend name function.
120

120

00:05:34,620  -->  00:05:37,390
So just to recap, get friend name
121

121

00:05:37,390  -->  00:05:39,260
will be the finder function.
122

122

00:05:39,260  -->  00:05:42,100
So that will run on each element.
123

123

00:05:42,100  -->  00:05:44,440
For example, for the first one, it will run on this
124

124

00:05:44,440  -->  00:05:47,290
dictionary here, and it will give you back the name
125

125

00:05:47,290  -->  00:05:51,123
property of that value. So you'll get back Rolf Smith.
126

126

00:05:52,010  -->  00:05:54,920
The Rolf Smith will be here, and you'll compare it with
127

127

00:05:54,920  -->  00:05:57,820
the expected value, which is Bob Smith.
128

128

00:05:57,820  -->  00:06:00,170
If they match, you will return that element,
129

129

00:06:00,170  -->  00:06:01,550
which is this dictionary.
130

130

00:06:01,550  -->  00:06:03,670
The same thing will happen for all the other ones.
131

131

00:06:03,670  -->  00:06:06,180
At this point, we don't have our friend called Bob Smith.
132

132

00:06:06,180  -->  00:06:08,830
So by running this we will get the run-time error.
133

133

00:06:08,830  -->  00:06:11,340
Could not find an element with expected.
134

134

00:06:11,340  -->  00:06:13,883
However, if we change this to Rolf Smith,
135

135

00:06:15,240  -->  00:06:17,090
then you will get it to work.
136

136

00:06:17,090  -->  00:06:20,770
The name is Rolf Smith and the age is twenty-four.
137

137

00:06:20,770  -->  00:06:23,400
This is quite a confusing bit of code but is a prime
138

138

00:06:23,400  -->  00:06:27,320
example of how first-class functions can be useful.
139

139

00:06:27,320  -->  00:06:30,050
So I would recommend giving it a go, playing around with it,
140

140

00:06:30,050  -->  00:06:32,490
see if it makes sense. And if it doesn't please ask a
141

141

00:06:32,490  -->  00:06:33,950
question in the course Q and A.
142

142

00:06:33,950  -->  00:06:36,120
Of course we're always happy to help.
143

143

00:06:36,120  -->  00:06:38,600
This is also a great place to use a lambda function.
144

144

00:06:38,600  -->  00:06:41,990
So instead of using that function, you can just define
145

145

00:06:41,990  -->  00:06:43,173
something like this,
146

146

00:06:44,190  -->  00:06:46,720
and just created it there where it is used.
147

147

00:06:46,720  -->  00:06:49,740
This is an alternative. No one is better than the other.
148

148

00:06:49,740  -->  00:06:51,820
You can do what you prefer. The other one is slightly longer
149

149

00:06:51,820  -->  00:06:53,660
but it does have a nicer name.
150

150

00:06:53,660  -->  00:06:55,080
Because you get the function name and it tells
151

151

00:06:55,080  -->  00:06:55,970
you what it does.
152

152

00:06:55,970  -->  00:06:57,520
So that's a good thing as well.
153

153

00:06:59,700  -->  00:07:01,500
Finally, you can use neither of these,
154

154

00:07:01,500  -->  00:07:04,640
do you can not define your own function or use a
155

155

00:07:04,640  -->  00:07:05,473
lambda function.
156

156

00:07:05,473  -->  00:07:09,130
You can just use a built-in from operator,
157

157

00:07:09,130  -->  00:07:11,030
import item getter.
158

158

00:07:11,030  -->  00:07:14,510
And here instead of this lambda function that is used to get
159

159

00:07:14,510  -->  00:07:17,395
a property of a object,
160

160

00:07:17,395  -->  00:07:19,950
you can use item getter
161

161

00:07:19,950  -->  00:07:20,980
with name.
162

162

00:07:20,980  -->  00:07:22,360
And that does exactly the same thing.
163

163

00:07:22,360  -->  00:07:26,220
This here, is a function that creates a function and
164

164

00:07:26,220  -->  00:07:27,570
lets you use it afterwards.
165

165

00:07:27,570  -->  00:07:29,730
So this is a little bit more advanced. We're going to learn
166

166

00:07:29,730  -->  00:07:32,923
more about functions that create other functions later on.
167

167

00:07:34,242  -->  00:07:36,673
So there you have it, that is the same thing.
168

168

00:07:39,010  -->  00:07:41,390
I set aside the operator built-in module,
169

169

00:07:41,390  -->  00:07:42,360
in fact quite a few of
170

170

00:07:42,360  -->  00:07:45,683
the Python built-in modules are amazing and really useful.
171

171

00:07:46,770  -->  00:07:48,450
All right, that's everything for this video.
172

172

00:07:48,450  -->  00:07:50,500
I hope you've enjoyed it, I hope you've learned something,
173

173

00:07:50,500  -->  00:07:52,150
and I'll see you in the next one.
