WEBVTT

1
00:00:00.250 --> 00:00:01.610
<v Jose>Hi guys and welcome back.</v>

2
00:00:01.610 --> 00:00:03.280
In this video, we're going to talk about how

3
00:00:03.280 --> 00:00:06.070
to add type hinting to our application.

4
00:00:06.070 --> 00:00:07.610
Type hinting is going to be really useful

5
00:00:07.610 --> 00:00:10.510
because it allows to avoid some bugs.

6
00:00:10.510 --> 00:00:12.340
And if you don't know what type hinting is,

7
00:00:12.340 --> 00:00:14.590
we've got a full section dedicated to that

8
00:00:14.590 --> 00:00:16.080
in our complete Python course.

9
00:00:16.080 --> 00:00:17.370
If you're not in that course,

10
00:00:17.370 --> 00:00:18.396
we're gonna leave a couple of links

11
00:00:18.396 --> 00:00:20.560
in the resources section of this lecture

12
00:00:20.560 --> 00:00:21.900
for you to check out instead.

13
00:00:21.900 --> 00:00:22.900
But it's pretty straight forward,

14
00:00:22.900 --> 00:00:23.993
so let's go to it.

15
00:00:25.310 --> 00:00:27.152
Here we've got our application

16
00:00:27.152 --> 00:00:28.140
and what we're gonna do

17
00:00:28.140 --> 00:00:32.230
is we're gonna begin by type hinting our functions here.

18
00:00:32.230 --> 00:00:34.660
So, we're going to go ahead

19
00:00:34.660 --> 00:00:36.643
and add the...

20
00:00:36.643 --> 00:00:37.520
imports.

21
00:00:37.520 --> 00:00:38.730
So from the typing module

22
00:00:38.730 --> 00:00:40.543
we're gonna import list and tuple.

23
00:00:41.980 --> 00:00:44.760
And then we're going to go to down here

24
00:00:44.760 --> 00:00:47.720
where we have get_Poll_details for example.

25
00:00:47.720 --> 00:00:51.540
And every parameter is going to get a type hint.

26
00:00:51.540 --> 00:00:54.110
What that's gonna do is later on when we call this function,

27
00:00:54.110 --> 00:00:57.276
PyCharm is going to know what sort of value

28
00:00:57.276 --> 00:00:59.766
this parameter should be.

29
00:00:59.766 --> 00:01:02.720
So what we're gonna do is Poll_id should be an integer,

30
00:01:02.720 --> 00:01:06.036
so we simply type : int before the bracket

31
00:01:06.036 --> 00:01:10.846
and that annotates the Poll_id and tells the PyCharm linter

32
00:01:10.846 --> 00:01:14.220
or type checker that it should be an integer.

33
00:01:14.220 --> 00:01:15.990
And if we try to call this function with something

34
00:01:15.990 --> 00:01:17.160
that's not an integer,

35
00:01:17.160 --> 00:01:19.006
then PyCharm is gonna give us a warning.

36
00:01:19.006 --> 00:01:21.374
Note that it will be a warning,

37
00:01:21.374 --> 00:01:24.160
and it's never going to be an error.

38
00:01:24.160 --> 00:01:26.260
Type hinting is just a hint,

39
00:01:26.260 --> 00:01:28.265
so that's something to remember.

40
00:01:28.265 --> 00:01:30.485
So the other things that are gonna be integers,

41
00:01:30.485 --> 00:01:32.330
we're gonna annotate as well,

42
00:01:32.330 --> 00:01:35.945
such as this Poll_id down here, Option_id down here.

43
00:01:35.945 --> 00:01:39.350
And for these, there are, for example, strings:

44
00:01:39.350 --> 00:01:43.108
the title and owner, we're going to do str down there.

45
00:01:43.108 --> 00:01:45.370
Options we're going to leave for just now

46
00:01:45.370 --> 00:01:46.335
and we're going to come back to it.

47
00:01:46.335 --> 00:01:48.380
Username is going to be a string

48
00:01:48.380 --> 00:01:51.950
and Option_id is going to be an integer as well.

49
00:01:51.950 --> 00:01:55.950
The Options list here is going to be a list of strings.

50
00:01:55.950 --> 00:01:59.050
So how we annotate that is we use the typing module

51
00:01:59.050 --> 00:02:03.450
and we do list of strings inside square brackets.

52
00:02:03.450 --> 00:02:06.400
That tells the Python type hinting system

53
00:02:06.400 --> 00:02:08.289
that this is going to be a list

54
00:02:08.289 --> 00:02:12.150
and it is going to be a list of strings.

55
00:02:12.150 --> 00:02:14.870
Note that I'm using Python 3.8 at the moment

56
00:02:14.870 --> 00:02:17.490
but, as of Python 3.9, you no longer need

57
00:02:17.490 --> 00:02:19.160
to import the typing module.

58
00:02:19.160 --> 00:02:22.200
You can simply use the built-in list for this.

59
00:02:22.200 --> 00:02:25.340
But, because I'm using Python 3.8, I can't do that yet.

60
00:02:25.340 --> 00:02:28.320
So you do have to import and use the L there

61
00:02:28.320 --> 00:02:31.160
in order to use the list type hinting mechanism

62
00:02:31.160 --> 00:02:33.960
with Python 3.8 and above.

63
00:02:33.960 --> 00:02:35.560
So now that we have got our

64
00:02:35.560 --> 00:02:38.980
parameter type hints for everything, we can also type hint

65
00:02:38.980 --> 00:02:41.913
the return type of these functions, and that is where

66
00:02:41.913 --> 00:02:44.080
it's going to get a bit more interesting.

67
00:02:44.080 --> 00:02:46.110
What I'm going to do is I'm going to

68
00:02:46.110 --> 00:02:48.320
define my own custom types.

69
00:02:48.320 --> 00:02:49.750
And the reason I'm going to do that is because

70
00:02:49.750 --> 00:02:52.030
these are going to reappear everywhere

71
00:02:52.030 --> 00:02:54.870
and I don't want to be duplicating a lot of code.

72
00:02:54.870 --> 00:02:58.120
So I'm going to do Poll is equal to a tuple

73
00:02:58.120 --> 00:03:00.960
of int, string, and string.

74
00:03:00.960 --> 00:03:02.730
And the reason I'm doing this is because

75
00:03:02.730 --> 00:03:05.707
whenever one of my functions is returning a Poll,

76
00:03:05.707 --> 00:03:08.720
that I'm going to signal with the Poll type

77
00:03:08.720 --> 00:03:13.290
and that represents a tuple with three values inside it.

78
00:03:13.290 --> 00:03:14.950
The first one is going to be an integer,

79
00:03:14.950 --> 00:03:16.330
the second one is going to be a string,

80
00:03:16.330 --> 00:03:18.310
and the third one is going to be a string as well.

81
00:03:18.310 --> 00:03:20.410
The reason why I'm doing this is because

82
00:03:20.410 --> 00:03:22.173
the Polls that are coming from my table

83
00:03:22.173 --> 00:03:25.940
are integer, string, and string.

84
00:03:25.940 --> 00:03:27.860
I'm going to do the same for votes.

85
00:03:27.860 --> 00:03:30.510
And the reason I'm not doing it for Option is because

86
00:03:30.510 --> 00:03:32.950
we actually never return Options on their own

87
00:03:32.950 --> 00:03:36.020
right now so we don't need it.

88
00:03:36.020 --> 00:03:39.890
However, we do return Poll with Option joined together.

89
00:03:39.890 --> 00:03:42.560
So I'm going to create a PollWithOption type

90
00:03:42.560 --> 00:03:45.590
that is a tuple that has the Poll: int, str, str;

91
00:03:45.590 --> 00:03:49.130
and that it also has the Option: int, str, int.

92
00:03:49.130 --> 00:03:52.460
So this tuple here represents the joined tables:

93
00:03:52.460 --> 00:03:54.450
the Poll and the Option.

94
00:03:54.450 --> 00:03:55.710
What we do return, though,

95
00:03:55.710 --> 00:03:58.180
are Polls with Options joined together.

96
00:03:58.180 --> 00:04:01.020
So I'm going to create the PollWithOption type here

97
00:04:01.020 --> 00:04:04.940
that is a tuple of Polls: int, str, and str;

98
00:04:04.940 --> 00:04:08.860
joined together with the Option which is int, str, and int.

99
00:04:08.860 --> 00:04:11.760
Note that the Polls have id, title, and owner_username,

100
00:04:11.760 --> 00:04:13.100
so that's these three,

101
00:04:13.100 --> 00:04:15.684
and Options have the id, Option_text, and Poll_id,

102
00:04:15.684 --> 00:04:18.290
so that's these three.

103
00:04:18.290 --> 00:04:20.040
Then we're also going to get PollResults

104
00:04:20.040 --> 00:04:22.140
which is another tuple that we're going to use

105
00:04:22.140 --> 00:04:25.000
and which is an int, str, int,

106
00:04:25.000 --> 00:04:28.080
and a float for the vote percentage.

107
00:04:28.080 --> 00:04:29.960
That's down here.

108
00:04:29.960 --> 00:04:31.860
Now, let's go ahead and use these types

109
00:04:31.860 --> 00:04:35.013
to type hint the return values of our functions.

110
00:04:35.013 --> 00:04:37.975
What we can do, for example here with get_Polls,

111
00:04:37.975 --> 00:04:42.380
is we can do this arrow with a dash and a greater than sign

112
00:04:42.380 --> 00:04:45.170
and then List of Poll, and that is going to

113
00:04:45.170 --> 00:04:47.980
give us the list of tuples that we defined above.

114
00:04:47.980 --> 00:04:49.940
And that means that whenever we get

115
00:04:49.940 --> 00:04:53.517
the values from this function, the caller of the function

116
00:04:53.517 --> 00:04:56.820
will actually be able to see that this is

117
00:04:56.820 --> 00:04:59.123
a list of tuples that are being returned.

118
00:05:00.070 --> 00:05:03.040
PyCharm can make use of that by offering you hints later on,

119
00:05:03.040 --> 00:05:04.710
such as the sort of things that you can do

120
00:05:04.710 --> 00:05:05.890
with a returned value.

121
00:05:05.890 --> 00:05:08.580
For get_latest_Poll, we're going to do

122
00:05:08.580 --> 00:05:10.813
List of PollWithOption.

123
00:05:11.960 --> 00:05:14.990
For Poll details we're going to do the same, actually:

124
00:05:14.990 --> 00:05:16.453
List of PollWithOptions.

125
00:05:17.720 --> 00:05:19.940
For the get_Poll_and_vote_results, we're going to do

126
00:05:19.940 --> 00:05:21.670
a List...

127
00:05:21.670 --> 00:05:23.300
of PollResults.

128
00:05:23.300 --> 00:05:24.640
Note that some of these are lists

129
00:05:24.640 --> 00:05:27.280
even though they only pertain to one Poll,

130
00:05:27.280 --> 00:05:30.823
because the database is returning multiple rows.

131
00:05:32.400 --> 00:05:34.640
This one is simply going to be a Vote

132
00:05:34.640 --> 00:05:38.300
because it gets one random Vote from the database.

133
00:05:38.300 --> 00:05:39.550
And that's about it.

134
00:05:39.550 --> 00:05:42.010
These don't return anything so we can just leave them.

135
00:05:42.010 --> 00:05:44.510
Alternatively, you can always do None,

136
00:05:44.510 --> 00:05:45.530
but it's not necessary.

137
00:05:45.530 --> 00:05:46.870
That's implying that it's just going to add

138
00:05:46.870 --> 00:05:48.313
a bit of craft to your code.

139
00:05:49.560 --> 00:05:52.640
In app.py, there's actually not much typing to do,

140
00:05:52.640 --> 00:05:55.030
or type hinting, because what we've got here

141
00:05:55.030 --> 00:05:57.780
is just this function that actually

142
00:05:57.780 --> 00:05:59.820
accepts anything or returns anything.

143
00:05:59.820 --> 00:06:02.550
And so all we have to do here is go ahead and say

144
00:06:02.550 --> 00:06:04.803
List of database.PollWithOption.

145
00:06:06.200 --> 00:06:08.360
I'm using this here to refer to

146
00:06:08.360 --> 00:06:09.676
the type defined in the database,

147
00:06:09.676 --> 00:06:11.610
because it's just defined in one place.

148
00:06:11.610 --> 00:06:15.170
So I'm not bothered enough to move my types

149
00:06:15.170 --> 00:06:16.400
into a separate file.

150
00:06:16.400 --> 00:06:18.170
You could do that if you are using them

151
00:06:18.170 --> 00:06:20.320
from many different places, but right now

152
00:06:20.320 --> 00:06:21.660
we don't have to do that.

153
00:06:21.660 --> 00:06:23.240
We do have to import this, though.

154
00:06:23.240 --> 00:06:26.700
So I'm going to just click over it and then

155
00:06:26.700 --> 00:06:30.440
find this wee icon, import this name, type in .List,

156
00:06:30.440 --> 00:06:33.010
and that's going to essentially just paste that

157
00:06:33.010 --> 00:06:36.510
up there for me or you could type it yourself, of course.

158
00:06:36.510 --> 00:06:38.010
That's everything for type hinting.

159
00:06:38.010 --> 00:06:39.910
Now what that's going to do is, for example,

160
00:06:39.910 --> 00:06:43.373
if we go down here, and this is going to know that

161
00:06:43.373 --> 00:06:46.250
Poll_with_Options is a tuple.

162
00:06:46.250 --> 00:06:49.367
So if you try to do something like .append(),

163
00:06:50.270 --> 00:06:52.220
then it's going to allow it that.

164
00:06:52.220 --> 00:06:54.010
But if you try to run something here

165
00:06:54.010 --> 00:06:57.070
that doesn't exist in a list, then it's not

166
00:06:57.070 --> 00:06:59.470
going to appear as a suggestion in PyCharm

167
00:06:59.470 --> 00:07:01.067
and it will underline and say,

168
00:07:01.067 --> 00:07:04.290
"List object doesn't have this method," for example.

169
00:07:04.290 --> 00:07:07.090
So it's all pretty good with that.

170
00:07:07.090 --> 00:07:08.440
It's really helpful, especially when

171
00:07:08.440 --> 00:07:11.260
you're doing larger applications.

172
00:07:11.260 --> 00:07:12.380
That's everything for this video.

173
00:07:12.380 --> 00:07:13.630
Thank you guys for watching.

174
00:07:13.630 --> 00:07:15.363
I'll see you in the next one.

