1 00:00:00,000 --> 00:00:03,479 [MUSIC PLAYING] 2 00:00:03,479 --> 00:00:23,860 3 00:00:23,860 --> 00:00:24,820 DAVID MALAN: All right. 4 00:00:24,820 --> 00:00:28,120 This is CS50's Introduction to Programming with Python. 5 00:00:28,120 --> 00:00:29,350 My name is David Malan. 6 00:00:29,350 --> 00:00:31,120 And this is a look at debugging. 7 00:00:31,120 --> 00:00:33,340 Odds are, by now, you've written quite a bit of code. 8 00:00:33,340 --> 00:00:36,550 And within that code is at least one, maybe even more, 9 00:00:36,550 --> 00:00:39,670 bugs, that is mistakes that you accidentally introduce to your code. 10 00:00:39,670 --> 00:00:41,770 Now, maybe your code doesn't even run at all. 11 00:00:41,770 --> 00:00:44,500 And you have some form of syntax error, or maybe you've 12 00:00:44,500 --> 00:00:45,610 gotten past that hurdle. 13 00:00:45,610 --> 00:00:48,400 And you just have one or more logical bugs, so to speak, 14 00:00:48,400 --> 00:00:51,580 whereby when you run your code, it doesn't produce the output 15 00:00:51,580 --> 00:00:52,777 that you actually intended. 16 00:00:52,777 --> 00:00:53,860 So it's not quite correct. 17 00:00:53,860 --> 00:00:55,210 There are mistakes therein. 18 00:00:55,210 --> 00:00:57,970 And how do you go about, then, solving those problems? 19 00:00:57,970 --> 00:01:00,730 Well, if you can't quite wrap your mind around what's 20 00:01:00,730 --> 00:01:02,980 going wrong by just reading with your own human eyes 21 00:01:02,980 --> 00:01:06,160 your own code from top to bottom, left to right, and you don't have, 22 00:01:06,160 --> 00:01:09,220 for instance, a teacher, a friend, a colleague, a rubber duck 23 00:01:09,220 --> 00:01:13,120 to help you reason through what might be wrong in your code, what kind of tools 24 00:01:13,120 --> 00:01:15,490 do we actually have for chasing down bugs in code 25 00:01:15,490 --> 00:01:16,780 and ultimately fixing them? 26 00:01:16,780 --> 00:01:20,380 Well, already, we actually have some tools at our disposal. 27 00:01:20,380 --> 00:01:23,980 And for instance, let me propose that we build something like this in code. 28 00:01:23,980 --> 00:01:27,910 So pictured here is Mario from Super Mario Brothers, the original Nintendo 29 00:01:27,910 --> 00:01:30,520 game, jumping over a pyramid of sorts. 30 00:01:30,520 --> 00:01:33,790 And that period is implemented with these bricks of sorts. 31 00:01:33,790 --> 00:01:36,310 Let's go ahead and create a textual version thereof, 32 00:01:36,310 --> 00:01:39,340 whereby we use maybe hash symbols, simple hashes, 33 00:01:39,340 --> 00:01:40,840 to represent each of these bricks. 34 00:01:40,840 --> 00:01:44,980 And therefore, the goal in printing out a pyramid textually that 35 00:01:44,980 --> 00:01:48,850 resembles that of Mario here would be to print out one hash, and then two 36 00:01:48,850 --> 00:01:51,730 hashes, and then three hashes, and perhaps more if the pyramid 37 00:01:51,730 --> 00:01:53,170 itself is higher. 38 00:01:53,170 --> 00:01:56,800 Well, let me propose that if I open up VS Code here-- and, in advance, 39 00:01:56,800 --> 00:01:59,350 I've created a file called mario.py. 40 00:01:59,350 --> 00:02:03,880 Let me propose that this is my intended solution to this problem. 41 00:02:03,880 --> 00:02:06,580 Let's go ahead and walk through what's here. 42 00:02:06,580 --> 00:02:09,639 I first, at the top of my file, have a main function 43 00:02:09,639 --> 00:02:13,450 defined, inside of which is a second line of code that calls input, 44 00:02:13,450 --> 00:02:15,820 asking the user for the height of this pyramid. 45 00:02:15,820 --> 00:02:20,620 Immediately, the return value of input is passed to the input of int 46 00:02:20,620 --> 00:02:23,140 so as to convert that textual input, presumably, 47 00:02:23,140 --> 00:02:24,640 to the corresponding integer. 48 00:02:24,640 --> 00:02:28,390 And then I'm storing on the left-hand side of that equal sign the value 49 00:02:28,390 --> 00:02:32,260 that the user typed in, be it 1, 2, 3, or anything else. 50 00:02:32,260 --> 00:02:34,690 And then I'm using that variable as an input 51 00:02:34,690 --> 00:02:38,170 to a function that's apparently called pyramid so that I can ultimately 52 00:02:38,170 --> 00:02:40,220 print out a pyramid of that height. 53 00:02:40,220 --> 00:02:40,720 All right. 54 00:02:40,720 --> 00:02:42,400 Well, what is this pyramid function? 55 00:02:42,400 --> 00:02:46,180 Well, it looks like, on this line six, that the pyramid function expects 56 00:02:46,180 --> 00:02:49,690 one argument called n, n presumably for number. 57 00:02:49,690 --> 00:02:51,370 And how am I using that number? 58 00:02:51,370 --> 00:02:53,890 Well, inside of this function, I have a for loop 59 00:02:53,890 --> 00:02:56,980 that's going to iterate, it would seem, n times. 60 00:02:56,980 --> 00:03:01,240 And this is indeed our common paradigm, doing for i in the range of n 61 00:03:01,240 --> 00:03:03,730 allows us to iterate from zero on up. 62 00:03:03,730 --> 00:03:05,980 And then that innermost line of code is just 63 00:03:05,980 --> 00:03:09,010 going to go ahead and print out some number of hashes. 64 00:03:09,010 --> 00:03:13,180 And recall this trick, whereby we're using the multiplication operator 65 00:03:13,180 --> 00:03:17,620 but really just to automatically concatenate one or more of these hashes 66 00:03:17,620 --> 00:03:18,250 together. 67 00:03:18,250 --> 00:03:20,590 So hopefully, the net effect of this program, 68 00:03:20,590 --> 00:03:24,310 once we actually run it per these final two lines, and main is invoked, 69 00:03:24,310 --> 00:03:26,350 and then pyramid is invoked, is that we'll get 70 00:03:26,350 --> 00:03:28,330 a pyramid of the corresponding height. 71 00:03:28,330 --> 00:03:31,390 But suppose now that I very enthusiastically 72 00:03:31,390 --> 00:03:33,340 went about trying to run this program. 73 00:03:33,340 --> 00:03:37,788 And so I went to my terminal window and ran python of mario.py. 74 00:03:37,788 --> 00:03:39,580 And then I went ahead and proposed a height 75 00:03:39,580 --> 00:03:44,740 of three, the goal being to have one hash, two hashes, three hashes so 76 00:03:44,740 --> 00:03:46,990 that the total pyramid is of height three. 77 00:03:46,990 --> 00:03:51,790 I'm a little disappointed already to see that it's not quite correct, 78 00:03:51,790 --> 00:03:52,810 this output. 79 00:03:52,810 --> 00:03:55,420 I seem to have a pyramid really of height two 80 00:03:55,420 --> 00:03:58,690 because there's a blank line, and then a single hash, and then two hashes. 81 00:03:58,690 --> 00:04:02,710 But, again, what I wanted was one hash, then two hashes, then three hashes, 82 00:04:02,710 --> 00:04:05,590 forming a pyramid that's in total of height three. 83 00:04:05,590 --> 00:04:08,950 Now, you might have an immediate instinct as to how to fix this problem. 84 00:04:08,950 --> 00:04:12,910 And indeed, relatively speaking, this isn't the most complicated program, 85 00:04:12,910 --> 00:04:17,290 at least if you're a few weeks into learning and writing code in Python. 86 00:04:17,290 --> 00:04:19,959 But suppose that it's just not obvious to me, 87 00:04:19,959 --> 00:04:23,500 or this is representative of an even more complicated problem down the road. 88 00:04:23,500 --> 00:04:27,340 And so I'd really like to start figuring out, systematically, 89 00:04:27,340 --> 00:04:29,500 how to solve this particular bug. 90 00:04:29,500 --> 00:04:31,410 Well, what's one tool in my toolkit? 91 00:04:31,410 --> 00:04:33,160 Well, let me propose first that I do this. 92 00:04:33,160 --> 00:04:36,730 Let me clear my terminal window to get rid of the output from before. 93 00:04:36,730 --> 00:04:41,470 And let me propose that it might be helpful for me to maybe figure out 94 00:04:41,470 --> 00:04:44,950 if maybe i is wrong, right? i is my variable in this for loop 95 00:04:44,950 --> 00:04:47,110 that's responsible for printing out, presumably, 96 00:04:47,110 --> 00:04:50,230 one hash, then two hashes, then three hashes, and so forth. 97 00:04:50,230 --> 00:04:54,310 So maybe just to check my understanding here 98 00:04:54,310 --> 00:04:58,780 I should-- maybe why don't I temporarily just print out i in addition 99 00:04:58,780 --> 00:05:02,260 to these hashes just so that I can make sure that i is what I expect next 100 00:05:02,260 --> 00:05:03,760 to the appropriate number of hashes? 101 00:05:03,760 --> 00:05:06,580 Which is to say, Print itself, the function 102 00:05:06,580 --> 00:05:08,680 we've been using now for quite some time, 103 00:05:08,680 --> 00:05:13,450 is a very reasonable, effective tool for debugging, at least in some cases. 104 00:05:13,450 --> 00:05:16,330 It's a nice way to quickly and dirtily, kind of, 105 00:05:16,330 --> 00:05:18,580 see what's going on inside of your code. 106 00:05:18,580 --> 00:05:19,690 Well, let me do this. 107 00:05:19,690 --> 00:05:22,570 In addition to printing out that number of hashes, 108 00:05:22,570 --> 00:05:25,180 let me also print out the value of i. 109 00:05:25,180 --> 00:05:27,490 But rather than print out a new line, which I think 110 00:05:27,490 --> 00:05:29,350 is going to completely mess up the pyramid, 111 00:05:29,350 --> 00:05:31,660 let me just end the line with a single space 112 00:05:31,660 --> 00:05:33,910 just to kind of push the cursor over to the right 113 00:05:33,910 --> 00:05:38,390 so that my pyramid is printed to the right of all of these integers. 114 00:05:38,390 --> 00:05:38,890 All right. 115 00:05:38,890 --> 00:05:43,750 Let me go down to my terminal window again and run python of mario.py Enter. 116 00:05:43,750 --> 00:05:45,940 I'm going to, again, type in 3 for the height. 117 00:05:45,940 --> 00:05:48,340 And now, I see essentially the same output. 118 00:05:48,340 --> 00:05:53,140 But I've prepended, so to speak, to each line the value of i. 119 00:05:53,140 --> 00:05:55,570 And now, maybe it makes a little more sense to me. 120 00:05:55,570 --> 00:05:58,540 Now, maybe the proverbial light bulb just went off over my head 121 00:05:58,540 --> 00:06:02,620 because, oh, the reason I'm seeing a blank line and then only 122 00:06:02,620 --> 00:06:06,370 one and only two hashes on the screen instead of one, two, and three 123 00:06:06,370 --> 00:06:09,610 respectively is because i, of course-- now I remember. 124 00:06:09,610 --> 00:06:14,020 --starts from zero, certainly when doing a for loop like the one 125 00:06:14,020 --> 00:06:15,730 I have here on line seven. 126 00:06:15,730 --> 00:06:17,410 So how do I go about fixing this? 127 00:06:17,410 --> 00:06:19,900 Well, I think, instinctively, I could just do this. 128 00:06:19,900 --> 00:06:22,180 Let me go ahead and remove the previous print. 129 00:06:22,180 --> 00:06:25,830 Indeed, when using print to debug your code, it's usually temporary. 130 00:06:25,830 --> 00:06:27,580 So I should now undo that change because I 131 00:06:27,580 --> 00:06:30,940 don't want those numbers to appear ultimately in my program's output. 132 00:06:30,940 --> 00:06:33,200 Let me go ahead now and print out-- 133 00:06:33,200 --> 00:06:33,700 OK. 134 00:06:33,700 --> 00:06:38,080 I don't want to print out zero hashes, and then one, and then two. 135 00:06:38,080 --> 00:06:41,985 I want to print out one more than the current value of i. 136 00:06:41,985 --> 00:06:44,110 And I bet there's a bunch of ways I can solve this. 137 00:06:44,110 --> 00:06:46,360 But I think the easiest way might be this. 138 00:06:46,360 --> 00:06:52,030 Let me go ahead and in parentheses do i + 1 so that what I'm really doing 139 00:06:52,030 --> 00:06:55,630 is multiplying this single hash by i + 1. 140 00:06:55,630 --> 00:06:59,650 So instead of being zero, one, and two hashes respectively, 141 00:06:59,650 --> 00:07:01,990 now it's one, two, and three. 142 00:07:01,990 --> 00:07:04,870 And I've parenthesized it just to make clear to myself 143 00:07:04,870 --> 00:07:07,030 that indeed the math is going to happen first, 144 00:07:07,030 --> 00:07:09,730 just like in math class, inside of the parentheses. 145 00:07:09,730 --> 00:07:13,360 And then I'm going to use that total value for the concatenation of all 146 00:07:13,360 --> 00:07:14,170 of those hashes. 147 00:07:14,170 --> 00:07:14,500 All right. 148 00:07:14,500 --> 00:07:16,458 Let me go ahead now back to my terminal window, 149 00:07:16,458 --> 00:07:20,350 clearing it, running python of mario.py once more. 150 00:07:20,350 --> 00:07:22,120 Let's again type in a height of 3. 151 00:07:22,120 --> 00:07:24,970 And now I have the intended pyramid. 152 00:07:24,970 --> 00:07:26,897 So a minor bug, if you will-- 153 00:07:26,897 --> 00:07:29,230 Certainly, if you're several weeks into learning python, 154 00:07:29,230 --> 00:07:32,230 already that kind of bug might have jumped out at you pretty quickly. 155 00:07:32,230 --> 00:07:34,022 But that's not always going to be the case. 156 00:07:34,022 --> 00:07:36,220 And so Print is the first of your friends 157 00:07:36,220 --> 00:07:37,900 when it comes to debugging your code. 158 00:07:37,900 --> 00:07:41,140 Using Print, you can temporarily, but pretty easily, 159 00:07:41,140 --> 00:07:45,100 just display the values of variables or other things in your program 160 00:07:45,100 --> 00:07:48,820 just so you can help see what the computer sees underneath the hood, 161 00:07:48,820 --> 00:07:49,870 so to speak. 162 00:07:49,870 --> 00:07:51,820 But it turns out there's more powerful tools. 163 00:07:51,820 --> 00:07:54,528 And Print can start to get a little tedious, especially if you're 164 00:07:54,528 --> 00:07:57,112 adding a print up here, and up here, and up here, and up here, 165 00:07:57,112 --> 00:07:59,413 and all over the place in more complicated programs 166 00:07:59,413 --> 00:08:02,080 because then you have to clean up a whole mess that you've made. 167 00:08:02,080 --> 00:08:04,180 And you might have put the Print in not the right location. 168 00:08:04,180 --> 00:08:06,763 And you have to remember what output is coming from one Print. 169 00:08:06,763 --> 00:08:09,790 So eventually, Print is not so much your friend. 170 00:08:09,790 --> 00:08:11,500 And we need better tools than that. 171 00:08:11,500 --> 00:08:13,990 So let me go ahead and clear my terminal window again. 172 00:08:13,990 --> 00:08:16,960 Let me undo these changes so that I again 173 00:08:16,960 --> 00:08:21,550 have the same bug, where I'm now printing out i number of hashes, so 174 00:08:21,550 --> 00:08:23,470 zero, one, and two again. 175 00:08:23,470 --> 00:08:25,780 And let me propose that we use another tool that 176 00:08:25,780 --> 00:08:28,750 comes with a lot of programming environments nowadays, 177 00:08:28,750 --> 00:08:30,130 VS Code included. 178 00:08:30,130 --> 00:08:33,159 Indeed, typically, I've hidden the so-called activity bar 179 00:08:33,159 --> 00:08:35,169 to the left-hand side here of VS Code. 180 00:08:35,169 --> 00:08:37,098 But I've revealed it today so that we can 181 00:08:37,098 --> 00:08:38,890 see some of the functionality that actually 182 00:08:38,890 --> 00:08:42,669 comes with VS Code, and other text editors, and other IDEs. 183 00:08:42,669 --> 00:08:47,170 Integrated Development Environments often come with built-in debuggers. 184 00:08:47,170 --> 00:08:50,470 And indeed, a debugger is a special type of program whose purpose in life 185 00:08:50,470 --> 00:08:53,860 is to do just that, to help you debug your program. 186 00:08:53,860 --> 00:08:56,830 It doesn't necessarily solve the problems for you. 187 00:08:56,830 --> 00:08:58,570 So it's perhaps a bit of a misnomer. 188 00:08:58,570 --> 00:08:59,470 But it helps you. 189 00:08:59,470 --> 00:09:03,580 It empowers you to solve bugs yourself and eliminate 190 00:09:03,580 --> 00:09:06,490 them more methodically than maybe Print alone would allow. 191 00:09:06,490 --> 00:09:08,170 So I'm going to do this first. 192 00:09:08,170 --> 00:09:12,130 I'm going to introduce this notion of what's called, generally, a breakpoint. 193 00:09:12,130 --> 00:09:16,750 A breakpoint is simply a mechanism when using a text editor or an IDE that 194 00:09:16,750 --> 00:09:20,320 allows you to specify on what line or what lines of code 195 00:09:20,320 --> 00:09:24,010 do you want to pause or break execution of the program 196 00:09:24,010 --> 00:09:27,280 just so you can start poking around at that line of code. 197 00:09:27,280 --> 00:09:31,240 In other words, if I keep running mario.py in my terminal window, 198 00:09:31,240 --> 00:09:34,480 it pretty much runs from top to bottom, left to right, again and again, 199 00:09:34,480 --> 00:09:36,550 pausing of course for my own human input. 200 00:09:36,550 --> 00:09:40,210 But it's so darn fast, Python, that I can't really 201 00:09:40,210 --> 00:09:43,630 see what's happening on each individual line of code. 202 00:09:43,630 --> 00:09:47,140 So let me go back to VS Code and this time set a breakpoint. 203 00:09:47,140 --> 00:09:49,420 Wouldn't it be nice if I could pump the brakes, 204 00:09:49,420 --> 00:09:53,320 so to speak, and slow down the execution of my program 205 00:09:53,320 --> 00:09:57,310 so that I can tell the computer when I, the human, am ready to step, 206 00:09:57,310 --> 00:10:00,340 step, step through each of my lines of code? 207 00:10:00,340 --> 00:10:04,450 So it turns out that to the left of the line numbers here in VS Code-- and this 208 00:10:04,450 --> 00:10:07,000 is a popular approach in other programs as well. 209 00:10:07,000 --> 00:10:09,940 Notice if you hover over to the left of a line number, 210 00:10:09,940 --> 00:10:13,570 it becomes a grayed out form of red. 211 00:10:13,570 --> 00:10:16,060 And if you click on it once, it becomes really red. 212 00:10:16,060 --> 00:10:17,980 And what that indicates is that I've set one 213 00:10:17,980 --> 00:10:19,660 of these things called a breakpoint. 214 00:10:19,660 --> 00:10:23,860 I've indicated to VS code, in this case, that I want it to break, 215 00:10:23,860 --> 00:10:28,060 that is pause execution of my code just before main is called. 216 00:10:28,060 --> 00:10:30,972 And I can actually set it on almost any of these lines of code. 217 00:10:30,972 --> 00:10:33,430 But I'm starting at the very bottom one because, of course, 218 00:10:33,430 --> 00:10:35,805 that's the line of code that we know is going to kick off 219 00:10:35,805 --> 00:10:37,633 the whole process of running my code. 220 00:10:37,633 --> 00:10:39,550 But it's going to allow me, therefore, to step 221 00:10:39,550 --> 00:10:42,610 through any and all of the specific lines therein. 222 00:10:42,610 --> 00:10:43,960 So let's go ahead and do this. 223 00:10:43,960 --> 00:10:48,010 But now, I'm not going to go ahead and just run python of mario.py. 224 00:10:48,010 --> 00:10:49,780 I need to actually run the debugger. 225 00:10:49,780 --> 00:10:51,760 And the debugger in VS Code is pretty smart 226 00:10:51,760 --> 00:10:53,890 to figure out exactly what I want to run. 227 00:10:53,890 --> 00:10:56,950 And you can even configure it to be even more customized. 228 00:10:56,950 --> 00:11:01,510 I'm going to go ahead and, perhaps aptly, click on this icon here, a.k.a. 229 00:11:01,510 --> 00:11:02,470 Run and Debug. 230 00:11:02,470 --> 00:11:06,190 And it's the little Play icon with what appears to be an actual bug on it. 231 00:11:06,190 --> 00:11:09,790 And when I click that, this additional panel opens up in VS Code. 232 00:11:09,790 --> 00:11:11,920 And its a big button there. 233 00:11:11,920 --> 00:11:13,210 It's called Run and Debug. 234 00:11:13,210 --> 00:11:16,180 Now, I could follow more of the directions and customize it further. 235 00:11:16,180 --> 00:11:18,730 But I'm just going to go ahead and click Run and Debug. 236 00:11:18,730 --> 00:11:23,020 And using some default settings that I might have specified earlier too, 237 00:11:23,020 --> 00:11:28,420 it's going to run my program but pause it on this line here. 238 00:11:28,420 --> 00:11:31,960 Notice that in yellow on line 12, that's where I set the breakpoint. 239 00:11:31,960 --> 00:11:35,350 And the yellow highlight of line 12 means that line of code 240 00:11:35,350 --> 00:11:36,700 has not yet executed. 241 00:11:36,700 --> 00:11:39,880 But it's about to be executed if and when I am ready. 242 00:11:39,880 --> 00:11:43,480 There's a bit of noise, or messy output, in my terminal window potentially. 243 00:11:43,480 --> 00:11:46,510 But that's just part of the debugging process in my terminal window. 244 00:11:46,510 --> 00:11:48,970 Eventually will I see that same prompt for height, 245 00:11:48,970 --> 00:11:52,600 but I don't yet because I'm not at that line of code. 246 00:11:52,600 --> 00:11:55,900 Now let me draw your attention to all of these icons at the top of the screen. 247 00:11:55,900 --> 00:11:59,200 The first of these, which looks like a Play button with a line 248 00:11:59,200 --> 00:12:01,570 to the left of it, is this Continue button. 249 00:12:01,570 --> 00:12:05,470 If I click that button, the breakpoint is going to be left behind. 250 00:12:05,470 --> 00:12:08,647 And my code is just going to continue on to the end of the program. 251 00:12:08,647 --> 00:12:10,480 That's probably not what I want in this case 252 00:12:10,480 --> 00:12:13,600 because I actually do want to step through it line by line. 253 00:12:13,600 --> 00:12:17,380 There's this next icon here, an arrow going over a single dot. 254 00:12:17,380 --> 00:12:19,390 That's the Step Over command. 255 00:12:19,390 --> 00:12:23,140 This would allow me to step over this line 12. 256 00:12:23,140 --> 00:12:25,240 It will execute it, but that's it. 257 00:12:25,240 --> 00:12:27,280 It's not going to step into that function 258 00:12:27,280 --> 00:12:31,000 so that I can go line by line through main or, in turn, pyramid either. 259 00:12:31,000 --> 00:12:35,290 The one I really want to use now is this one in the middle, Step Into. 260 00:12:35,290 --> 00:12:37,690 And this is the line pointing down at the dot which 261 00:12:37,690 --> 00:12:41,230 is a symbol that indicates that if I click this button in a moment, 262 00:12:41,230 --> 00:12:44,170 I'm going to step into line 12. 263 00:12:44,170 --> 00:12:47,230 That is, I'm going to step inside of the main function. 264 00:12:47,230 --> 00:12:51,790 And from there, I can continue to step-by-step walk through my code. 265 00:12:51,790 --> 00:12:54,130 So watch what happens on the yellow on the screen 266 00:12:54,130 --> 00:12:57,130 here when I click Step Into like this. 267 00:12:57,130 --> 00:13:01,120 You'll see that now line 12 has begun executing. 268 00:13:01,120 --> 00:13:04,450 But when we step into that function, notice now 269 00:13:04,450 --> 00:13:07,960 that the debugger has broken, or paused, on line two. 270 00:13:07,960 --> 00:13:10,150 Line two has not yet executed. 271 00:13:10,150 --> 00:13:13,842 But as soon as I step over this one, I think 272 00:13:13,842 --> 00:13:15,550 we're going to start to see some results. 273 00:13:15,550 --> 00:13:19,720 And I was careful there to say step over instead of step into. 274 00:13:19,720 --> 00:13:20,290 Why? 275 00:13:20,290 --> 00:13:24,490 Well, notice on this line of code two, there's two functions, input and int. 276 00:13:24,490 --> 00:13:26,440 And I didn't implement either of those. 277 00:13:26,440 --> 00:13:30,550 And allow me to propose that the people who invented Python probably 278 00:13:30,550 --> 00:13:32,800 implemented input and int correctly. 279 00:13:32,800 --> 00:13:36,010 So there's really no point in my stepping into their functions 280 00:13:36,010 --> 00:13:37,120 or even trying to. 281 00:13:37,120 --> 00:13:39,640 I really should only be stepping into my own functions. 282 00:13:39,640 --> 00:13:41,440 But I do want line two to execute. 283 00:13:41,440 --> 00:13:43,540 But let me call your attention to this. 284 00:13:43,540 --> 00:13:48,700 At the top left of VS Code now, there is, under the Run and Debug panel, 285 00:13:48,700 --> 00:13:52,000 some mention of variables, both locals and globals. 286 00:13:52,000 --> 00:13:54,100 And there's nothing under locals at the moment 287 00:13:54,100 --> 00:13:58,480 because at this moment, before line two has been executed, 288 00:13:58,480 --> 00:14:01,330 no variables actually yet exist. 289 00:14:01,330 --> 00:14:05,620 In a moment, once I do execute this line of code and step over it, 290 00:14:05,620 --> 00:14:08,110 well, a variable called height should exist. 291 00:14:08,110 --> 00:14:09,220 So let's try that. 292 00:14:09,220 --> 00:14:10,690 I'm not going to click Step Into. 293 00:14:10,690 --> 00:14:12,580 I'm going to click Step Over. 294 00:14:12,580 --> 00:14:14,740 But that will not ignore the line of code. 295 00:14:14,740 --> 00:14:17,950 It will execute it but not dive into it, if you will. 296 00:14:17,950 --> 00:14:20,380 Once I click Step Over, notice that the line 297 00:14:20,380 --> 00:14:24,220 is no longer highlighted because execution hasn't broken or paused yet. 298 00:14:24,220 --> 00:14:27,460 Notice in my terminal window, despite the output from earlier, 299 00:14:27,460 --> 00:14:29,980 I'm being prompted for the actual height of the pyramid. 300 00:14:29,980 --> 00:14:31,630 So this part is still interactive. 301 00:14:31,630 --> 00:14:33,640 Let me go ahead and type 3 and hit Enter. 302 00:14:33,640 --> 00:14:37,090 And now we'll see what's happened at the top of the screen. 303 00:14:37,090 --> 00:14:38,710 Line two has just executed. 304 00:14:38,710 --> 00:14:40,420 The height variable now exists. 305 00:14:40,420 --> 00:14:43,240 And indeed, if you look up here, you'll see in the debugger 306 00:14:43,240 --> 00:14:48,760 a graphical summary of all, or in this case, the one variable that now exists. 307 00:14:48,760 --> 00:14:51,730 And better still, you see the value of that variable. 308 00:14:51,730 --> 00:14:53,710 Now, that's not that helpful at the moment 309 00:14:53,710 --> 00:14:56,800 because I'm pretty sure the height is as the user typed in. 310 00:14:56,800 --> 00:14:59,650 So there's no off by one error or any bug there. 311 00:14:59,650 --> 00:15:03,460 I think then the bug is probably inside of my pyramid function. 312 00:15:03,460 --> 00:15:06,460 So here, I don't want to click Step Over because that's 313 00:15:06,460 --> 00:15:08,770 going to execute pyramid and not allow me a chance 314 00:15:08,770 --> 00:15:10,450 to step through each of its lines. 315 00:15:10,450 --> 00:15:15,190 I'm going to, again, this time, because it's my function, Step Into the pyramid 316 00:15:15,190 --> 00:15:15,850 function. 317 00:15:15,850 --> 00:15:18,610 Once I do that, now it's line seven that's 318 00:15:18,610 --> 00:15:21,640 highlighted because I've stepped into the pyramid function. 319 00:15:21,640 --> 00:15:24,470 Notice that the panel up here has changed. 320 00:15:24,470 --> 00:15:27,560 The local variable, that is the variables that 321 00:15:27,560 --> 00:15:31,010 exist local to the pyramid function, are indeed 322 00:15:31,010 --> 00:15:35,690 n because n was the argument that was passed in with a value of 3. 323 00:15:35,690 --> 00:15:39,620 i does not yet exist because line seven has not yet executed. 324 00:15:39,620 --> 00:15:41,300 But here comes my for loop. 325 00:15:41,300 --> 00:15:44,120 And here's where it's going to be interesting to step over and step 326 00:15:44,120 --> 00:15:45,680 over a few times. 327 00:15:45,680 --> 00:15:48,590 I don't want to step into because the range function, again, 328 00:15:48,590 --> 00:15:50,240 was invented by someone other than me. 329 00:15:50,240 --> 00:15:51,890 And let's just trust that it's correct. 330 00:15:51,890 --> 00:15:54,800 So let's step over this line, thereby executing it. 331 00:15:54,800 --> 00:15:57,740 But watch the top left-hand corner of VS Code. 332 00:15:57,740 --> 00:15:59,570 Let's step over it once. 333 00:15:59,570 --> 00:16:03,350 And now notice not only does n equal 3, now there's 334 00:16:03,350 --> 00:16:06,350 another local variable called i that equals 0. 335 00:16:06,350 --> 00:16:08,240 And what am I about to do on line eight? 336 00:16:08,240 --> 00:16:10,448 Well, in a moment, I'm going to click Step Over again 337 00:16:10,448 --> 00:16:12,490 because I'm going to trust that print is correct. 338 00:16:12,490 --> 00:16:14,060 So I don't need to step into print. 339 00:16:14,060 --> 00:16:17,630 But watch what happens now in my terminal window down here. 340 00:16:17,630 --> 00:16:20,030 No pyramid, no bricks have been printed. 341 00:16:20,030 --> 00:16:23,990 But as soon as I step over line eight, thereby executing it, 342 00:16:23,990 --> 00:16:25,730 we see the first of my-- 343 00:16:25,730 --> 00:16:27,020 wait a minute. 344 00:16:27,020 --> 00:16:28,730 I'm not seeing an actual brick. 345 00:16:28,730 --> 00:16:31,100 If you notice, the cursor did move down. 346 00:16:31,100 --> 00:16:33,410 And effectively, a blank line was printed. 347 00:16:33,410 --> 00:16:36,560 And now there's an opportunity for that light bulb again to go off. 348 00:16:36,560 --> 00:16:37,220 Wait a minute. 349 00:16:37,220 --> 00:16:38,360 I saw the cursor move. 350 00:16:38,360 --> 00:16:40,730 It printed something, but it's really nothing. 351 00:16:40,730 --> 00:16:42,050 It's no bricks. 352 00:16:42,050 --> 00:16:42,650 Oh. 353 00:16:42,650 --> 00:16:46,370 This is where now I might realize, this is why my program is flawed. 354 00:16:46,370 --> 00:16:51,110 Because when i equals 0, I'm apparently printing zero bricks. 355 00:16:51,110 --> 00:16:51,830 Aha. 356 00:16:51,830 --> 00:16:53,960 Now hopefully I understand. 357 00:16:53,960 --> 00:16:55,310 If not, no big deal. 358 00:16:55,310 --> 00:16:58,760 I can continue stepping over or stepping into each of my lines of code. 359 00:16:58,760 --> 00:17:02,900 I can click the big Stop icon, or I can restart the whole process. 360 00:17:02,900 --> 00:17:05,480 Sometimes it might not be obvious the first time around. 361 00:17:05,480 --> 00:17:09,470 And sometimes you might want to unset or reset a different breakpoint 362 00:17:09,470 --> 00:17:12,650 so as to figure out what's actually going on. 363 00:17:12,650 --> 00:17:15,043 It's just part of the process of debugging. 364 00:17:15,043 --> 00:17:17,960 For now that I figured it out, I'm going to go ahead and just continue 365 00:17:17,960 --> 00:17:19,752 my program because I know that it's flawed. 366 00:17:19,752 --> 00:17:21,619 But I now know what the problem is. 367 00:17:21,619 --> 00:17:23,842 Let me go ahead and close this panel over here. 368 00:17:23,842 --> 00:17:27,050 I'm going to get rid of the breakpoint because I've now, in my mind at least, 369 00:17:27,050 --> 00:17:28,130 solved this problem. 370 00:17:28,130 --> 00:17:29,750 I'm going to clear my terminal window. 371 00:17:29,750 --> 00:17:31,910 I'm going to go in and just logically add 372 00:17:31,910 --> 00:17:36,380 what I think is the solution to this problem by doing i + 1 in parentheses 373 00:17:36,380 --> 00:17:37,010 again. 374 00:17:37,010 --> 00:17:41,375 I'm going to now run one final time mario.py with Python. 375 00:17:41,375 --> 00:17:44,240 I'm going to again type in height of 3. 376 00:17:44,240 --> 00:17:46,970 And there it is, my pyramid of height three. 377 00:17:46,970 --> 00:17:49,610 So ultimately, what are the tools in your toolkit? 378 00:17:49,610 --> 00:17:52,400 Well, certainly Print is something that you can always reach for, 379 00:17:52,400 --> 00:17:55,670 not just in Python, but so many other languages as well or some equivalent 380 00:17:55,670 --> 00:17:56,240 thereof. 381 00:17:56,240 --> 00:18:00,410 But sometimes once your programs get sufficiently complicated, sufficiently 382 00:18:00,410 --> 00:18:03,350 sophisticated, or, heck, maybe it's someone else's code 383 00:18:03,350 --> 00:18:06,380 that you yourself didn't write and, therefore, you would especially 384 00:18:06,380 --> 00:18:11,120 benefit from stepping through it line by line, stepping into functions 385 00:18:11,120 --> 00:18:14,360 of interest, a debugger, like that that comes with VS Code, 386 00:18:14,360 --> 00:18:17,860 is going to be your new best friend. 387 00:18:17,860 --> 00:18:19,000