1
00:00:00,180 --> 00:00:04,560
The goal is to take our password manager to the next level.

2
00:00:04,980 --> 00:00:09,150
And in order to do that, we need to add a search functionality.

3
00:00:09,240 --> 00:00:12,930
It's not good enough just to look through the data file anymore.

4
00:00:13,470 --> 00:00:18,180
What we want to be able to do is the type a website into the website entry,

5
00:00:18,420 --> 00:00:19,560
and then hit search

6
00:00:19,590 --> 00:00:24,540
and we get a pop up showing us our email and the password that was saved for

7
00:00:24,540 --> 00:00:27,060
that website. So this is the goal.

8
00:00:28,050 --> 00:00:32,070
But where we're currently at is we have a text file

9
00:00:32,520 --> 00:00:36,870
which contains the name of the website, the email and the password.

10
00:00:37,230 --> 00:00:39,480
This is very difficult to search

11
00:00:39,510 --> 00:00:42,840
and this is a really terrible format to work with.

12
00:00:43,350 --> 00:00:48,090
So we're going to be leveling up our data storage in our password manager

13
00:00:48,420 --> 00:00:53,420
and we're going to switch from saving data straight to a text file to a fancier

14
00:00:54,090 --> 00:00:57,720
data format, which is called JSON. Nope,

15
00:00:57,780 --> 00:01:01,770
this is not the latest hottest DJ on the block.

16
00:01:01,800 --> 00:01:04,019
It's actually JSON,

17
00:01:04,080 --> 00:01:06,930
which stands for JavaScript Object Notation.

18
00:01:07,620 --> 00:01:11,370
This was something that was designed originally for JavaScript

19
00:01:11,700 --> 00:01:16,080
but because it has such a simple structure and it's so easy to understand and

20
00:01:16,080 --> 00:01:19,620
work with that it's been adopted by many, many different fields,

21
00:01:19,710 --> 00:01:20,880
including Python.

22
00:01:21,480 --> 00:01:25,290
This is probably one of the most popular ways of transferring data,

23
00:01:25,590 --> 00:01:28,500
especially when you're transferring data across the internet.

24
00:01:29,010 --> 00:01:30,990
So this is what we're going to be learning about.

25
00:01:31,260 --> 00:01:33,780
And for those of you looking at this slide,

26
00:01:34,080 --> 00:01:37,800
you might've already realized that it's kind of similar to the dictionaries

27
00:01:37,800 --> 00:01:40,080
that we've been working with in Python, right?

28
00:01:40,890 --> 00:01:45,890
A JSON is essentially composed of a bunch of nested lists and dictionaries,

29
00:01:46,920 --> 00:01:50,550
and it has that key value pair data structure.

30
00:01:51,090 --> 00:01:56,090
This is essentially what we're aiming for so that we can store our data in this

31
00:01:56,520 --> 00:01:57,353
format

32
00:01:57,420 --> 00:02:02,420
and we'll be able to easily load up this data and search through it for the

33
00:02:02,730 --> 00:02:07,730
particular website that we want the information for. To work with JSON data in

34
00:02:08,610 --> 00:02:12,090
Python, we can use the inbuilt JSON library,

35
00:02:12,660 --> 00:02:15,690
and we're going to use it to write, read,

36
00:02:15,900 --> 00:02:19,830
and update data to a JSON file. To begin.

37
00:02:19,890 --> 00:02:22,170
I'm going to simplify our code a little bit.

38
00:02:22,260 --> 00:02:26,640
I'm going to get rid of this message box, which asked the user OK 

39
00:02:26,640 --> 00:02:30,540
or cancel. We're just going to assume that once they click add,

40
00:02:30,840 --> 00:02:33,180
then they're happy with email and password.

41
00:02:33,900 --> 00:02:36,450
So now that we've cut down that little bit of code,

42
00:02:36,480 --> 00:02:38,970
it makes this a little bit easier to understand.

43
00:02:39,540 --> 00:02:43,740
All that we're doing here is we're checking to make sure that the length of the

44
00:02:43,740 --> 00:02:48,390
website entry and the length of the password entry is equal to zero.

45
00:02:48,900 --> 00:02:52,620
And you might still have the length checking for the email entry,

46
00:02:52,920 --> 00:02:55,680
but remember that at the end of previous lessons,

47
00:02:55,980 --> 00:02:58,770
we actually inserted a default value.

48
00:02:59,110 --> 00:03:02,560
So we can actually skip that check as well if you wanted to.

49
00:03:03,820 --> 00:03:07,510
The reason why we want our code as simple as possible is so that when we're

50
00:03:07,510 --> 00:03:11,260
working with the JSON and we're learning about how to work with it,

51
00:03:11,620 --> 00:03:13,270
as long as everything else is simple,

52
00:03:13,450 --> 00:03:17,410
then we can focus on the new things that we're learning. In this case,

53
00:03:17,440 --> 00:03:20,590
instead of opening a data.txt file,

54
00:03:20,950 --> 00:03:24,820
I'm going to change the data format to a .json.

55
00:03:25,750 --> 00:03:28,450
And instead of using the append mode,

56
00:03:28,810 --> 00:03:33,810
I'm going to use the write mode because I'm going to be writing to this data.

57
00:03:34,990 --> 00:03:38,950
json file. Now, in order to write to a JSON file,

58
00:03:39,010 --> 00:03:42,100
we don't use this line of code. Instead,

59
00:03:42,340 --> 00:03:45,400
we use a method called json.dump,

60
00:03:46,420 --> 00:03:50,860
and that, of course, requires us to import the JSON module

61
00:03:51,400 --> 00:03:55,030
which should be inbuilt to Python so you don't actually have to install it.

62
00:03:55,840 --> 00:03:58,840
Now, once we've imported our JSON module,

63
00:03:58,870 --> 00:04:01,570
we can say json.dump.

64
00:04:02,200 --> 00:04:06,310
And this takes a number of inputs, but the most important

65
00:04:06,670 --> 00:04:10,450
are the things you want to dump and the file that you want to dump it to.

66
00:04:10,960 --> 00:04:14,590
The data that we want to put in here should go in as a dictionary.

67
00:04:15,220 --> 00:04:18,790
Essentially, what we want to create is a new dictionary

68
00:04:18,820 --> 00:04:23,050
which I'll call new_data and it's going to be a nested dictionary.

69
00:04:23,560 --> 00:04:26,530
So the first level key is going to be the website,

70
00:04:26,740 --> 00:04:29,470
because this is what we're going to be searching through eventually.

71
00:04:30,100 --> 00:04:33,640
And the website is going to, itself, contain a dictionary.

72
00:04:34,360 --> 00:04:38,140
Now this dictionary contains two keys, the email,

73
00:04:38,650 --> 00:04:41,080
and also the password.

74
00:04:42,490 --> 00:04:45,580
The values for each of these are pretty self-explanatory,

75
00:04:45,580 --> 00:04:50,580
it's the email that we got from this line of code and the password is the

76
00:04:50,680 --> 00:04:53,380
password that we got from this line of code.

77
00:04:55,720 --> 00:04:59,110
Now that we've created this new dictionary called new_data,

78
00:04:59,530 --> 00:05:03,610
well that is what we're going to use to dump into our JSON file.

79
00:05:04,060 --> 00:05:08,830
Let's go ahead and dump our new data. So that's the first input. Now,

80
00:05:08,830 --> 00:05:13,390
the next input is going to be the data file that we want to put it into.

81
00:05:13,870 --> 00:05:17,230
So that is going to be the file that we opened up inside this line.

82
00:05:18,190 --> 00:05:21,940
Let's provide our data file as the location to dump this data.

83
00:05:22,570 --> 00:05:25,540
And now if I go ahead and hit run

84
00:05:27,040 --> 00:05:32,040
and I create a new entry for my Amazon website password, generate the password,

85
00:05:32,680 --> 00:05:33,520
hit add,

86
00:05:34,600 --> 00:05:38,770
then you can see that we've got our brand new data.json file

87
00:05:38,800 --> 00:05:42,070
that's just been created. So just as a quick reminder,

88
00:05:42,100 --> 00:05:45,880
when you open a file in write mode, if that file doesn't exist,

89
00:05:45,910 --> 00:05:50,590
it will actually create it. So we've created this new file, data.json,

90
00:05:50,770 --> 00:05:54,910
and we've dumped the data that we entered into that file.

91
00:05:55,030 --> 00:05:56,500
So now if I open this up,

92
00:05:56,740 --> 00:06:01,740
you can see we've got a JSON format in here and we've got our Amazon website

93
00:06:02,390 --> 00:06:04,370
and all of its associated data.

94
00:06:05,540 --> 00:06:09,500
Notice how this data is not very easy to read for a human.

95
00:06:10,100 --> 00:06:14,210
So we can actually improve that by adding one other argument.

96
00:06:14,690 --> 00:06:17,240
And it's an argument called indent. This,

97
00:06:17,240 --> 00:06:22,240
we can provide the number of spaces to indent all the JSON data so that it

98
00:06:22,460 --> 00:06:24,350
becomes much easier to read.

99
00:06:24,680 --> 00:06:29,030
So I'm going to go ahead and delete everything that's in here and I'm gonna run

100
00:06:29,060 --> 00:06:32,300
the code again. And this time,

101
00:06:32,660 --> 00:06:36,770
once I save this data into my data.json,

102
00:06:37,040 --> 00:06:41,510
you can see everything is all indented and it's much easier for the human to

103
00:06:41,510 --> 00:06:42,343
read.

104
00:06:43,070 --> 00:06:47,210
Now that we've seen how we can write data to a JSON file,

105
00:06:47,780 --> 00:06:52,780
the next step I want to show you is how you can load data from the JSON file or

106
00:06:53,420 --> 00:06:57,200
how to read from it. To read JSON data

107
00:06:57,230 --> 00:07:00,440
te use the JSON module and we call the load method.

108
00:07:01,010 --> 00:07:03,650
So I'm going to go ahead and comment out this line of code.

109
00:07:04,160 --> 00:07:08,840
And now that I've actually got some data in my data.json file,

110
00:07:09,080 --> 00:07:11,030
I'm going to try and read from it.

111
00:07:11,480 --> 00:07:16,430
We call the json.load method and we pass in the file path,

112
00:07:16,520 --> 00:07:18,380
or you can see here the fp.

113
00:07:18,950 --> 00:07:21,590
So that's the only required input.

114
00:07:22,040 --> 00:07:25,820
The file that we're going to pass in is our data file

115
00:07:25,850 --> 00:07:28,040
which we opened up over here

116
00:07:28,700 --> 00:07:33,700
ad what we're going to do is we're going to change this from write mode to read

117
00:07:35,150 --> 00:07:39,230
mode. Once we've loaded up the data,

118
00:07:39,230 --> 00:07:41,930
we're gonna save it inside a variable called data

119
00:07:42,230 --> 00:07:46,400
and then I'm just going to print it out. So when I hit run right now,

120
00:07:47,510 --> 00:07:50,120
and I simply add any sort of gobbledy goop,

121
00:07:50,390 --> 00:07:52,730
but as long as I can hit the add button,

122
00:07:52,970 --> 00:07:55,130
it's going to trigger this part of the code.

123
00:07:55,700 --> 00:07:58,370
And now if we take a look inside our console,

124
00:07:58,580 --> 00:08:02,180
you can see that data is being printed down here,

125
00:08:02,420 --> 00:08:07,250
but without any of these indentations or any of the formatting. Instead,

126
00:08:07,370 --> 00:08:12,370
what that load method does is it essentially takes this JSON data and

127
00:08:13,370 --> 00:08:16,310
converts it into a Python dictionary.

128
00:08:17,060 --> 00:08:18,530
So this data,

129
00:08:19,760 --> 00:08:22,100
if we actually do a type check on it,

130
00:08:22,250 --> 00:08:24,890
you can see it has a type of dictionary.

131
00:08:24,890 --> 00:08:27,680
This is just a normal Python dictionary.

132
00:08:28,430 --> 00:08:33,429
So essentially we can use json.dump and json. load to serialize

133
00:08:33,710 --> 00:08:38,150
and deserialize from JSON data to Python dictionaries.

134
00:08:38,600 --> 00:08:41,720
And it allows us that free interchange of information.

135
00:08:42,500 --> 00:08:44,540
We change it into a JSON to store it,

136
00:08:44,720 --> 00:08:48,530
and then we take it out of storage and turn it into a Python dictionary to

137
00:08:48,530 --> 00:08:50,570
easily work with it in our code.

138
00:08:51,740 --> 00:08:53,750
Now that we've seen how to write,

139
00:08:53,870 --> 00:08:58,440
how to read, the last thing I want to show you is how to update data.

140
00:08:58,980 --> 00:09:02,040
Because if we have a new piece of data come in,

141
00:09:02,370 --> 00:09:06,390
we want to add to this JSON but we don't want to overwrite it.

142
00:09:06,960 --> 00:09:09,930
But we also don't want to just append to the end of it,

143
00:09:10,140 --> 00:09:14,070
because as you can imagine if we had something that we just appended to the end,

144
00:09:14,400 --> 00:09:16,950
that's not a valid data structure

145
00:09:17,040 --> 00:09:21,510
and that's why we're getting all of these errors. Instead of doing it manually,

146
00:09:21,540 --> 00:09:24,810
we're going to use the builtin method json.update.

147
00:09:25,350 --> 00:09:30,210
And here's how it works. So we've already got some data inside our data.

148
00:09:30,240 --> 00:09:34,830
json file and I'm going to change this from read again, back to write.

149
00:09:35,430 --> 00:09:40,320
And what we want to do is we want to take that data and we want to update what's

150
00:09:40,350 --> 00:09:45,350
existing in there with the new data that's being passed in. To do that

151
00:09:46,560 --> 00:09:51,480
we first have to load up the data, so I'm going to uncomment this line,

152
00:09:51,930 --> 00:09:54,210
and once we've gotten hold of the data,

153
00:09:54,480 --> 00:09:58,500
we're going to say data.update.

154
00:10:00,570 --> 00:10:05,570
And we update it with the new data. What's happened so far is we have our data

155
00:10:07,530 --> 00:10:10,020
loaded up into a dictionary,

156
00:10:10,530 --> 00:10:15,530
we use the update method to update that dictionary with some new piece of data.

157
00:10:16,980 --> 00:10:17,550
Now,

158
00:10:17,550 --> 00:10:22,550
the next thing we want to do is we want to actually write that data back into

159
00:10:22,650 --> 00:10:23,490
this file.

160
00:10:23,850 --> 00:10:28,620
So we have to use this line of code using json.dump.

161
00:10:30,960 --> 00:10:33,270
But instead of dumping the new data,

162
00:10:33,330 --> 00:10:36,750
we're going to dump that data that we updated right here.

163
00:10:38,370 --> 00:10:42,150
Essentially what we're doing here is a three-step approach.

164
00:10:42,480 --> 00:10:47,480
We're reading the old data, we're updating old data with new data,

165
00:10:50,940 --> 00:10:55,230
and we're finally saving the updated data. Here

166
00:10:55,230 --> 00:10:59,070
we've got two things happening. We've got reading and we've got writing.

167
00:10:59,460 --> 00:11:04,080
So we can split this code into two sections. First,

168
00:11:04,440 --> 00:11:08,700
we open the file in read mode, we get hold of the data,

169
00:11:08,730 --> 00:11:13,730
we update the data and then we open up the file again.

170
00:11:14,700 --> 00:11:17,370
But in this case, we open it in write mode.

171
00:11:18,960 --> 00:11:23,960
This time we're going to dump the data that we've updated over here into that

172
00:11:24,780 --> 00:11:28,200
data file using this particular indent format.

173
00:11:29,640 --> 00:11:31,260
And once we written to file,

174
00:11:31,320 --> 00:11:36,180
and we delete all the text from a website and password entries and these lines

175
00:11:36,180 --> 00:11:41,180
of code now replace our previous functionality where we were saving just plain

176
00:11:41,220 --> 00:11:45,660
text to our data.txt. Let's go ahead and run it and test it out.

177
00:11:46,170 --> 00:11:50,040
Currently, we have a single entry inside our data.json.

178
00:11:50,520 --> 00:11:53,250
So if we go ahead and add a new entry,

179
00:11:53,290 --> 00:11:56,830
say for eBay, and we generate password, click add.

180
00:11:57,670 --> 00:12:02,620
If we go back to our data.json, you can see how it's now been updated.

181
00:12:03,190 --> 00:12:08,190
This entire JSON has now been updated to have two entries,

182
00:12:08,560 --> 00:12:12,430
Amazon and eBay. It didn't just append it.

183
00:12:12,460 --> 00:12:15,520
It actually added it into the dictionary

184
00:12:15,820 --> 00:12:18,340
and that's all thanks to that update method.

185
00:12:18,820 --> 00:12:20,920
And once it updated that data,

186
00:12:21,160 --> 00:12:26,160
then we told it to save the updated data back into the data file and wipe all of

187
00:12:26,740 --> 00:12:31,180
the previous data. So now that we're able to read,

188
00:12:31,210 --> 00:12:33,670
write and update JSON data,

189
00:12:34,090 --> 00:12:39,070
the next step is to think about what situations might this fail.

190
00:12:39,820 --> 00:12:44,820
And one of the biggest problems we have at the moment is we're trying to open up

191
00:12:45,550 --> 00:12:49,090
this file, load up the data and update it.

192
00:12:49,600 --> 00:12:52,420
But if we actually had no data in here,

193
00:12:52,510 --> 00:12:55,570
say the first time we ran our program, or indeed,

194
00:12:55,570 --> 00:12:58,870
if we didn't actually have this data.json file,

195
00:12:59,470 --> 00:13:04,420
then you can see that the first time I run it and I tried to save a password,

196
00:13:06,580 --> 00:13:11,110
then it's going to crush and we get some exceptions being thrown.

197
00:13:11,620 --> 00:13:15,340
But we know all about exceptions now. So in the next lesson,

198
00:13:15,610 --> 00:13:18,460
that's what we're going to tackle. For all of that,

199
00:13:18,790 --> 00:13:20,650
and more, head ever to the next lesson.

