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