WEBVTT

0
00:00.560 --> 00:06.170
Now, before you start getting really committed to print and start making friendship bracelets for this

1
00:06.170 --> 00:12.470
print statement, there's another tool that I really want to talk about, and it's a tool that's bigger,

2
00:12.470 --> 00:14.540
it's fancier, it's more complex.

3
00:14.540 --> 00:15.860
So what is it?

4
00:15.860 --> 00:17.060
It's a debugger.

5
00:17.420 --> 00:20.060
And we've already seen debuggers a little bit.

6
00:20.270 --> 00:23.150
So I've already shown you pythontutor.com,

7
00:23.150 --> 00:28.280
and you've also seen us use the debugger in the Thonny editor right here.

8
00:28.280 --> 00:37.770
Now in the starting code, we have a function called mutate() that takes a list as the input and then

9
00:37.770 --> 00:40.440
prints another list at the end.

10
00:40.530 --> 00:48.480
So what happens is we start out with this b_list being an empty list, and we have a new_item that starts

11
00:48.480 --> 00:49.860
out being 0.

12
00:49.860 --> 00:57.300
Then we loop through each of the items in the a_list that comes in through the input, and we multiply

13
00:57.300 --> 01:01.860
it by 2 and turn that into the new_item.

14
01:02.040 --> 01:10.380
And then we modify the new_item even further by adding to it a random number between 1 and 3.

15
01:10.530 --> 01:19.580
Finally, we use a function called add() in our Maths Module, which we created right here,

16
01:19.580 --> 01:26.000
and it does the simple thing that you created before, which is just to add one number to another.

17
01:26.000 --> 01:32.840
So we add the new_item that we've got up to now to the item that we're currently looping through,

18
01:32.840 --> 01:35.870
and finally we add it all to our b_list,

19
01:35.870 --> 01:44.290
and hopefully, we are able to modify the a_list with this step-by-step approach to end up with a new

20
01:44.290 --> 01:49.450
list where each of the numbers is modified according to our rules.

21
01:50.200 --> 01:54.640
Now, unfortunately, at the moment it does not do what we expect it to do,

22
01:54.640 --> 01:58.060
it just prints out a single number in our list.

23
01:58.060 --> 02:04.600
So in order to debug and figure out what is wrong with our code to be able to fix it, we're going to

24
02:04.600 --> 02:08.030
cover how to use the debugger in PyCharm.

25
02:08.240 --> 02:16.910
Now, debuggers are pretty similar in most of these Intelligent Development Environments such as PyCharm.

26
02:16.910 --> 02:22.550
So I'm going to use this opportunity to show you a lot of things that will be reusable, even if later

27
02:22.550 --> 02:26.330
on down the line you choose to use a different code editor.

28
02:26.600 --> 02:31.760
Now what we do first is we can define what's called a breakpoint.

29
02:31.760 --> 02:35.870
So a breakpoint can be created in the gutter of our code.

30
02:35.870 --> 02:38.300
And you might have done it accidentally before.

31
02:38.300 --> 02:44.150
So when I hover over these line numbers in the gutter, you can see this red dot appears.

32
02:44.150 --> 02:51.350
And if I decide to go on to line nine and click on that red dot, I've now created a breakpoint and

33
02:51.350 --> 02:55.250
you can see that breaking line is now highlighted.

34
02:55.320 --> 03:01.890
So now I'm going to go into the debug run mode by clicking on this little bug here,

35
03:01.890 --> 03:05.160
and it's going to run my current file,

36
03:05.160 --> 03:11.220
and it's going to take into account the fact that now I have a defined breakpoint.

37
03:11.250 --> 03:12.810
So what is a breakpoint do.

38
03:12.840 --> 03:18.960
Well it basically puts a break on the code at that particular line.

39
03:19.150 --> 03:29.290
So here is where I'm setting the new_item from 0 to a new value, which is the value of the item

40
03:29.290 --> 03:30.940
multiplied by 2.

41
03:30.970 --> 03:36.700
Now you'll see a couple of things show up already in line in our code, which is kind of helpful.

42
03:36.700 --> 03:44.500
It's showing us at this point, where the code is at, where we've stopped the code on Line 9,

43
03:44.500 --> 03:52.360
the current value of a_list is this, this big list which we inputted right here.

44
03:52.360 --> 03:55.420
So this is the input for this function,

45
03:55.420 --> 03:57.310
and that's showing up right there.

46
03:57.310 --> 04:00.850
And then it's showing us b_list is still an empty list,

47
04:00.850 --> 04:02.680
new_item is 0.

48
04:02.680 --> 04:10.700
An item which is the first item in the a_list that we're looping through right here is equal to 1.

49
04:10.940 --> 04:18.890
So now what we can do is use the first of the step buttons in the debug console.

50
04:18.920 --> 04:25.820
So if I click on this one which is called, Step Over, what it's going to do is it's going to execute

51
04:25.820 --> 04:30.860
my code line by line, stopping at the very next line.

52
04:30.890 --> 04:38.300
So now that we've executed this line, which we've broken, it's now happened,

53
04:38.300 --> 04:47.000
and we can see that what's updated is the new_item is no longer equal to 0, but it's now equal to

54
04:47.000 --> 04:54.020
2, because we took the item which is one, multiplied it by 2, and then set it equal to new_item.

55
04:54.020 --> 04:57.390
So new item is now equal to 2 instead of 0.

56
04:57.390 --> 05:01.170
So we can continue stepping over to the next line,

57
05:01.170 --> 05:06.240
and remember that the highlighted line is the one that's going to be executed next,

58
05:06.240 --> 05:10.260
and the line above it is the one that just got executed.

59
05:10.260 --> 05:15.390
So right now we can see that this Line 10 has just been executed,

60
05:15.390 --> 05:25.840
and we've generated a random integer between 1 and 3, and we've added that number to our new_item.

61
05:25.870 --> 05:29.980
So now our new_item is equal to 5.

62
05:30.070 --> 05:33.850
So while we're here we can do something else,

63
05:34.660 --> 05:38.050
we can look at another one of these buttons.

64
05:38.050 --> 05:46.690
So if I go ahead and rerun my debugger and I use instead of the Step Over button, I click on the Step

65
05:46.690 --> 05:54.910
Into button, so it's going to continue executing each line as it goes, line by line,

66
05:54.910 --> 06:01.810
but when it encounters a line such as Line 10 where we're using another module,

67
06:01.810 --> 06:09.970
so code in another file, such as this randint() function from the Random Module, when I click Step Into,

68
06:09.980 --> 06:18.950
it's going to go into the definition of that function, the randint() function in the Random Module from

69
06:18.950 --> 06:25.490
random.py, which is built in to Python, and it's going to show you how that function works.

70
06:25.490 --> 06:30.950
So in fact the randint() actually uses another function called randrange().

71
06:30.950 --> 06:38.150
And if I continue stepping into it it will go and find this function randrange() and show me how that

72
06:38.150 --> 06:39.320
function works.

73
06:39.320 --> 06:46.280
Now once you're done exploring this, which can be really helpful because your code relies on code that's

74
06:46.280 --> 06:48.230
been written by other people,

75
06:48.230 --> 06:53.840
and if you want to know how they've defined it, how they've created randrange(), then you can read

76
06:53.840 --> 06:54.800
through their code.

77
06:54.800 --> 07:00.390
And sometimes it can provide helpful hints for us to figure out what is wrong with our code.

78
07:00.510 --> 07:06.420
Now, you don't want to continue stepping through other people's code, so when you want to exit, you

79
07:06.450 --> 07:12.990
click on this button, which is Step Out and we can continue stepping out until we get back to the code

80
07:12.990 --> 07:14.460
that we want to examine.

81
07:15.330 --> 07:20.280
So this can be really helpful where we're stepping through the functions,

82
07:20.280 --> 07:27.420
but more often than not we don't actually want to step into the library functions such as random because

83
07:27.420 --> 07:30.780
they work the way they do and we can't really modify it.

84
07:30.780 --> 07:34.920
So we probably haven't made a mistake there.

85
07:35.010 --> 07:41.610
And what we want to do sometimes, though, is we want to be able to step into code that is in other

86
07:41.610 --> 07:46.050
files, but only the code that is written by us,

87
07:46.050 --> 07:50.500
and we want to ignore these library functions written by the Python team.

88
07:50.500 --> 07:52.180
So how can we do that?

89
07:52.180 --> 07:54.490
Well, let's repeat from the beginning.

90
07:54.490 --> 08:00.340
So this button restarts our debug run and again pauses on our breakpoint.

91
08:00.340 --> 08:07.420
Instead of using this Step Into button, we're going to use the Step Into My Code button, which does

92
08:07.420 --> 08:13.540
exactly the same thing as step into going line by line, but it ignores the library functions.

93
08:13.540 --> 08:19.960
For example, that random() function right there, it doesn't take you over to the random.py file.

94
08:19.960 --> 08:28.540
But now if I click into step into this current Line 11, then it takes me into this file that I created,

95
08:28.540 --> 08:32.650
math.py, where I created this function called add().

96
08:32.770 --> 08:40.070
And it shows me that right now I'm trying to add 4 to 2, which was passed over from the previous function

97
08:40.070 --> 08:40.610
call.

98
08:40.610 --> 08:48.320
And if I step out of that add() function in the Math Module, I can go back to examine my file.

99
08:48.800 --> 08:54.230
So this button can be more useful when we have multi file projects,

100
08:54.230 --> 09:00.480
and we're trying to examine the cause and the relationship of what could be going wrong in our code.

101
09:00.480 --> 09:06.180
Because very often as our code gets more and more complex, there's more and more relations that start

102
09:06.180 --> 09:07.020
happening.

103
09:07.020 --> 09:13.800
And we're sometimes using code that's been defined elsewhere, and chasing it around can be quite difficult.

104
09:14.100 --> 09:19.020
So those are some of the most important features of the debugger.

105
09:19.020 --> 09:21.930
And I want you to take a look

106
09:21.930 --> 09:28.170
also down here, we've got two tabs here, the threads and variables and the console.

107
09:28.170 --> 09:33.960
So the threads and variables can be really helpful, showing us the values of the variables that we've

108
09:33.960 --> 09:35.040
got going on.

109
09:35.040 --> 09:41.490
So for example, just as they've shown up here as these comments, you can also see them in the list

110
09:41.490 --> 09:42.150
right here.

111
09:42.150 --> 09:47.130
What's the current value of new_item at this particular time point?

112
09:47.130 --> 09:51.370
What is the current value of b_list at this particular time point?

113
09:51.370 --> 09:59.590
And as you can see that as I continue stepping through my code line by line, these values, they update

114
09:59.590 --> 10:02.680
as they get changed in the code.

115
10:02.680 --> 10:08.800
So we can actually trace what's happening to each of our variables in their intermediate stages.

116
10:08.800 --> 10:12.880
And especially for something like a for loop where everything is pretty much hidden,

117
10:12.880 --> 10:15.520
we don't know what's going on while it's looping.

118
10:15.520 --> 10:20.530
This can be really, really helpful to help us figure out what's wrong with our code.

119
10:20.890 --> 10:23.830
So the other tab here is the console.

120
10:23.830 --> 10:30.400
And you can see that it shows what gets printed during the run of the code.

121
10:30.400 --> 10:34.720
So for example, if I was to get rid of this breakpoint,

122
10:34.720 --> 10:41.960
so I can either disable it by clicking it once and it goes into this darker color, or I can keep it

123
10:41.960 --> 10:45.110
there and simply say mute breakpoints.

124
10:45.320 --> 10:52.850
Now if we continue running through our code and stepping it through, you'll see that eventually it

125
10:52.850 --> 10:56.450
ends the loop and goes to the print.

126
10:56.450 --> 10:59.390
And we can see that print happening in the console.

127
10:59.390 --> 11:03.800
So we get our console even when we're running in debug mode as well.

128
11:03.890 --> 11:09.260
So that's pretty much all there is to it, to the major features of a debugger.

129
11:09.260 --> 11:18.380
The most useful thing, I think, is just simply being able to see these values show up as you go through

130
11:18.380 --> 11:21.500
the code, stepping through each of the lines.

131
11:22.430 --> 11:29.490
So now it's your turn to use what you've learned about the PyCharm debugger and figure out what is wrong

132
11:29.490 --> 11:30.540
with our code.

133
11:30.540 --> 11:39.030
Why is it not printing out an entire list with 123456 items?

134
11:39.030 --> 11:44.880
And instead, why is it only modifying and printing out the first item in the list?

135
11:44.880 --> 11:48.960
So pause the video and complete this challenge.

136
11:56.230 --> 11:56.740
All right.

137
11:56.740 --> 12:01.480
So with our breakpoint in its current position let's do another debug run.

138
12:01.600 --> 12:10.000
And we are going to watch the value of the b_list and see if it's changing the way we expect it to.

139
12:10.030 --> 12:16.930
So as I step over each of these lines and we're looping through the list, one thing you'll notice is

140
12:16.930 --> 12:20.770
that the value of b_list is not changing at all.

141
12:20.770 --> 12:27.250
So at which point does it actually get populated with these new items?

142
12:27.250 --> 12:29.320
Well, it's on line 12.

143
12:29.320 --> 12:34.120
So let's disable this and put our breakpoint here instead.

144
12:34.120 --> 12:39.650
Let's go ahead and resume our program until it runs to this point.

145
12:39.650 --> 12:43.010
And we can see that b_list is still empty,

146
12:43.010 --> 12:47.180
and all that's happening is we're appending new_item.

147
12:47.180 --> 12:51.680
So new_item is currently equal to 42 as we can see here.

148
12:51.680 --> 12:58.370
And if I step over this line to execute it, you can see that 42 gets added to the b_list,

149
12:58.370 --> 13:06.710
and then if I step over once more you'll see that print statement execute and that 42 gets printed.

150
13:06.710 --> 13:10.370
And then that's the end of our code.

151
13:10.370 --> 13:18.020
So what's happening is that these new items are not being added to the b_list as they're created.

152
13:18.020 --> 13:22.730
So the only thing we need to do is just to add an indent.

153
13:22.730 --> 13:29.670
And so often my Python code fails because of an indent, or because of something silly like that, but

154
13:29.670 --> 13:34.260
with the debugger, it makes it a lot easier to figure out what is the problem.

155
13:34.260 --> 13:42.450
So if we do another debug run and you watch how this b_list changes now, every time we loop through the

156
13:42.450 --> 13:51.000
list, once we get to the end of it, that new_item gets added to the b_list, and you can see it's

157
13:51.000 --> 13:54.390
adding a new_item each time the loop runs.

158
13:54.390 --> 13:57.660
And that is what we expect to happen.

159
13:57.900 --> 14:00.840
So a debugger can be really useful.

160
14:00.840 --> 14:07.380
It's almost like you've put a print statement on all the variables in your code, and you can isolate

161
14:07.380 --> 14:11.670
a particular time point to see what each of the values are.

162
14:11.700 --> 14:17.520
And as we become even more experienced, we're going to be using the debugger more and more.