1
00:00:00,480 --> 00:00:03,330
In the last lesson we saw how the asterix operator

2
00:00:03,330 --> 00:00:07,320
could be used to provide any number of positional arguments to a function

3
00:00:07,680 --> 00:00:11,370
because it collected them into a tuple. In this lesson,

4
00:00:11,430 --> 00:00:14,130
we'll take a look at the double asterix operator,

5
00:00:14,430 --> 00:00:18,750
and this is going to allow us to work with an arbitrary number of keyword

6
00:00:18,750 --> 00:00:20,940
arguments. Let's see this in action.

7
00:00:21,600 --> 00:00:24,360
So let's say I create another function called calculate,

8
00:00:24,720 --> 00:00:29,160
and this time I'm going to add two asteriks. And in this case,

9
00:00:29,220 --> 00:00:34,220
I'm going to call my argument **kwargs or keyword arguments.

10
00:00:34,770 --> 00:00:39,770
What we've done now is we've added two asterisks signs in front of this parameter

11
00:00:39,900 --> 00:00:40,733
name,

12
00:00:41,160 --> 00:00:45,630
and we've now created unlimited keyword arguments.

13
00:00:46,080 --> 00:00:51,080
What this allows me to do is I could basically now call this calculate function,

14
00:00:52,380 --> 00:00:57,090
I could pass in a keyword argument, for example,

15
00:00:57,210 --> 00:01:00,210
add, and let's give it a value, maybe three,

16
00:01:00,510 --> 00:01:04,739
and then let's add another keyword argument which I'll call multiply,

17
00:01:05,069 --> 00:01:08,910
set that to equal five. And effectively

18
00:01:08,940 --> 00:01:13,140
what this has been turned into is these **kwargs,

19
00:01:13,500 --> 00:01:18,210
which is basically a dictionary. So if I print these **kwargs,

20
00:01:18,810 --> 00:01:23,040
you can see what gets printed is basically a bog-standard dictionary.

21
00:01:23,490 --> 00:01:26,790
And in fact, if we do that type check thing again, so type,

22
00:01:28,620 --> 00:01:30,900
you can see it is in fact, a dictionary.

23
00:01:31,920 --> 00:01:36,810
This dictionary basically represents each of the keyword arguments and their

24
00:01:36,810 --> 00:01:37,643
values.

25
00:01:37,950 --> 00:01:42,570
So add is now a key and three is now it's value, multiply's

26
00:01:42,570 --> 00:01:45,660
the second key and five is its value.

27
00:01:46,140 --> 00:01:50,760
What I can do here is I could do the standard way of looping through dictionary.

28
00:01:50,760 --> 00:01:55,760
So I could say for key, value in **kwargs .items,

29
00:01:57,960 --> 00:02:02,160
and then I can get access to each of the keys and their values as I loop through

30
00:02:02,160 --> 00:02:04,800
the dictionary like this.

31
00:02:04,920 --> 00:02:08,910
So add three multiplied by five. Alternatively,

32
00:02:08,970 --> 00:02:11,700
I can simply use the names of the keys.

33
00:02:12,120 --> 00:02:17,120
So I could just simply print my **kwargs and then use the square brackets and then

34
00:02:18,270 --> 00:02:22,200
provide the name of the key, so add for example.

35
00:02:22,950 --> 00:02:27,060
And that will give me the value which is three as you can see here.

36
00:02:27,930 --> 00:02:28,260
Now,

37
00:02:28,260 --> 00:02:33,260
what this allows me to do is it basically lets me look through all of the inputs

38
00:02:34,920 --> 00:02:39,060
and find the ones that I want and use them to do something.

39
00:02:39,540 --> 00:02:44,100
So for example, in this case, it's a calculate function, right?

40
00:02:44,490 --> 00:02:48,420
So we could let's say start off with a normal positional argument,

41
00:02:48,450 --> 00:02:53,370
so let's call it n and let's pass in that n at the very beginning.

42
00:02:53,670 --> 00:02:58,500
So let's say we start out with the number 2, n is now equal to 2,

43
00:02:58,900 --> 00:03:03,700
and then the **kwargs is a dictionary of the remainder arguments.

44
00:03:05,290 --> 00:03:08,020
Let's say that I wanted to do some calculations.

45
00:03:08,050 --> 00:03:13,050
I wanted to say n+= kwargs,

46
00:03:13,870 --> 00:03:18,340
and I'm going to get hold of the value under add.

47
00:03:19,030 --> 00:03:22,960
And then I'm going to say, n*= the kwargs,

48
00:03:23,380 --> 00:03:26,290
and I'm going to get hold of value of multiply.

49
00:03:26,950 --> 00:03:30,250
So now when I go ahead and print

50
00:03:30,310 --> 00:03:35,310
my n, you can see that what happens is it takes the first value 2 as equal to n,

51
00:03:39,850 --> 00:03:44,380
and then n, this 2, is going to be added to the number I wanted to add

52
00:03:44,410 --> 00:03:46,660
which is 3. So 2 + 3 is 5,

53
00:03:47,140 --> 00:03:52,140
and then it multiplied that 5 by whatever it is I had stored in multiply.

54
00:03:52,660 --> 00:03:55,120
So 5 plus 5, and we get 25.

55
00:03:55,810 --> 00:04:00,460
This gives us a more flexible way of working with these arguments.

56
00:04:00,910 --> 00:04:05,500
And it gives us a way to name the values that we're passing in to this function.

57
00:04:06,880 --> 00:04:11,110
Now, coming back to what they've done in the Tkinter module,

58
00:04:11,650 --> 00:04:16,649
basically this Tkinter module is actually ported from another technology called

59
00:04:17,560 --> 00:04:18,392
TK.

60
00:04:18,940 --> 00:04:23,320
And TK actually has a very different syntax from Python.

61
00:04:23,950 --> 00:04:28,900
In order for it to work, they basically took all of the Tk commands,

62
00:04:28,930 --> 00:04:32,470
like creating a label or packing some sort of item,

63
00:04:32,920 --> 00:04:37,920
and took all of the options and turn them into these **kwargs or optional keyword

64
00:04:40,180 --> 00:04:41,013
arguments.

65
00:04:41,380 --> 00:04:46,000
And that is why when we create a new label from the Tkinter module

66
00:04:46,030 --> 00:04:48,310
or when we call the pack method,

67
00:04:48,520 --> 00:04:53,290
you can see that it doesn't actually come up with any properties that we can

68
00:04:53,290 --> 00:04:57,850
modify other than this **kw,

69
00:04:58,120 --> 00:05:00,580
which is the same as our **kwargs.

70
00:05:01,390 --> 00:05:04,390
So we could actually create a class like that as well,

71
00:05:04,660 --> 00:05:07,180
because this is done at initialization, right?

72
00:05:07,180 --> 00:05:09,640
This is done when they're creating that label class.

73
00:05:10,420 --> 00:05:13,810
Let's say that we create a class like this which I'll car,

74
00:05:14,410 --> 00:05:16,270
and in the init,

75
00:05:16,780 --> 00:05:21,430
what I'll include in addition to self is **

76
00:05:21,670 --> 00:05:25,030
kw, or **kwargs, or however you want to spell it.

77
00:05:25,840 --> 00:05:30,840
This kw are going to be all of the optional arguments that I'll pass in

78
00:05:31,270 --> 00:05:35,950
when I'm initializing a new object from this class. I can say,

79
00:05:35,950 --> 00:05:38,770
for example, self.

80
00:05:38,830 --> 00:05:42,370
make of the car equals kw.

81
00:05:43,270 --> 00:05:47,230
And then from kw, I'm going to get the make.

82
00:05:48,010 --> 00:05:49,810
And then I'm going to have self.model

83
00:05:49,810 --> 00:05:53,980
which is going to be equal to kw and then model. And of course,

84
00:05:53,980 --> 00:05:57,830
all of the spelling matters so make sure you don't make any typos.

85
00:05:58,280 --> 00:06:00,260
And then I decide to create my car

86
00:06:00,290 --> 00:06:04,490
which is going to be the object created from this class. Now notice how

87
00:06:04,490 --> 00:06:06,440
when I open up the parentheses here,

88
00:06:06,740 --> 00:06:10,850
you don't actually see any of the properties like make and model show up

89
00:06:10,880 --> 00:06:14,480
when I'm initializing. All you see is **

90
00:06:14,510 --> 00:06:18,380
kw, just in the same way as you see it here,

91
00:06:19,850 --> 00:06:21,680
**kw.

92
00:06:22,640 --> 00:06:26,750
And that of course refers to our optional keyword arguments.

93
00:06:27,320 --> 00:06:31,610
Let's add some values. Let's set the make to a Nissan,

94
00:06:32,150 --> 00: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

95
00:06:40,820 --> 00:06:44,930
just as I would any other object. I can say my_car.model.

96
00:06:45,290 --> 00:06:49,580
And when I hit run, you can see I've got GT-R being printed here.

97
00:06:50,690 --> 00:06:54,740
And if I decided to print make, you can see

98
00:06:54,740 --> 00:06:55,970
it gets hold off the make.

99
00:06:56,480 --> 00:07:00,830
Now, what if I didn't actually specify one of these arguments.

100
00:07:01,430 --> 00:07:05,390
Notice how it's now actually going to crash.

101
00:07:06,020 --> 00:07:08,570
It tells me that keyError model.

102
00:07:08,750 --> 00:07:13,750
So when it was initializing this car object, it fell on this line. And it

103
00:07:15,800 --> 00:07:20,800
couldn't get hold of a value called model from this kw argument dictionary.

104
00:07:23,060 --> 00:07:24,650
In fact, with dictionaries,

105
00:07:25,040 --> 00:07:28,370
we can get hold of the values through the square bracket method,

106
00:07:28,640 --> 00:07:33,640
but we can also use a function called get. And we use get in a very similar way

107
00:07:35,030 --> 00:07:37,220
to the way that we use the square brackets.

108
00:07:37,250 --> 00:07:41,540
We just pass in the name of the key and we want to get hold of the value.

109
00:07:42,140 --> 00:07:47,140
But the benefit of get is that if this key doesn't exist in the dictionary,

110
00:07:50,510 --> 00:07:54,650
then it will just return none and it won't give us an error.

111
00:07:55,820 --> 00:08:00,080
So now if I run this code again, you can see that everything works,

112
00:08:00,320 --> 00:08:03,890
but my car.model is now equal to none.

113
00:08:04,580 --> 00:08:09,580
So this is how we can actually create a class with lots of optional keyword

114
00:08:10,340 --> 00:08:11,173
arguments.

115
00:08:12,110 --> 00:08:17,110
So we could have a self.color or self.seats.

116
00:08:21,050 --> 00:08:25,580
And depending on what it is we want to initialize this car object to,

117
00:08:25,910 --> 00:08:30,910
then we can simply go ahead and add whatever it is we want to set as the make

118
00:08:31,820 --> 00:08:35,750
and the model or the color and the seats. And in the same way

119
00:08:35,780 --> 00:08:38,059
that way using this label class,

120
00:08:38,390 --> 00:08:41,150
we can set the text or we can set the font.

121
00:08:41,270 --> 00:08:46,270
We can set all of the options or we can leave them as the default values. That

122
00:08:48,230 --> 00:08:52,610
should help you understand how this code works a little bit better.

123
00:08:53,180 --> 00:08:56,580
And the reason why it works like this is, as I say,

124
00:08:56,580 --> 00:09:01,580
mostly because this module was converted from another language and this just

125
00:09:01,950 --> 00:09:06,950
happened to be the most efficient way for them to do this. Now with other more

126
00:09:07,380 --> 00:09:11,280
Pythonic modules or things that have been created in Python

127
00:09:11,610 --> 00:09:16,260
like the turtle module, then you'll see more bog-standard kind of code

128
00:09:16,320 --> 00:09:19,740
like what we've been working with. So when we initialize a new turtle,

129
00:09:19,950 --> 00:09:22,530
you can see that it has a default shape,

130
00:09:22,620 --> 00:09:25,230
it has a visible boolean,

131
00:09:25,290 --> 00:09:29,190
and we can set all of those properties that we can see in this prompt.

132
00:09:30,510 --> 00:09:31,860
Now in the next lesson,

133
00:09:31,890 --> 00:09:36,210
I want to dive deeper into the TKinter documentation

134
00:09:36,570 --> 00:09:40,230
and I want to show you how we can create other components, not just the label,

135
00:09:40,470 --> 00:09:42,990
but things like buttons and text inputs

136
00:09:43,280 --> 00:09:46,790
and a whole range of things that will bring our GUI program to life.

137
00:09:47,210 --> 00:09:50,120
So for all of that and more, I'll see you in the next lesson.

