WEBVTT 1 00:00:00.290 --> 00:00:02.250 line:15% Hi guys and welcome back. 2 00:00:02.250 --> 00:00:04.030 In this video we're going to learn about 3 00:00:04.030 --> 00:00:08.330 first class functions and higher order functions. 4 00:00:08.330 --> 00:00:11.890 In Python, functions are first class functions. 5 00:00:11.890 --> 00:00:14.000 And what that means, is that they behave in 6 00:00:14.000 --> 00:00:16.580 exactly the same way as an integer or a string 7 00:00:16.580 --> 00:00:19.000 would when you assign them to a variable, 8 00:00:19.000 --> 00:00:22.200 or you pass them into a function as an argument. 9 00:00:22.200 --> 00:00:23.950 So here's an example. 10 00:00:23.950 --> 00:00:27.733 Imagine you've got a greet function that just prints hello. 11 00:00:29.650 --> 00:00:32.750 What you've got is you've got a function called greet 12 00:00:32.750 --> 00:00:36.070 and whenever you use the function you must type 13 00:00:36.070 --> 00:00:39.860 out the name followed by the brackets. 14 00:00:39.860 --> 00:00:43.570 Some functions you can put stuff inside the brackets, 15 00:00:43.570 --> 00:00:45.310 but in some functions you don't. 16 00:00:45.310 --> 00:00:50.010 However, you can, not use the brackets at all. 17 00:00:50.010 --> 00:00:54.150 And what that does is that does not run the function code. 18 00:00:54.150 --> 00:00:56.330 When you type out greet on it's own, 19 00:00:56.330 --> 00:00:59.850 what you are saying is the greet function. 20 00:00:59.850 --> 00:01:01.740 You are not asking python to run it, 21 00:01:01.740 --> 00:01:04.090 you are just referring to it. 22 00:01:04.090 --> 00:01:07.420 So just as you can refer to a string or a number, 23 00:01:07.420 --> 00:01:10.440 you can actually assign this to another variable, 24 00:01:10.440 --> 00:01:11.273 if you want. 25 00:01:12.320 --> 00:01:15.090 So here you've got the hello variable, 26 00:01:15.090 --> 00:01:19.710 and its value is the same value as the greet variable. 27 00:01:19.710 --> 00:01:21.540 And I know that greet is a function 28 00:01:21.540 --> 00:01:23.930 but it's really just the same as a variable, 29 00:01:23.930 --> 00:01:26.510 it's a variable that contains a function, 30 00:01:26.510 --> 00:01:30.100 and when you run the variable, then the function runs. 31 00:01:30.100 --> 00:01:31.690 But if you don't run it, 32 00:01:31.690 --> 00:01:34.210 then you're just referring to the contents, 33 00:01:34.210 --> 00:01:36.170 which is the function itself. 34 00:01:36.170 --> 00:01:38.060 If you do hello equal greet, 35 00:01:38.060 --> 00:01:40.900 now hello is also the greet function, 36 00:01:40.900 --> 00:01:42.383 and you can run it. 37 00:01:44.050 --> 00:01:47.600 So this is what the first class function means. 38 00:01:47.600 --> 00:01:50.210 When you have a first class function, you can assign it to 39 00:01:50.210 --> 00:01:53.840 other variables just as you can with strings or numbers. 40 00:01:53.840 --> 00:01:55.580 Interestingly, you can also 41 00:01:55.580 --> 00:01:58.563 pass a function into another function. 42 00:01:59.550 --> 00:02:01.210 For example, let's say you have a function called 43 00:02:01.210 --> 00:02:02.340 before and after, 44 00:02:02.340 --> 00:02:04.850 and it takes in a function as a parameter. 45 00:02:04.850 --> 00:02:07.626 Then we're going to print before. 46 00:02:07.626 --> 00:02:09.730 Then we're going to print after. 47 00:02:09.730 --> 00:02:13.223 And in the middle, we're going to call our function. 48 00:02:14.990 --> 00:02:19.160 In this case, we assume that the value of this parameter 49 00:02:19.160 --> 00:02:21.223 will be a function. 50 00:02:22.150 --> 00:02:24.838 So, if we have our greet function, 51 00:02:24.838 --> 00:02:26.890 that brings hello. 52 00:02:26.890 --> 00:02:30.800 Then we can do before and after, 53 00:02:30.800 --> 00:02:34.010 and pass to it the greet function. 54 00:02:34.010 --> 00:02:36.730 Notice that I'm not calling the greet function, 55 00:02:36.730 --> 00:02:39.880 because if I do that that runs through the function 56 00:02:40.846 --> 00:02:43.090 and then returns that value of this function return, 57 00:02:43.090 --> 00:02:44.590 which is none. 58 00:02:44.590 --> 00:02:46.610 But if I don't use the brackets, 59 00:02:46.610 --> 00:02:49.653 what I am passing through is the function itself. 60 00:02:50.520 --> 00:02:54.350 So when this gets passed to the "func" parameter, 61 00:02:54.350 --> 00:02:57.326 we're then going to print before, 62 00:02:57.326 --> 00:02:58.600 then we're going to run the function. 63 00:02:58.600 --> 00:03:00.270 And then we're going to print after. 64 00:03:00.270 --> 00:03:04.000 And this function here is the greet function. 65 00:03:04.000 --> 00:03:06.410 So this is going to print before, 66 00:03:06.410 --> 00:03:09.363 then hello, and then after. 67 00:03:10.620 --> 00:03:13.500 This is another example of first class functions. 68 00:03:13.500 --> 00:03:16.700 Because a function behaves when you interact with it 69 00:03:16.700 --> 00:03:19.300 in just any other way, like a string or a number, 70 00:03:19.300 --> 00:03:22.770 you can also pass it as an argument if you want. 71 00:03:22.770 --> 00:03:25.140 In some programming languages, functions are not 72 00:03:25.140 --> 00:03:27.820 first class, so you would not be able to pass it in 73 00:03:27.820 --> 00:03:29.320 as an argument. 74 00:03:29.320 --> 00:03:31.490 And I know that at the moment you may not really 75 00:03:31.490 --> 00:03:34.020 understand why this is of any interest. 76 00:03:34.020 --> 00:03:36.710 But later on we will learn about decorators, 77 00:03:36.710 --> 00:03:39.590 and that's a very interesting feature of the python language 78 00:03:39.590 --> 00:03:41.470 that makes extensive use of 79 00:03:41.470 --> 00:03:44.090 passing functions to other functions. 80 00:03:44.090 --> 00:03:45.700 I also mentioned at the start of the video 81 00:03:45.700 --> 00:03:48.690 that we would learn about higher order functions. 82 00:03:48.690 --> 00:03:50.880 A higher order function is something like 83 00:03:50.880 --> 00:03:52.070 before and after. 84 00:03:52.070 --> 00:03:55.420 Just a function that accepts another function 85 00:03:55.420 --> 00:03:56.393 as an argument. 86 00:03:57.400 --> 00:04:00.460 Before and after is a higher order function. 87 00:04:00.460 --> 00:04:04.360 Note that all functions in python are first class functions. 88 00:04:04.360 --> 00:04:07.270 So before and after function is a first class function. 89 00:04:07.270 --> 00:04:09.470 The greet function is a first class function. 90 00:04:09.470 --> 00:04:11.260 You can pass them as arguments, or assign them 91 00:04:11.260 --> 00:04:13.220 to variables whenever you want. 92 00:04:13.220 --> 00:04:15.200 This one is a higher order function, 93 00:04:15.200 --> 00:04:16.540 but this one is not, 94 00:04:16.540 --> 00:04:18.910 because this one accepts a function as an argument. 95 00:04:18.910 --> 00:04:20.010 And this one does not. 96 00:04:21.420 --> 00:04:24.210 Let's move on to a more slightly useful example. 97 00:04:24.210 --> 00:04:26.800 Let's say we've got an operations dictionary 98 00:04:26.800 --> 00:04:30.310 that contains some string keys, such as average. 99 00:04:30.310 --> 00:04:34.213 And the value assigned to the key is a lambda function. 100 00:04:37.120 --> 00:04:39.980 What we've got here is the key average and the 101 00:04:39.980 --> 00:04:42.620 lambda function associated with it, 102 00:04:42.620 --> 00:04:46.063 which calculates the average of a sequence. 103 00:04:47.410 --> 00:04:49.060 Then we can have a total, 104 00:04:49.060 --> 00:04:52.200 which is another function that takes in a sequence 105 00:04:52.200 --> 00:04:54.760 and returns the sum of the elements. 106 00:04:54.760 --> 00:04:57.515 And then you've got the top key, 107 00:04:57.515 --> 00:04:59.640 that again takes another sequence and returns 108 00:04:59.640 --> 00:05:02.830 the max of the sequence. 109 00:05:02.830 --> 00:05:05.160 Max is another function just like sum 110 00:05:05.160 --> 00:05:08.510 that takes in a list or a tuple or another iterable 111 00:05:08.510 --> 00:05:11.223 and returns the highest value inside it. 112 00:05:12.260 --> 00:05:14.890 Then we've got a list of students in this format 113 00:05:14.890 --> 00:05:17.260 with a name and a grades, 114 00:05:17.260 --> 00:05:18.933 we could iterate over them, 115 00:05:20.860 --> 00:05:24.080 get the name and the grades, 116 00:05:24.080 --> 00:05:26.990 and then we could bring something like the students name 117 00:05:27.940 --> 00:05:30.083 and we can ask the user 118 00:05:30.083 --> 00:05:32.540 for what they want to do with this student. 119 00:05:32.540 --> 00:05:34.680 Whether they want to get the average grade, 120 00:05:34.680 --> 00:05:37.270 the total grade, or the top grade. 121 00:05:37.270 --> 00:05:40.253 So we will ask for an operation, and we'll say input. 122 00:05:41.330 --> 00:05:46.063 Enter average, total, or top. 123 00:05:47.430 --> 00:05:50.916 And then we're going to get the result, which is 124 00:05:50.916 --> 00:05:55.916 operations- this is our dictionary that we defined up here. 125 00:05:56.570 --> 00:06:00.840 And we are going to get the operation the user entered. 126 00:06:00.840 --> 00:06:03.530 So this is a little bit confusing, but operation 127 00:06:03.530 --> 00:06:05.760 is a string that the user has given us. 128 00:06:05.760 --> 00:06:08.370 For example, the string average. 129 00:06:08.370 --> 00:06:09.490 We are then accessing the 130 00:06:09.490 --> 00:06:13.060 average key of the operations dictionary, 131 00:06:13.060 --> 00:06:14.963 which gives us this function. 132 00:06:16.150 --> 00:06:18.340 That means that we can call the function 133 00:06:18.340 --> 00:06:21.100 by using the two brackets. 134 00:06:21.100 --> 00:06:23.698 But the function takes in a sequence, 135 00:06:23.698 --> 00:06:24.531 so we must pass in the grades, 136 00:06:24.531 --> 00:06:29.531 and then we can print result. 137 00:06:30.380 --> 00:06:32.960 Let's run this so you can see exactly how it works. 138 00:06:32.960 --> 00:06:36.950 For Rolf, we can get the average, for example. 139 00:06:36.950 --> 00:06:39.480 Then that calculates 88.0. 140 00:06:39.480 --> 00:06:42.760 What's going on is that when we enter average here 141 00:06:42.760 --> 00:06:46.690 we then use this function with Rolf's grades 142 00:06:46.690 --> 00:06:49.780 which calculates the average of this. 143 00:06:49.780 --> 00:06:52.410 For Bob, though, we can use total, 144 00:06:52.410 --> 00:06:53.570 and that gives you the total 145 00:06:53.570 --> 00:06:55.430 amount of points that he scored. 146 00:06:55.430 --> 00:06:58.180 And for Jen, we can do top, and that will give you 147 00:06:58.180 --> 00:06:59.913 the maximum grade she scored. 148 00:07:01.730 --> 00:07:05.350 Interestingly, the total and the top functions, 149 00:07:05.350 --> 00:07:08.540 are a function that takes in an argument 150 00:07:08.540 --> 00:07:11.794 and then returns calling a function, 151 00:07:11.794 --> 00:07:13.350 which also takes in an argument. 152 00:07:13.350 --> 00:07:18.210 So really, we could just do this. 153 00:07:21.340 --> 00:07:25.970 Before we had lambda sec is sum of sec. 154 00:07:25.970 --> 00:07:30.970 So, we have a function, that when we call it, 155 00:07:31.550 --> 00:07:34.480 with an argument it calls the sum function 156 00:07:34.480 --> 00:07:35.443 with an argument. 157 00:07:36.610 --> 00:07:40.090 And now, we have a function that when we call it 158 00:07:40.090 --> 00:07:43.300 with an argument, it gives us the result 159 00:07:43.300 --> 00:07:45.320 of calling the sum function with an argument. 160 00:07:45.320 --> 00:07:47.530 Because that is the function we are calling. 161 00:07:47.530 --> 00:07:49.970 The result is exactly the same. 162 00:07:49.970 --> 00:07:53.130 Instead of having a intermediary function, 163 00:07:53.130 --> 00:07:55.110 that calls the sum function, 164 00:07:55.110 --> 00:07:57.370 we are just putting the sum function here, 165 00:07:57.370 --> 00:07:59.580 so that when we call it here, 166 00:07:59.580 --> 00:08:02.310 we can just pass the grades directly to it. 167 00:08:02.310 --> 00:08:04.730 For total and top, we don't need 168 00:08:04.730 --> 00:08:06.610 an intermediary lambda function, 169 00:08:06.610 --> 00:08:09.880 because it wasn't doing anything extra. 170 00:08:09.880 --> 00:08:11.950 I appreciate that this stuff is getting a little bit 171 00:08:11.950 --> 00:08:15.260 confusing now, because we are learning more about python. 172 00:08:15.260 --> 00:08:18.570 Do write this code alongside me, and ask questions 173 00:08:18.570 --> 00:08:20.270 in the course Q and A if you have any, 174 00:08:20.270 --> 00:08:22.140 and I would be more than happy to help. 175 00:08:22.140 --> 00:08:23.660 But for now, I hope you have learned something 176 00:08:23.660 --> 00:08:24.493 in this video, 177 00:08:24.493 --> 00:08:25.460 thank you for joining me, 178 00:08:25.460 --> 00:08:27.110 and I'll see you in the next one.