1 00:00:00,550 --> 00:00:02,740 We covered a lot of rules in the last video. 2 00:00:02,740 --> 00:00:06,070 Things like keeping functions limited and not causing side effects. 3 00:00:06,070 --> 00:00:08,510 But how do we actually do those things? 4 00:00:08,510 --> 00:00:11,890 Let's go to WorkSpaces and look at some things not to do. 5 00:00:11,890 --> 00:00:15,060 So to illustrate some of the things that are bad ideas, 6 00:00:15,060 --> 00:00:20,380 things we shouldn't really do when we use Python, I've got a file here called 7 00:00:20,380 --> 00:00:25,340 bad examples.py, and we're gonna walk through what each of these things are. 8 00:00:25,340 --> 00:00:30,060 So up at the top, we have this list that's a very important list. 9 00:00:30,060 --> 00:00:32,130 It needs to stay exactly that way it is. 10 00:00:32,130 --> 00:00:38,930 Maybe these are the order that players signed up, or any number of things. 11 00:00:38,930 --> 00:00:43,680 So it needs to stay in the order of five, two, three, one whenever I use it, 12 00:00:43,680 --> 00:00:46,280 in different places, but you may want to do stuff with it. 13 00:00:46,280 --> 00:00:49,180 And then we have a variable called name that's just my name. 14 00:00:50,220 --> 00:00:53,140 So we have this function here called def mutate, and 15 00:00:53,140 --> 00:00:56,330 it takes very important lists and it sorts it. 16 00:00:56,330 --> 00:01:00,690 So let's do, right here, let's print 17 00:01:00,690 --> 00:01:06,220 very_important_list, and then let's call mutate. 18 00:01:07,800 --> 00:01:12,851 And then let's again print very_important_list. 19 00:01:12,851 --> 00:01:17,950 All right, so then we can run this with bad_example.py. 20 00:01:17,950 --> 00:01:22,957 And you can see that, since inside this function, 21 00:01:22,957 --> 00:01:28,902 we called sort on the list, it sorted the list even out here. 22 00:01:28,902 --> 00:01:33,470 So ideally, we'd get the same thing here and here. 23 00:01:33,470 --> 00:01:37,970 Both of those print calls would give us 5, 2, 3, 1, but instead, 24 00:01:37,970 --> 00:01:43,060 since we called mutate, we sorted the list in memory, it's sorted for good 25 00:01:43,060 --> 00:01:47,630 now as far as the program is concerned, and we get two different outputs. 26 00:01:47,630 --> 00:01:52,130 So, you don't want to call methods on mutable types 27 00:01:52,130 --> 00:01:55,310 unless you know exactly what you're doing and why, because you get this. 28 00:01:55,310 --> 00:01:57,620 It changes that list outside of the scope. 29 00:01:58,980 --> 00:02:01,490 All right, so that's a bad one. 30 00:02:01,490 --> 00:02:03,240 We won't do that anymore. 31 00:02:03,240 --> 00:02:05,040 On our next function here we're using global. 32 00:02:06,080 --> 00:02:11,840 And so what global does, there is another keyword similar to global called nonlocal 33 00:02:11,840 --> 00:02:14,880 that I'll put in the teacher's notes and recommend that you look up. 34 00:02:14,880 --> 00:02:18,590 What global does though is it says, hey, go out to the global scope, 35 00:02:18,590 --> 00:02:23,560 go as far out as you need to go and see if you can find a variable with this name. 36 00:02:23,560 --> 00:02:25,870 And if you do, give it to me, I'm gonna use it. 37 00:02:27,040 --> 00:02:30,490 So, normally, let's ignore this line. 38 00:02:30,490 --> 00:02:32,390 Let's comment out that line. 39 00:02:32,390 --> 00:02:36,699 Okay, so, if we're just looking at this function, all we're doing in here is we're 40 00:02:36,699 --> 00:02:40,020 setting a name, and we're setting it to the string James, okay? 41 00:02:41,040 --> 00:02:45,900 But, when we use global and we use name it 42 00:02:45,900 --> 00:02:49,850 comes out to this global scope and says oh hey there's a variable here called name. 43 00:02:49,850 --> 00:02:52,540 Let's reference that one and then here we've set it to James. 44 00:02:52,540 --> 00:02:56,420 So again let's do a similar kind of experiment we're gonna print name and 45 00:02:57,460 --> 00:02:59,335 then we're gonna call global.use. 46 00:03:00,600 --> 00:03:02,090 And then we're gonna print name again. 47 00:03:02,090 --> 00:03:05,080 Now ideally we would get Kenneth both times 48 00:03:05,080 --> 00:03:09,700 but We get Kenneth and then we get James. 49 00:03:09,700 --> 00:03:14,080 And the reason is because we've overridden that global name variable. 50 00:03:14,080 --> 00:03:16,220 We've got back up to this top scope and 51 00:03:16,220 --> 00:03:19,160 said hey, we're gonna change that variable up there. 52 00:03:19,160 --> 00:03:21,240 So don't do that. 53 00:03:21,240 --> 00:03:23,260 That's not good or predictable. 54 00:03:23,260 --> 00:03:27,510 There are occasionally times when you're gonna wanna use global. 55 00:03:27,510 --> 00:03:30,610 But those are very few and very far between. 56 00:03:30,610 --> 00:03:33,190 So now these next two we don't really need to run them. 57 00:03:33,190 --> 00:03:34,770 We're just gonna talk about these. 58 00:03:34,770 --> 00:03:37,630 I mentioned that we want to avoid functions that are too long, so 59 00:03:37,630 --> 00:03:38,240 let's look at this. 60 00:03:38,240 --> 00:03:43,390 We have this long_func here, it imports random, it gets some random 61 00:03:43,390 --> 00:03:49,210 numbers between 5 and 250, or rather shuffles the range 5 to 250 randomly. 62 00:03:49,210 --> 00:03:51,770 And then we run through, what do we have? 63 00:03:51,770 --> 00:03:55,530 We have an index and a num coming out of enumerate of all those numbers. 64 00:03:55,530 --> 00:04:02,292 If the number is divisible by three, or isn't evenly divisible by three. 65 00:04:02,292 --> 00:04:08,730 So, if this comes back as a truthy value, then we set the number to the fifth power. 66 00:04:09,980 --> 00:04:16,340 If it's not evenly divisible by seven, then we set the number to the tenth power, 67 00:04:16,340 --> 00:04:19,100 otherwise I always set the number squared. 68 00:04:19,100 --> 00:04:22,960 And then we total all those up, and then we print out the total and 69 00:04:22,960 --> 00:04:29,520 then we're returning the list of shuffled and now randomly mutated numbers. 70 00:04:29,520 --> 00:04:33,220 I wrote this function and I just had to stop and read it for 71 00:04:33,220 --> 00:04:35,520 a second to tell you what was happening in it. 72 00:04:35,520 --> 00:04:39,700 So we don't want functions like this, where there's just so much stuff going on, 73 00:04:39,700 --> 00:04:42,400 and you have to constantly think about what's happening. 74 00:04:42,400 --> 00:04:45,460 And now you may be saying but Kenneth I can put in comments, 75 00:04:45,460 --> 00:04:48,760 I can put in a doc string and I can explain what's going on. 76 00:04:48,760 --> 00:04:53,000 And then everybody will know and yeah that's true you can but 77 00:04:53,000 --> 00:04:57,630 if you have to explain what's happening in a function, what, not why, 78 00:04:57,630 --> 00:05:01,250 explaining the reason why the function was written is a great thing to do. 79 00:05:01,250 --> 00:05:05,340 But if you have to explain what the function does 80 00:05:05,340 --> 00:05:08,770 then you've probably written that function wrong, you should probably simplify this. 81 00:05:08,770 --> 00:05:12,180 This would be really good if we were to say like, 82 00:05:12,180 --> 00:05:16,700 maybe the function takes in the range of numbers, the list, right? 83 00:05:16,700 --> 00:05:19,500 Maybe it takes in that list and then works on them. 84 00:05:19,500 --> 00:05:23,000 Maybe it just returns that shuffled list or 85 00:05:23,000 --> 00:05:25,560 it returns, instead of returning the shuffled list because then you 86 00:05:25,560 --> 00:05:30,580 are repeating what the Python already does, maybe it returns the mutated list. 87 00:05:30,580 --> 00:05:31,080 This part. 88 00:05:32,230 --> 00:05:34,310 And it doesn't print or total or anything like that. 89 00:05:34,310 --> 00:05:35,550 Because why do we need to total it? 90 00:05:35,550 --> 00:05:38,530 The total seems completely useless. 91 00:05:38,530 --> 00:05:41,120 So, things to think about when you're designing functions, 92 00:05:41,120 --> 00:05:42,640 when you're designing your software. 93 00:05:43,760 --> 00:05:46,040 And then for the last one, lot_of_inputs. 94 00:05:47,140 --> 00:05:50,150 We mentioned having functions that take too many inputs, 95 00:05:50,150 --> 00:05:51,715 they take a whole bunch of stuff. 96 00:05:51,715 --> 00:05:53,035 Now in this case, 97 00:05:53,035 --> 00:05:56,705 if you look through you'll see that I've taken inputs that I'm not using. 98 00:05:56,705 --> 00:06:00,265 It's kind of an idea of like, well, we might need that some day so let's do it. 99 00:06:00,265 --> 00:06:03,675 That's generally a bad idea because it means you're usually putting way more 100 00:06:03,675 --> 00:06:08,685 thought into the software than actually needs to be there. 101 00:06:08,685 --> 00:06:11,250 And that might sound like a silly thing, but 102 00:06:11,250 --> 00:06:14,760 it means that you're spending all this time on details that don't actually 103 00:06:14,760 --> 00:06:17,870 matter, instead of writing the code that you need. 104 00:06:17,870 --> 00:06:19,290 So try not to do that. 105 00:06:20,620 --> 00:06:22,970 Try to do things in a smart and 106 00:06:22,970 --> 00:06:26,540 simple way to where you know exactly what the code's gonna do. 107 00:06:26,540 --> 00:06:29,720 So in this one we've got seven inputs coming in, 108 00:06:29,720 --> 00:06:31,970 only four of them actually get used. 109 00:06:31,970 --> 00:06:35,500 And we return this and again this is when I would say it's too long, 110 00:06:35,500 --> 00:06:37,051 it's too complicated of a function too. 111 00:06:37,051 --> 00:06:41,890 Cuz inside here we make these two named tuples which act kind of like classes 112 00:06:42,910 --> 00:06:47,530 and then we return objects that are of those classes and 113 00:06:47,530 --> 00:06:50,888 it's a lot of work for one function. 114 00:06:50,888 --> 00:06:53,740 So we're gonna avoid all of these design mistakes, 115 00:06:53,740 --> 00:06:56,980 all of these usage mistakes when we write our code. 116 00:06:56,980 --> 00:06:58,650 Mutable types, like lists and 117 00:06:58,650 --> 00:07:00,770 dictionaries, are things that we can deal with. 118 00:07:00,770 --> 00:07:04,610 Python gives us some handy tools like slices and some functions that we'll cover 119 00:07:04,610 --> 00:07:08,870 later in this course, that make it pretty easy to leave those things alone. 120 00:07:08,870 --> 00:07:11,050 Global is also pretty simple to avoid. 121 00:07:11,050 --> 00:07:12,470 Just don't use it. 122 00:07:12,470 --> 00:07:14,980 The last two things, writing long functions, or 123 00:07:14,980 --> 00:07:18,700 writing functions with inflated scopes are things you get better at not doing 124 00:07:18,700 --> 00:07:20,720 the more you pay attention to your code. 125 00:07:20,720 --> 00:07:23,040 You'll find, as you get more experience and practice, 126 00:07:23,040 --> 00:07:24,810 that it's second nature to keep things tight. 127 00:07:25,810 --> 00:07:28,340 In our next video, we'll get to the tools that we're actually going to 128 00:07:28,340 --> 00:07:30,990 use in the course, and the data that we'll use those tools on.