1 00:00:00,720 --> 00:00:02,009 Instructor: Up to this point, 2 00:00:02,009 --> 00:00:06,270 we've learned about a few ways to organize our Python code. 3 00:00:06,270 --> 00:00:07,770 The first thing we did, 4 00:00:07,770 --> 00:00:11,130 well, we just wrote Python in a file, 5 00:00:11,130 --> 00:00:13,200 and that organizes it, right? 6 00:00:13,200 --> 00:00:17,880 Our entire code has been so far on one single file. 7 00:00:17,880 --> 00:00:20,673 So that was one way that we organized our code. 8 00:00:21,510 --> 00:00:24,030 Next, we learned about functions. 9 00:00:24,030 --> 00:00:28,560 And functions were used as a way for us to not write code 10 00:00:28,560 --> 00:00:30,720 that we repeat over and over. 11 00:00:30,720 --> 00:00:34,470 We could write functions that we can use anywhere we want 12 00:00:34,470 --> 00:00:35,640 in our file 13 00:00:35,640 --> 00:00:38,820 so that we can call these functions over and over, 14 00:00:38,820 --> 00:00:40,980 and we can name the functions appropriately 15 00:00:40,980 --> 00:00:43,973 so that our code makes sense. 16 00:00:43,973 --> 00:00:47,070 And then we learned about classes, right? 17 00:00:47,070 --> 00:00:50,250 These blueprints that we can create objects from. 18 00:00:50,250 --> 00:00:53,520 We can instantiate new Python data types 19 00:00:53,520 --> 00:00:56,730 beyond the ones that they just gave us, right? 20 00:00:56,730 --> 00:00:59,430 Instead of just having dictionaries and lists, 21 00:00:59,430 --> 00:01:01,530 we can create our own custom ones. 22 00:01:01,530 --> 00:01:05,078 Our own lists may be that have extra features, 23 00:01:05,078 --> 00:01:09,000 and we're able to use classes to organize our code 24 00:01:09,000 --> 00:01:13,920 to box them up and give each class a certain method 25 00:01:13,920 --> 00:01:18,920 and attribute that packages it nicely for us to use. 26 00:01:19,170 --> 00:01:21,690 We also learned about functional programming 27 00:01:21,690 --> 00:01:25,676 and how unlike, let's say, object oriented programming 28 00:01:25,676 --> 00:01:26,670 where we see a lot of classes. 29 00:01:26,670 --> 00:01:28,350 With functional programming, 30 00:01:28,350 --> 00:01:32,490 we just use a lot of functions, a lot of pure functions. 31 00:01:32,490 --> 00:01:36,060 And we have data that we just pass into those functions. 32 00:01:36,060 --> 00:01:39,960 And we organize things into small little pieces. 33 00:01:39,960 --> 00:01:42,570 All of these things were meant for us 34 00:01:42,570 --> 00:01:45,270 to keep our code clean, 35 00:01:45,270 --> 00:01:47,460 make our code more maintainable, 36 00:01:47,460 --> 00:01:50,130 thus keeping our code organized. 37 00:01:50,130 --> 00:01:53,160 Because as we write more lines of code, 38 00:01:53,160 --> 00:01:57,840 it gets harder and harder to keep everything in your head. 39 00:01:57,840 --> 00:02:00,930 If other people join your team to work on your project, 40 00:02:00,930 --> 00:02:04,942 they need an easy way to figure out how things are working. 41 00:02:04,942 --> 00:02:07,560 But we still have a problem. 42 00:02:07,560 --> 00:02:10,259 And that problem is that everything is contained 43 00:02:10,259 --> 00:02:12,450 in this one file. 44 00:02:12,450 --> 00:02:14,850 All the functions, all the classes we've been writing 45 00:02:14,850 --> 00:02:17,703 has been on just one dot py file. 46 00:02:18,540 --> 00:02:21,270 But in real life, this isn't the case. 47 00:02:21,270 --> 00:02:23,610 We have a lot more code. 48 00:02:23,610 --> 00:02:27,660 And we can't just have one file with millions line of code. 49 00:02:27,660 --> 00:02:30,640 So, how do we stay organized? 50 00:02:30,640 --> 00:02:35,640 Well, if we had multiple files of Python like this, 51 00:02:38,400 --> 00:02:40,830 because our project is getting bigger and bigger. 52 00:02:40,830 --> 00:02:41,790 would this work, 53 00:02:41,790 --> 00:02:46,053 is there a way for us to link all of these files together? 54 00:02:47,400 --> 00:02:49,140 As a matter of fact, there is, 55 00:02:49,140 --> 00:02:52,950 and this is very common practice all across industry. 56 00:02:52,950 --> 00:02:57,093 And we call this way of organizing code modules. 57 00:02:57,960 --> 00:03:01,350 And modules are simply, well, these files, 58 00:03:01,350 --> 00:03:06,350 each one of these files, each dot py file is a module. 59 00:03:06,990 --> 00:03:09,120 And by building these modules, 60 00:03:09,120 --> 00:03:11,340 kind of like we built different functions, 61 00:03:11,340 --> 00:03:13,710 kind of like we built different classes. 62 00:03:13,710 --> 00:03:16,710 Because in inside of these files, we can have classes, 63 00:03:16,710 --> 00:03:20,520 we can have functions, but we can also have different files. 64 00:03:20,520 --> 00:03:24,363 So, a layer higher to divide up our code. 65 00:03:25,230 --> 00:03:26,063 And in this section, 66 00:03:26,063 --> 00:03:28,800 we're gonna learn all about modules and try to master it 67 00:03:28,800 --> 00:03:32,640 and see how we can write organized code. 68 00:03:32,640 --> 00:03:33,960 Let's have a look. 69 00:03:33,960 --> 00:03:34,830 You can see over here, 70 00:03:34,830 --> 00:03:39,830 if I click on files in our repo, we have a main.py. 71 00:03:39,870 --> 00:03:43,620 And every time I click run, this file gotta run. 72 00:03:43,620 --> 00:03:46,560 But what if we have more files? 73 00:03:46,560 --> 00:03:48,690 What if I add another file here? 74 00:03:48,690 --> 00:03:51,873 and we'll call it utility.py? 75 00:03:53,850 --> 00:03:55,950 So, based on what I just told you, 76 00:03:55,950 --> 00:03:58,320 these two things are what? 77 00:03:58,320 --> 00:04:00,450 They're modules, right? 78 00:04:00,450 --> 00:04:02,010 Maine.py is a module. 79 00:04:02,010 --> 00:04:04,533 Utility.py is a module. 80 00:04:05,400 --> 00:04:07,410 And when writing modules, 81 00:04:07,410 --> 00:04:10,950 we use the same principles as variables in Python, 82 00:04:10,950 --> 00:04:12,330 which is snake case. 83 00:04:12,330 --> 00:04:13,560 That is if there's spaces, 84 00:04:13,560 --> 00:04:16,833 we use underscore everything is lowercase letter. 85 00:04:17,760 --> 00:04:22,760 So, how do we divide up these modules? 86 00:04:22,800 --> 00:04:24,420 And this comes with practice. 87 00:04:24,420 --> 00:04:26,587 When you're just beginning, it's hard to say, 88 00:04:26,587 --> 00:04:28,230 "Hey, what goes into what file? 89 00:04:28,230 --> 00:04:29,940 What goes into what file?" 90 00:04:29,940 --> 00:04:32,550 But it's similar to classes, right? 91 00:04:32,550 --> 00:04:34,200 Similar to functions. 92 00:04:34,200 --> 00:04:39,200 We wanna divide up our code into chunks that make sense. 93 00:04:39,840 --> 00:04:42,810 Again, let's say we're working at Netflix. 94 00:04:42,810 --> 00:04:47,810 We might have a file dedicated to videos. 95 00:04:48,150 --> 00:04:50,970 We might have another file or module 96 00:04:50,970 --> 00:04:54,750 dedicated to the login of a user, 97 00:04:54,750 --> 00:04:58,320 maybe another file dedicated to analytics 98 00:04:58,320 --> 00:05:02,310 and figuring it out recommendations for users. 99 00:05:02,310 --> 00:05:06,150 We wanna group these classes and functions together 100 00:05:06,150 --> 00:05:09,423 inside of a file that makes sense. 101 00:05:10,290 --> 00:05:13,770 Now, one of the most common ways to use a module 102 00:05:13,770 --> 00:05:16,200 is something like a utility. 103 00:05:16,200 --> 00:05:19,830 Let's say we wanna create a utility module, 104 00:05:19,830 --> 00:05:22,230 that is a module that has a lot of, 105 00:05:22,230 --> 00:05:24,420 well, kind of like a tool belt, 106 00:05:24,420 --> 00:05:26,940 very simple functions that we can use 107 00:05:26,940 --> 00:05:28,440 all across our project, 108 00:05:28,440 --> 00:05:31,950 because we can imagine here having multiple files. 109 00:05:31,950 --> 00:05:34,380 So, let's create a very simple example. 110 00:05:34,380 --> 00:05:37,646 I'm going to say a multiply function exists here, 111 00:05:37,646 --> 00:05:41,163 and this takes a num1 and num2. 112 00:05:42,780 --> 00:05:47,580 And in here we're simply going to return num1 times num2, 113 00:05:48,750 --> 00:05:50,790 a very simple function. 114 00:05:50,790 --> 00:05:54,510 And once again, we'll also have a divide function. 115 00:05:54,510 --> 00:05:56,400 And yes, this is kind of useless 116 00:05:56,400 --> 00:06:01,140 because we can just use the plus or to divide operant 117 00:06:01,140 --> 00:06:01,973 in Python. 118 00:06:01,973 --> 00:06:03,330 But stick with me here. 119 00:06:03,330 --> 00:06:05,790 I'm trying to show you an example. 120 00:06:05,790 --> 00:06:06,843 All right, so num2, 121 00:06:07,680 --> 00:06:12,660 I'm going to return num1 divided by num2. 122 00:06:12,660 --> 00:06:14,490 Nice and simple. 123 00:06:14,490 --> 00:06:19,200 So, this is our utility module 124 00:06:19,200 --> 00:06:22,203 that has all these functions for us. 125 00:06:23,370 --> 00:06:26,010 Now, notice here that we're actually not doing anything 126 00:06:26,010 --> 00:06:26,843 in this file. 127 00:06:26,843 --> 00:06:28,830 I'm simply defining functions, 128 00:06:28,830 --> 00:06:31,680 but I'm not running any of the functions. 129 00:06:31,680 --> 00:06:34,020 But let's say we have this utility module 130 00:06:34,020 --> 00:06:37,860 and I wanna use it in my main.py file. 131 00:06:37,860 --> 00:06:39,510 How would we go about doing this? 132 00:06:40,860 --> 00:06:44,010 Well, the way we communicate 133 00:06:44,010 --> 00:06:47,010 between these two files is quite simple. 134 00:06:47,010 --> 00:06:50,610 All we need to do is use the import command, 135 00:06:50,610 --> 00:06:54,480 we import and then give it the file name 136 00:06:54,480 --> 00:06:55,560 that we wanna import. 137 00:06:55,560 --> 00:06:56,670 What do we wanna import? 138 00:06:56,670 --> 00:07:00,180 We wanna import utility, just like that. 139 00:07:00,180 --> 00:07:03,150 And notice that I'm not adding the dot py 140 00:07:03,150 --> 00:07:05,910 because we assume that whatever we're gonna import 141 00:07:05,910 --> 00:07:08,277 is going to be a Python file. 142 00:07:08,277 --> 00:07:11,700 So, we don't need to do that, just the name, just like that. 143 00:07:11,700 --> 00:07:14,193 Now, let's print utility here. 144 00:07:15,270 --> 00:07:16,683 If I run this, 145 00:07:19,590 --> 00:07:21,570 wow, do you see that? 146 00:07:21,570 --> 00:07:24,060 We have module utility from, 147 00:07:24,060 --> 00:07:27,690 and then this is a file path that this website generates 148 00:07:27,690 --> 00:07:28,993 for us. 149 00:07:28,993 --> 00:07:30,480 So, it doesn't really matter. 150 00:07:30,480 --> 00:07:33,717 Now, there's a few things that happened here. 151 00:07:33,717 --> 00:07:38,147 One is that we generated this pycache folder, 152 00:07:39,750 --> 00:07:41,883 underscore, underscore pycache. 153 00:07:42,960 --> 00:07:46,323 And oh, boy, what is this gibberish? 154 00:07:47,700 --> 00:07:50,970 Hmm, this is pretty confusing, right? 155 00:07:50,970 --> 00:07:54,900 Well, this pycache is created 156 00:07:54,900 --> 00:07:59,880 every time we run a file with, let's say, import statements. 157 00:07:59,880 --> 00:08:02,193 So, when we're using modules. 158 00:08:03,210 --> 00:08:07,714 You see what pycache does is when we click run, 159 00:08:07,714 --> 00:08:11,520 the interpreter is going to create this pycache folder 160 00:08:11,520 --> 00:08:14,910 and it's going to say, "Hey, I'm running this file, 161 00:08:14,910 --> 00:08:17,070 this one main.py file." 162 00:08:17,070 --> 00:08:20,130 Anything that main.py file imports, 163 00:08:20,130 --> 00:08:24,900 let's say utility in our case, I'm going to cache it. 164 00:08:24,900 --> 00:08:28,710 So, see how here it says .pyc. 165 00:08:28,710 --> 00:08:32,460 This is because it's using the C Python interpreter. 166 00:08:32,460 --> 00:08:35,700 Remember, this is the C Python, 167 00:08:35,700 --> 00:08:38,010 which is the interpreter written in C. 168 00:08:38,010 --> 00:08:41,669 So, this is actually a compiled file 169 00:08:41,669 --> 00:08:46,670 so that next time I click run here on my main.py, 170 00:08:47,130 --> 00:08:48,390 nothing changes. 171 00:08:48,390 --> 00:08:51,210 Because what's going to happen is, 172 00:08:51,210 --> 00:08:53,820 instead of loading up utility.py, 173 00:08:53,820 --> 00:08:58,680 it's going to load this compiled version of utility 174 00:08:58,680 --> 00:09:02,103 because nothing has changed in utility.py. 175 00:09:03,660 --> 00:09:05,670 And this makes things faster 176 00:09:05,670 --> 00:09:08,580 when I try to run main.py again. 177 00:09:08,580 --> 00:09:09,600 That's what caching is. 178 00:09:09,600 --> 00:09:11,730 Caching is, hey, I'm going to remember this, 179 00:09:11,730 --> 00:09:12,900 and this is the compiled version 180 00:09:12,900 --> 00:09:16,353 so I don't have to go through their compilation step again. 181 00:09:17,760 --> 00:09:21,330 But notice that the main.py file does not get compiled 182 00:09:21,330 --> 00:09:23,730 because, well, we run it every time. 183 00:09:23,730 --> 00:09:26,820 Now, if we change the utility function 184 00:09:26,820 --> 00:09:31,380 to not have the divide in there, I click run. 185 00:09:31,380 --> 00:09:32,730 And you don't notice it here. 186 00:09:32,730 --> 00:09:36,270 But this has now been rerun 187 00:09:36,270 --> 00:09:38,940 because we have a different file. 188 00:09:38,940 --> 00:09:41,970 You see that we have multiply here, but not divide. 189 00:09:41,970 --> 00:09:44,163 So, let's bring back divide again. 190 00:09:45,510 --> 00:09:47,253 Go back to here, click run. 191 00:09:50,130 --> 00:09:50,963 And there you go. 192 00:09:50,963 --> 00:09:53,430 We have divide here too now. 193 00:09:53,430 --> 00:09:55,380 But this is something that we don't touch. 194 00:09:55,380 --> 00:09:58,410 This just comes underneath the hood 195 00:09:58,410 --> 00:10:00,930 with any editor that we use. 196 00:10:00,930 --> 00:10:02,220 And in a few videos, 197 00:10:02,220 --> 00:10:04,410 we're gonna show you how this also happens 198 00:10:04,410 --> 00:10:06,930 when we use something like Pi Chart. 199 00:10:06,930 --> 00:10:11,377 This is just something that editors allow us to do 200 00:10:11,377 --> 00:10:13,560 just so our programs can run faster. 201 00:10:13,560 --> 00:10:15,150 So, I now have access. 202 00:10:15,150 --> 00:10:16,590 Let's make this a little bit smaller. 203 00:10:16,590 --> 00:10:18,180 I now have access to utility. 204 00:10:18,180 --> 00:10:19,470 And here's the interesting part. 205 00:10:19,470 --> 00:10:21,870 If I dot here, look at that. 206 00:10:21,870 --> 00:10:24,690 I have access to divide and multiply 207 00:10:24,690 --> 00:10:26,910 so that I can multiply numbers, 208 00:10:26,910 --> 00:10:29,163 let's say two and three, click run. 209 00:10:30,450 --> 00:10:35,250 And I am able to use the utility module in my main file. 210 00:10:35,250 --> 00:10:36,150 Very, very cool. 211 00:10:36,150 --> 00:10:41,150 If I do divide and I click run, I can use this as well. 212 00:10:41,250 --> 00:10:42,990 Very, very cool. 213 00:10:42,990 --> 00:10:45,540 And I can import as many times as I want. 214 00:10:45,540 --> 00:10:47,550 If I had a different file in here, 215 00:10:47,550 --> 00:10:49,170 and I wanna import another thing 216 00:10:49,170 --> 00:10:52,080 let's say there is a utility to file. 217 00:10:52,080 --> 00:10:53,130 Well, I can import that, 218 00:10:53,130 --> 00:10:55,093 and import as many things as I want 219 00:10:55,093 --> 00:10:59,160 and use them across my files. 220 00:10:59,160 --> 00:11:00,693 How cool is that? 221 00:11:02,160 --> 00:11:04,920 So now we have a way to organize our code 222 00:11:04,920 --> 00:11:08,610 and have all these files communicate together, 223 00:11:08,610 --> 00:11:11,370 because in real life, we have big projects. 224 00:11:11,370 --> 00:11:14,070 And these big projects are going to be worked on 225 00:11:14,070 --> 00:11:16,680 by different teams, different programmers. 226 00:11:16,680 --> 00:11:20,010 And we need a way to work with all these files. 227 00:11:20,010 --> 00:11:23,610 And by using the import statements between modules, 228 00:11:23,610 --> 00:11:25,905 we're able to use functionality 229 00:11:25,905 --> 00:11:28,680 just like we were able to use the functionality 230 00:11:28,680 --> 00:11:32,970 that functions provided us between different files. 231 00:11:32,970 --> 00:11:36,274 And most of the time, if you're working at a company, 232 00:11:36,274 --> 00:11:39,540 the first couple of lines on a dot py file 233 00:11:39,540 --> 00:11:41,370 are usually import statements 234 00:11:41,370 --> 00:11:45,123 because usually, you're communicating with other files. 235 00:11:46,050 --> 00:11:48,050 Let's learn some more in the next video.