WEBVTT

0
00:00.480 --> 00:03.330
In the last lesson we saw how the asterix operator

1
00:03.330 --> 00:07.320
could be used to provide any number of positional arguments to a function

2
00:07.680 --> 00:11.370
because it collected them into a tuple. In this lesson,

3
00:11.430 --> 00:14.130
we'll take a look at the double asterix operator,

4
00:14.430 --> 00:18.750
and this is going to allow us to work with an arbitrary number of keyword

5
00:18.750 --> 00:20.940
arguments. Let's see this in action.

6
00:21.600 --> 00:24.360
So let's say I create another function called calculate,

7
00:24.720 --> 00:29.160
and this time I'm going to add two asteriks. And in this case,

8
00:29.220 --> 00:34.220
I'm going to call my argument **kwargs or keyword arguments.

9
00:34.770 --> 00:39.770
What we've done now is we've added two asterisks signs in front of this parameter

10
00:39.900 --> 00:40.733
name,

11
00:41.160 --> 00:45.630
and we've now created unlimited keyword arguments.

12
00:46.080 --> 00:51.080
What this allows me to do is I could basically now call this calculate function,

13
00:52.380 --> 00:57.090
I could pass in a keyword argument, for example,

14
00:57.210 --> 01:00.210
add, and let's give it a value, maybe three,

15
01:00.510 --> 01:04.740
and then let's add another keyword argument which I'll call multiply,

16
01:05.070 --> 01:08.910
set that to equal five. And effectively

17
01:08.940 --> 01:13.140
what this has been turned into is these **kwargs,

18
01:13.500 --> 01:18.210
which is basically a dictionary. So if I print these **kwargs,

19
01:18.810 --> 01:23.040
you can see what gets printed is basically a bog-standard dictionary.

20
01:23.490 --> 01:26.790
And in fact, if we do that type check thing again, so type,

21
01:28.620 --> 01:30.900
you can see it is in fact, a dictionary.

22
01:31.920 --> 01:36.810
This dictionary basically represents each of the keyword arguments and their

23
01:36.810 --> 01:37.643
values.

24
01:37.950 --> 01:42.570
So add is now a key and three is now it's value, multiply's

25
01:42.570 --> 01:45.660
the second key and five is its value.

26
01:46.140 --> 01:50.760
What I can do here is I could do the standard way of looping through dictionary.

27
01:50.760 --> 01:55.760
So I could say for key, value in **kwargs .items,

28
01:57.960 --> 02:02.160
and then I can get access to each of the keys and their values as I loop through

29
02:02.160 --> 02:04.800
the dictionary like this.

30
02:04.920 --> 02:08.910
So add three multiplied by five. Alternatively,

31
02:08.970 --> 02:11.700
I can simply use the names of the keys.

32
02:12.120 --> 02:17.120
So I could just simply print my **kwargs and then use the square brackets and then

33
02:18.270 --> 02:22.200
provide the name of the key, so add for example.

34
02:22.950 --> 02:27.060
And that will give me the value which is three as you can see here.

35
02:27.930 --> 02:28.260
Now,

36
02:28.260 --> 02:33.260
what this allows me to do is it basically lets me look through all of the inputs

37
02:34.920 --> 02:39.060
and find the ones that I want and use them to do something.

38
02:39.540 --> 02:44.100
So for example, in this case, it's a calculate function, right?

39
02:44.490 --> 02:48.420
So we could let's say start off with a normal positional argument,

40
02:48.450 --> 02:53.370
so let's call it n and let's pass in that n at the very beginning.

41
02:53.670 --> 02:58.500
So let's say we start out with the number 2, n is now equal to 2,

42
02:58.900 --> 03:03.700
and then the **kwargs is a dictionary of the remainder arguments.

43
03:05.290 --> 03:08.020
Let's say that I wanted to do some calculations.

44
03:08.050 --> 03:13.050
I wanted to say n+= kwargs,

45
03:13.870 --> 03:18.340
and I'm going to get hold of the value under add.

46
03:19.030 --> 03:22.960
And then I'm going to say, n*= the kwargs,

47
03:23.380 --> 03:26.290
and I'm going to get hold of value of multiply.

48
03:26.950 --> 03:30.250
So now when I go ahead and print

49
03:30.310 --> 03:35.310
my n, you can see that what happens is it takes the first value 2 as equal to n,

50
03:39.850 --> 03:44.380
and then n, this 2, is going to be added to the number I wanted to add

51
03:44.410 --> 03:46.660
which is 3. So 2 + 3 is 5,

52
03:47.140 --> 03:52.140
and then it multiplied that 5 by whatever it is I had stored in multiply.

53
03:52.660 --> 03:55.120
So 5 plus 5, and we get 25.

54
03:55.810 --> 04:00.460
This gives us a more flexible way of working with these arguments.

55
04:00.910 --> 04:05.500
And it gives us a way to name the values that we're passing in to this function.

56
04:06.880 --> 04:11.110
Now, coming back to what they've done in the Tkinter module,

57
04:11.650 --> 04:16.650
basically this Tkinter module is actually ported from another technology called

58
04:17.560 --> 04:18.393
TK.

59
04:18.940 --> 04:23.320
And TK actually has a very different syntax from Python.

60
04:23.950 --> 04:28.900
In order for it to work, they basically took all of the Tk commands,

61
04:28.930 --> 04:32.470
like creating a label or packing some sort of item,

62
04:32.920 --> 04:37.920
and took all of the options and turn them into these **kwargs or optional keyword

63
04:40.180 --> 04:41.013
arguments.

64
04:41.380 --> 04:46.000
And that is why when we create a new label from the Tkinter module

65
04:46.030 --> 04:48.310
or when we call the pack method,

66
04:48.520 --> 04:53.290
you can see that it doesn't actually come up with any properties that we can

67
04:53.290 --> 04:57.850
modify other than this **kw,

68
04:58.120 --> 05:00.580
which is the same as our **kwargs.

69
05:01.390 --> 05:04.390
So we could actually create a class like that as well,

70
05:04.660 --> 05:07.180
because this is done at initialization, right?

71
05:07.180 --> 05:09.640
This is done when they're creating that label class.

72
05:10.420 --> 05:13.810
Let's say that we create a class like this which I'll car,

73
05:14.410 --> 05:16.270
and in the init,

74
05:16.780 --> 05:21.430
what I'll include in addition to self is **

75
05:21.670 --> 05:25.030
kw, or **kwargs, or however you want to spell it.

76
05:25.840 --> 05:30.840
This kw are going to be all of the optional arguments that I'll pass in

77
05:31.270 --> 05:35.950
when I'm initializing a new object from this class. I can say,

78
05:35.950 --> 05:38.770
for example, self.

79
05:38.830 --> 05:42.370
make of the car equals kw.

80
05:43.270 --> 05:47.230
And then from kw, I'm going to get the make.

81
05:48.010 --> 05:49.810
And then I'm going to have self.model

82
05:49.810 --> 05:53.980
which is going to be equal to kw and then model. And of course,

83
05:53.980 --> 05:57.830
all of the spelling matters so make sure you don't make any typos.

84
05:58.280 --> 06:00.260
And then I decide to create my car

85
06:00.290 --> 06:04.490
which is going to be the object created from this class. Now notice how

86
06:04.490 --> 06:06.440
when I open up the parentheses here,

87
06:06.740 --> 06:10.850
you don't actually see any of the properties like make and model show up

88
06:10.880 --> 06:14.480
when I'm initializing. All you see is **

89
06:14.510 --> 06:18.380
kw, just in the same way as you see it here,

90
06:19.850 --> 06:21.680
**kw.

91
06:22.640 --> 06:26.750
And that of course refers to our optional keyword arguments.

92
06:27.320 --> 06:31.610
Let's add some values. Let's set the make to a Nissan,

93
06:32.150 --> 06:37.150
and lets set the model to a-- let's set it to a GT-R. And now I can use my object

94
06:40.820 --> 06:44.930
just as I would any other object. I can say my_car.model.

95
06:45.290 --> 06:49.580
And when I hit run, you can see I've got GT-R being printed here.

96
06:50.690 --> 06:54.740
And if I decided to print make, you can see

97
06:54.740 --> 06:55.970
it gets hold off the make.

98
06:56.480 --> 07:00.830
Now, what if I didn't actually specify one of these arguments.

99
07:01.430 --> 07:05.390
Notice how it's now actually going to crash.

100
07:06.020 --> 07:08.570
It tells me that keyError model.

101
07:08.750 --> 07:13.750
So when it was initializing this car object, it fell on this line. And it

102
07:15.800 --> 07:20.800
couldn't get hold of a value called model from this kw argument dictionary.

103
07:23.060 --> 07:24.650
In fact, with dictionaries,

104
07:25.040 --> 07:28.370
we can get hold of the values through the square bracket method,

105
07:28.640 --> 07:33.640
but we can also use a function called get. And we use get in a very similar way

106
07:35.030 --> 07:37.220
to the way that we use the square brackets.

107
07:37.250 --> 07:41.540
We just pass in the name of the key and we want to get hold of the value.

108
07:42.140 --> 07:47.140
But the benefit of get is that if this key doesn't exist in the dictionary,

109
07:50.510 --> 07:54.650
then it will just return none and it won't give us an error.

110
07:55.820 --> 08:00.080
So now if I run this code again, you can see that everything works,

111
08:00.320 --> 08:03.890
but my car.model is now equal to none.

112
08:04.580 --> 08:09.580
So this is how we can actually create a class with lots of optional keyword

113
08:10.340 --> 08:11.173
arguments.

114
08:12.110 --> 08:17.110
So we could have a self.color or self.seats.

115
08:21.050 --> 08:25.580
And depending on what it is we want to initialize this car object to,

116
08:25.910 --> 08:30.910
then we can simply go ahead and add whatever it is we want to set as the make

117
08:31.820 --> 08:35.750
and the model or the color and the seats. And in the same way

118
08:35.780 --> 08:38.060
that way using this label class,

119
08:38.390 --> 08:41.150
we can set the text or we can set the font.

120
08:41.270 --> 08:46.270
We can set all of the options or we can leave them as the default values. That

121
08:48.230 --> 08:52.610
should help you understand how this code works a little bit better.

122
08:53.180 --> 08:56.580
And the reason why it works like this is, as I say,

123
08:56.580 --> 09:01.580
mostly because this module was converted from another language and this just

124
09:01.950 --> 09:06.950
happened to be the most efficient way for them to do this. Now with other more

125
09:07.380 --> 09:11.280
Pythonic modules or things that have been created in Python

126
09:11.610 --> 09:16.260
like the turtle module, then you'll see more bog-standard kind of code

127
09:16.320 --> 09:19.740
like what we've been working with. So when we initialize a new turtle,

128
09:19.950 --> 09:22.530
you can see that it has a default shape,

129
09:22.620 --> 09:25.230
it has a visible boolean,

130
09:25.290 --> 09:29.190
and we can set all of those properties that we can see in this prompt.

131
09:30.510 --> 09:31.860
Now in the next lesson,

132
09:31.890 --> 09:36.210
I want to dive deeper into the TKinter documentation

133
09:36.570 --> 09:40.230
and I want to show you how we can create other components, not just the label,

134
09:40.470 --> 09:42.990
but things like buttons and text inputs

135
09:43.280 --> 09:46.790
and a whole range of things that will bring our GUI program to life.

136
09:47.210 --> 09:50.120
So for all of that and more, I'll see you in the next lesson.