WEBVTT

1
00:00:00.500 --> 00:00:01.810
<v ->Hi guys and welcome back.</v>

2
00:00:01.810 --> 00:00:04.410
In this video, we're going to start looking at the code

3
00:00:04.410 --> 00:00:06.800
that we're giving you for this project.

4
00:00:06.800 --> 00:00:09.590
Because we've already built a few of these database

5
00:00:09.590 --> 00:00:12.240
using command line apps, we figured it would be best

6
00:00:12.240 --> 00:00:13.800
to give you some code so that we don't have

7
00:00:13.800 --> 00:00:15.650
to write everything from scratch.

8
00:00:15.650 --> 00:00:17.160
Everything we're going to give you though,

9
00:00:17.160 --> 00:00:18.950
we already know how to write.

10
00:00:18.950 --> 00:00:21.490
We've already covered this in previous sections,

11
00:00:21.490 --> 00:00:23.090
so there's nothing new here.

12
00:00:23.090 --> 00:00:25.510
Everything that's new, we haven't written yet,

13
00:00:25.510 --> 00:00:27.900
we're gonna write that over the next few videos.

14
00:00:27.900 --> 00:00:29.263
So, let's get started.

15
00:00:30.480 --> 00:00:33.250
Here I've opened the poll project in PyCharm,

16
00:00:33.250 --> 00:00:35.330
you can download all of this starter code

17
00:00:35.330 --> 00:00:37.840
with the resources section of this lecture

18
00:00:37.840 --> 00:00:40.180
and we have a few files.

19
00:00:40.180 --> 00:00:43.210
First of all, something new, the requirements.txd

20
00:00:43.210 --> 00:00:45.330
just contains the libraries that you need

21
00:00:45.330 --> 00:00:47.760
in order to run this project.

22
00:00:47.760 --> 00:00:50.240
When you open up the requirements.txd,

23
00:00:50.240 --> 00:00:51.330
you can see the libraries you need,

24
00:00:51.330 --> 00:00:53.150
you can just go ahead and instal them

25
00:00:53.150 --> 00:00:55.610
and these are the versions of those libraries.

26
00:00:55.610 --> 00:00:58.220
Notice the two equal signs in here is just the syntax used

27
00:00:58.220 --> 00:01:00.760
in requirements.txt files to signal

28
00:01:00.760 --> 00:01:02.690
what version of the library we're using.

29
00:01:02.690 --> 00:01:07.095
We've also got a .env file with a new instance URL

30
00:01:07.095 --> 00:01:10.120
and that's just something I've just created in ElephantSQL.

31
00:01:10.120 --> 00:01:12.650
You can create one and put it in there as well

32
00:01:12.650 --> 00:01:16.053
and .env.example with a database you arrive in.

33
00:01:16.922 --> 00:01:19.280
Then, we get to the meat of it.

34
00:01:19.280 --> 00:01:22.510
We've got app.py and database.py.

35
00:01:22.510 --> 00:01:24.850
Let's first talk about database.py.

36
00:01:24.850 --> 00:01:27.800
We've got three tables in this project:

37
00:01:27.800 --> 00:01:30.786
polls, options, and votes.

38
00:01:30.786 --> 00:01:33.330
I'm just gonna close the left-hand side

39
00:01:33.330 --> 00:01:36.190
so that we get a better view of this code.

40
00:01:36.190 --> 00:01:39.240
In the polls table, we have three columns.

41
00:01:39.240 --> 00:01:42.540
The id, which is a serial primary key,

42
00:01:42.540 --> 00:01:45.310
the title, which is text, and the owner,

43
00:01:45.310 --> 00:01:47.770
or the user that created this poll.

44
00:01:47.770 --> 00:01:49.970
Know that this owner is not a foreign key

45
00:01:49.970 --> 00:01:53.380
to some user's table, it's just a string there

46
00:01:53.380 --> 00:01:56.320
for us to identify who created the poll.

47
00:01:56.320 --> 00:01:58.710
It's not unique or anything like that.

48
00:01:58.710 --> 00:02:01.240
The options table has again three columns:

49
00:02:01.240 --> 00:02:04.420
the id, which is another primary key, serial as well,

50
00:02:04.420 --> 00:02:06.760
the option text or what people are going

51
00:02:06.760 --> 00:02:09.930
to be voting for, and the poll id.

52
00:02:09.930 --> 00:02:13.430
This is a foreign key onto the polls table.

53
00:02:13.430 --> 00:02:16.570
So, these two are related through that.

54
00:02:16.570 --> 00:02:19.470
Finally, we've got the votes table, which has

55
00:02:19.470 --> 00:02:21.940
the user name of the person who voted,

56
00:02:21.940 --> 00:02:24.950
as well as the option that they voted for.

57
00:02:24.950 --> 00:02:28.620
We don't need the poll id here because options have

58
00:02:28.620 --> 00:02:31.060
a unique id and they are related to polls,

59
00:02:31.060 --> 00:02:34.970
so we can find out the poll by going through options.

60
00:02:34.970 --> 00:02:37.520
The FOREIGN_KEY here is option_id and it references

61
00:02:37.520 --> 00:02:39.573
the options table id column.

62
00:02:40.620 --> 00:02:43.050
We've got a couple of queries in here to select all

63
00:02:43.050 --> 00:02:47.270
the polls and to select poll with options by using a join.

64
00:02:47.270 --> 00:02:49.980
That just gives us the poll information as well as each

65
00:02:49.980 --> 00:02:53.820
of the options in the table, given a poll id.

66
00:02:53.820 --> 00:02:58.040
And to insert a new option and to insert a new vote.

67
00:02:58.040 --> 00:02:59.960
So we've got a bunch of things missing here,

68
00:02:59.960 --> 00:03:02.040
like to insert polls and stuff like that,

69
00:03:02.040 --> 00:03:04.680
but we're gonna be adding those as we go along.

70
00:03:04.680 --> 00:03:07.440
Then for these queries we've got our functions.

71
00:03:07.440 --> 00:03:10.070
Nothing new here as well, they each take a connection,

72
00:03:10.070 --> 00:03:12.700
create a cursor, and then run the appropriate queries,

73
00:03:12.700 --> 00:03:15.930
like to create the different tables, to select polls

74
00:03:15.930 --> 00:03:17.570
and then there's cursor.fetchall.

75
00:03:17.570 --> 00:03:20.170
Here get_latest_poll is something we're gonna use

76
00:03:20.170 --> 00:03:22.940
to get the latest poll that was added to the database.

77
00:03:22.940 --> 00:03:24.850
This, I've put pass in here,

78
00:03:24.850 --> 00:03:26.540
because we haven't implemented yet.

79
00:03:26.540 --> 00:03:29.170
We're gonna use some new knowledge in order to do that

80
00:03:29.170 --> 00:03:32.420
so this is, at the moment, unimplemented.

81
00:03:32.420 --> 00:03:35.490
Getting poll details, we need a poll id,

82
00:03:35.490 --> 00:03:38.361
and then we're just gonna SELECT_POLL_WITH_OPTIONS,

83
00:03:38.361 --> 00:03:40.520
that just gives us essentially everything about a poll

84
00:03:40.520 --> 00:03:42.580
and then we return cursor.fetchall.

85
00:03:42.580 --> 00:03:45.260
To get a poll and the vote results that includes

86
00:03:45.260 --> 00:03:47.804
the vote percentage associated with it,

87
00:03:47.804 --> 00:03:49.710
we've got pass in there at the moment,

88
00:03:49.710 --> 00:03:51.670
we're gonna be implementing there later on.

89
00:03:51.670 --> 00:03:54.590
To get a random poll vote which would give us

90
00:03:54.590 --> 00:03:58.240
essentially the winner on a poll, we've got pass as well,

91
00:03:58.240 --> 00:04:00.200
we're gonna be implementing that later on.

92
00:04:00.200 --> 00:04:02.570
Creating a poll because it takes in the title

93
00:04:02.570 --> 00:04:04.870
and the owner as well as the options,

94
00:04:04.870 --> 00:04:06.880
we're gonna be implementing this later on as well.

95
00:04:06.880 --> 00:04:09.190
And finally to add a poll vote, that's just

96
00:04:09.190 --> 00:04:12.373
the INSERT_VOTE there, so we've got that running there.

97
00:04:13.530 --> 00:04:16.380
All right, so not much new in database.py,

98
00:04:16.380 --> 00:04:19.880
but again, that was of course the point of this,

99
00:04:19.880 --> 00:04:22.420
not to give you anything too new.

100
00:04:22.420 --> 00:04:24.722
Now we're gonna go over to app.py

101
00:04:24.722 --> 00:04:26.690
and I'll show you what we've got in here,

102
00:04:26.690 --> 00:04:28.940
which is quite a bit, so please bear with me.

103
00:04:30.090 --> 00:04:33.140
The imports, you may get an error here saying

104
00:04:34.023 --> 00:04:38.340
DivisionByZero is not a class inside psycopg2.errors.

105
00:04:38.340 --> 00:04:40.170
What I've done is I've just ignored that

106
00:04:40.170 --> 00:04:42.930
so on here you can essentially click ignore

107
00:04:42.930 --> 00:04:44.340
if you do get that error.

108
00:04:44.340 --> 00:04:45.900
If you're using VS code or anything

109
00:04:45.900 --> 00:04:47.040
like that that's not PyCharm,

110
00:04:47.040 --> 00:04:48.980
you're not gonna get an error, that's fine.

111
00:04:48.980 --> 00:04:52.130
This works, it's just due to how psychopg2 is built

112
00:04:52.130 --> 00:04:53.963
that it gives an error in PyCharm.

113
00:04:54.820 --> 00:04:57.300
Then we've got our constant database prompt

114
00:04:57.300 --> 00:04:59.590
asking the user for the database URI.

115
00:04:59.590 --> 00:05:02.660
The menu prompt to show him the different options

116
00:05:02.660 --> 00:05:05.330
in the menu and the new option prompt when we have

117
00:05:05.330 --> 00:05:07.790
to add new options into a poll,

118
00:05:07.790 --> 00:05:09.870
that just tells the user what to do.

119
00:05:09.870 --> 00:05:14.100
So, to create a poll, we're going to ask the user

120
00:05:14.100 --> 00:05:16.980
for a title and the owner of the poll,

121
00:05:16.980 --> 00:05:19.290
then we're gonna create an empty options list,

122
00:05:19.290 --> 00:05:21.440
and then we're gonna use this walrus operator

123
00:05:21.440 --> 00:05:24.730
that we've looked at before to keep adding new options

124
00:05:24.730 --> 00:05:29.730
to this list as strings until they enter an empty string,

125
00:05:30.040 --> 00:05:32.660
and then we're gonna pass all of that to create poll.

126
00:05:32.660 --> 00:05:35.310
So at the moment, this is not implemented, the create_poll,

127
00:05:35.310 --> 00:05:37.700
so we're gonna look at that later on.

128
00:05:37.700 --> 00:05:39.560
To list the open polls, we're just gonna do

129
00:05:39.560 --> 00:05:43.230
database.get_polls and then we're gonna destruction in here,

130
00:05:43.230 --> 00:05:45.670
the different poll fields, and we're gonna print them out.

131
00:05:45.670 --> 00:05:49.710
Prompting for a vote, we're gonna ask for the poll id

132
00:05:49.710 --> 00:05:50.990
that the user wants to vote on,

133
00:05:50.990 --> 00:05:52.900
we're gonna get its details, we're gonna print

134
00:05:52.900 --> 00:05:55.050
the different options out, and then we're gonna ask them

135
00:05:55.050 --> 00:05:56.940
for which option they want to vote for as well as

136
00:05:56.940 --> 00:05:58.890
what their username is and we're gonna pass

137
00:05:58.890 --> 00:06:02.080
all of that data to add_poll_vote.

138
00:06:02.080 --> 00:06:03.990
Printing the polls options just goes through them

139
00:06:03.990 --> 00:06:05.490
and prints their details out.

140
00:06:05.490 --> 00:06:06.970
We're gonna look into more detail

141
00:06:06.970 --> 00:06:09.350
as to how this works in just a moment.

142
00:06:09.350 --> 00:06:13.130
And then show_poll_votes is gonna essentially ask the user

143
00:06:13.130 --> 00:06:15.440
for the poll that they wanna see votes for,

144
00:06:15.440 --> 00:06:18.240
then it's gonna get the count and percentage

145
00:06:18.240 --> 00:06:19.910
of votes for each option in a poll

146
00:06:19.910 --> 00:06:22.200
using database.get_poll_and_vote_results.

147
00:06:22.200 --> 00:06:24.890
We haven't implemented this yet, but we will do.

148
00:06:24.890 --> 00:06:27.589
And this can raise DivisionByZero error,

149
00:06:27.589 --> 00:06:31.190
if there are no votes, because it'll try to divide by zero

150
00:06:31.190 --> 00:06:34.368
which it can't do so then we're gonna print no votes yet.

151
00:06:34.368 --> 00:06:37.060
Otherwise, if we didn't get an error,

152
00:06:37.060 --> 00:06:38.710
that means this ran successfully,

153
00:06:38.710 --> 00:06:42.410
then we jump into here and we're gonna print that stuff out.

154
00:06:42.410 --> 00:06:44.190
Notice that we're using .2f here

155
00:06:44.190 --> 00:06:46.070
as the formatting guide specifies.

156
00:06:46.070 --> 00:06:48.530
You can use for printing to two decimal places.

157
00:06:48.530 --> 00:06:50.310
I'm gonna leave a link in the resources section

158
00:06:50.310 --> 00:06:52.810
of this video in case you don't know what that is.

159
00:06:52.810 --> 00:06:56.150
All right so this is the more complicated thing so far,

160
00:06:56.150 --> 00:06:58.020
but we're going to analyse it in more detail

161
00:06:58.020 --> 00:07:01.860
as we implement get_poll_and_vote_results.

162
00:07:01.860 --> 00:07:05.340
Finally, randomize_poll_winner takes in a poll id,

163
00:07:05.340 --> 00:07:08.500
prints out the poll options, and then asks for the option id

164
00:07:08.500 --> 00:07:11.010
that is the winner, and then goes into the database

165
00:07:11.010 --> 00:07:14.730
and gets a random vote out of this option,

166
00:07:14.730 --> 00:07:16.800
and then it's gonna print it out.

167
00:07:16.800 --> 00:07:19.780
We're gonna use the database to get the random vote,

168
00:07:19.780 --> 00:07:22.080
so we're gonna learn how to do that later on.

169
00:07:22.080 --> 00:07:24.550
Finally, we have here the MENU_OPTIONS,

170
00:07:24.550 --> 00:07:26.800
so if the user types one,

171
00:07:26.800 --> 00:07:28.310
we're gonna run prompt_create_poll.

172
00:07:28.310 --> 00:07:29.810
If they type two, we're gonna run

173
00:07:29.810 --> 00:07:31.560
list_open_polls and so forth.

174
00:07:31.560 --> 00:07:33.260
But as you can see, this dictionary here

175
00:07:33.260 --> 00:07:37.390
is a mapping of strings, like one, two, and three,

176
00:07:37.390 --> 00:07:40.530
to functions, prompt_create_poll, for example.

177
00:07:40.530 --> 00:07:42.370
It does not run the function.

178
00:07:42.370 --> 00:07:43.530
You would have to run the function

179
00:07:43.530 --> 00:07:45.210
with the brackets like that.

180
00:07:45.210 --> 00:07:46.570
So we're not doing that here,

181
00:07:46.570 --> 00:07:48.320
we're simply mapping the strings

182
00:07:48.320 --> 00:07:49.869
to the functions themselves.

183
00:07:49.869 --> 00:07:51.070
Why?

184
00:07:51.070 --> 00:07:53.029
Because later on in the menu down here,

185
00:07:53.029 --> 00:07:56.659
what we're gonna do is we're going to access

186
00:07:56.659 --> 00:08:00.419
the selection that the user typed, for example, two,

187
00:08:00.419 --> 00:08:03.370
and we're gonna run that.

188
00:08:03.370 --> 00:08:04.960
So this is a little bit of syntax here

189
00:08:04.960 --> 00:08:06.900
that simplifies our menu greatly.

190
00:08:06.900 --> 00:08:09.250
Let's go through this menu function, by the way.

191
00:08:09.250 --> 00:08:11.390
First of all, we're asking for the database URI

192
00:08:11.390 --> 00:08:13.220
using the DATABASE_PROMPT which tells the user

193
00:08:13.220 --> 00:08:15.150
that they can leave it empty if they want

194
00:08:15.150 --> 00:08:17.500
to load from the .env file.

195
00:08:17.500 --> 00:08:19.290
So if they don't type anything, we'll load

196
00:08:19.290 --> 00:08:21.590
from the .env and then we set that

197
00:08:21.590 --> 00:08:24.020
from the environment variables, then we create

198
00:08:24.020 --> 00:08:26.410
the connection to the database, and we use that

199
00:08:26.410 --> 00:08:30.680
to create the tables, then again with the walrus operator,

200
00:08:30.680 --> 00:08:32.610
we allow the user to select an option.

201
00:08:32.610 --> 00:08:35.800
This will be the string one, two, three, four, or five.

202
00:08:35.800 --> 00:08:38.270
Then we go into the menu options and select

203
00:08:38.270 --> 00:08:39.990
the appropriate function using that string.

204
00:08:39.990 --> 00:08:42.290
For example let's say they entered three,

205
00:08:42.290 --> 00:08:44.630
then this piece of text that's highlighted

206
00:08:44.630 --> 00:08:46.670
would return prompt_vote_poll,

207
00:08:46.670 --> 00:08:49.250
so that would essentially replace that,

208
00:08:49.250 --> 00:08:51.910
and as you can see this is how we run the function.

209
00:08:51.910 --> 00:08:54.390
We grab the function from there and then we run it,

210
00:08:54.390 --> 00:08:57.943
passing the connection to it, so that it can use it inside.

211
00:08:59.120 --> 00:09:01.300
Otherwise if they entered something that is not one

212
00:09:01.300 --> 00:09:03.970
of these things, that would give us a KeyError,

213
00:09:03.970 --> 00:09:06.000
in which case we print that an invalid input

214
00:09:06.000 --> 00:09:08.120
was selected and please try again.

215
00:09:08.120 --> 00:09:10.863
At the very end, we run the menu function as well.

216
00:09:11.740 --> 00:09:13.370
So I know this is a lot to take in.

217
00:09:13.370 --> 00:09:16.530
I would really recommend you download this code,

218
00:09:16.530 --> 00:09:19.690
go through it slowly, try to understand it fully.

219
00:09:19.690 --> 00:09:21.260
I just wanted to save you some time,

220
00:09:21.260 --> 00:09:23.240
not have to write all of this stuff

221
00:09:23.240 --> 00:09:26.020
that we've already written before in front of you.

222
00:09:26.020 --> 00:09:28.040
So please do download it and check it out

223
00:09:28.040 --> 00:09:32.120
and once you're ready, we can continue with the next video.

224
00:09:32.120 --> 00:09:33.560
All right, so once you're happy with that,

225
00:09:33.560 --> 00:09:34.650
join me in the next video.

226
00:09:34.650 --> 00:09:37.583
Thank you for watching and I'll see you in the next one.

