0:14

In this video I'm going to talk about debugging.

People often don't like debugging and part of

that is because it can be difficult, right.

Well, [LAUGH] my response to that is then don't do it.

Alright, well, that sounds silly.

But my point here is that there are ways

in which you can make it easier on yourself, okay.

As you're writing your software, if you think

about what you're doing a little bit more carefully.

You follow the style guidelines.

You write code thoughtfully and you test this code, as you go.

You write a function, you test it.

Then you write the next function, you test it.

Then you start building up code based on other working code

instead of building up code based on unknown code, all right?

And this decreases the likelihood of bugs or, at least makes it easier to.

Find the bugs that you do introduce, because you're

look at small well written pieces of code, okay.

Now despite your best efforts you're probably

still going to have bugs in your software, okay.

So you are going to have to debug, okay.

Or, worse yet you might be given software of somebody else's that has bugs in it and

you've gotta use and you gotta deal with it

and it has bugs that you've got to find.

You can't imagine how much of Joe's code I have to debug, for instance.

Alright, so we have to debug.

Well, debugging doesn't have to be painful.

Okay, it can be interesting and fun to hunt

down these bugs, alright can be little puzzles, alright.

But the thing that you have to remember about debugging,

the simple most important thing you need, is patience, okay?

You have to be thoughtful about what you're doing, okay?

You have to think about, What am I doing right now?

What is the program supposed to be doing and what is it actually doing, okay?

And if you bring this patience to the, to

the process, and you think about what you're doing.

It can actually be a relatively painless process, or at least a systematic

process that allows you to get to the bug without a lot of frustration.

2:01

Debugging takes several steps, right?

And the first one is recognizing that a bug actually exists.

So how do you do that?

Well, you have to actually run your program, and you

have to think about what the outputs are supposed to be.

And compare them with, to the to what the outputs actually are, right?

And when they don't match, well, now you know that there's a bug, okay?

But if you skip this step and you only run your program once.

Or you don't really thoughtfully test your program,

you may never actually realize there's a bug, okay?

So this is the important first step here.

I'm recognizing that a bug exists.

Now, once you know the bug exists that's where the debugging begins, okay?

So what do I do first?

Well, I need to isolate the source of the bug.

I basically need to find out where the bug is, okay?

And so this is, you know, an important step here

where you have to think about how do I divide up

my program in to smaller and smaller pieces and how

do I figure out if those smaller pieces are working, okay?

And, one of the key elements here is that you have to come up

with these hypothesis, you have to say hey I believe this is true, okay.

And instead of just saying oh I know it's true, because I looked at

the code, and the code, it must be correct, right, you want to confirm this.

Alright, so a lot of debugging is about confirming these

hypotheses, alright, saying I know this is true, let's confirm it.

Alright so I have a little function here that I

know works, well, don't just say I know it works rather.

Run it with a bunch of different inputs, and confirm

that the outputs are exactly what you expect them to be.

Then you can rule that piece of code out as having a bug, and move on to the next.

All right, and you do the same thing you keep

coming up with these hypothesis saying, yeah, this is what I

believe to be true about this code, and then you

confirm it and then you move on to the next step.

And you do that again, and again, and again,

and eventually you are able to isolate the source.

You are able to say, heh, this function, or these, you know,

ten lines of code, or whatever, this is where the bug is okay?

3:51

Then you have to move on to the next step,

where you sort of identify the cause of the bug.

You actually figure out which line of code is really the problem, or which lines.

It doesn't necessarily have to be a single line.

Say hey, this is what is breaking my program.

This is how it's breaking my program and understanding

that, doesn't necessarily mean you know how to fix it.

But at least now, you have isolated the source

of the bug, you've identified what exactly is causing the

bug, and then you can move on to the

final stage where you actually fix the it all right?

You come up with a new way of implementing the

code so that you don't have the bug anymore all right?

If you follow these four steps, okay, then you will

end up with a more robust, better working program all right?

Now these steps are easy to say, they're much harder to do.

4:34

So here's a program I wrote to implement the game math dice, and it doesn't work.

Okay so we've already passed step one here.

We recognize that there's a bug.

So let's talk about what this program actually does.

Okay Math dice, I have five dice.

Two are 12 sided dice, three are six sided dice.

I roll the two 12 sided dice.

I multiply them together.

That's my target number, that's the number I'm trying to get.

Then I multiply the three six sided dice, and I try to put them together to

form an equation that gets me a result that is close to the target as possible.

Now use the three dice, and I can use add,

addition, subtraction, multiplication, division, or

exponentiation in between them, alright.

And I'm trying to make an equation of the form A op B op C, alright.

And, you know, A and B, A op B is

in parentheses here for the purposes of this game, okay.

So I evaluate A op B first, and then the result there, I do that result op C.

Okay?

Now, let's play alright?

Let's run this program.

And run it, okay, so it says the target is 48,

because I rolled 6 and 8 on my 2, 12 sided dice.

And then my 3, 6 sided dice; I got 5, 6 and

1, and I try to make an equation that got me close.

It says, six minus one, plus five, divided by five.

That doesn't seem like it's right because, there are

too many numbers in there right, and too many operations.

So it's not of the form A op B equals C all right?

So clearly, I have a problem.

5:59

All right, I know I have a problem, so let's try and find it.

Well, let's go down to the bottom here first to the play function.

This is actually playing the game.

Let's look at what it does.

First it rolls two 12-sided dice as the target

dice and takes their product and then it rolls three

six-sided dice as the other dice that I'm trying to

make the equation out of and that prints them out.

Let's look at these printouts.

Well, the target is 48, rolled six and an eight.

Well, that seems like that's reasonable and

the regular dice are five, six, and one.

Well, that seems like that's reasonable too.

So, I believe, that's probably okay.

Now I should actually confirm that but for the sake

of time in this video, okay, I'm going to skip that step.

But you should go off and confirm that, that's working correctly.

Next, I make a bunch of equations here, out of the dice.

All right, so I have a set of ops plus, minus, times, divided by, and power.

And the dice and I make the equation.

So first, well I know this is correct, right?

But let's print them out.

Print equations.

Okay, so, let's run this game again.

7:04

okay.

Here's the first mistake you might make, okay, trying to debug this,

now, when I have this many equations is going to take forever, okay.

I'm not going to, I can't really see, are these right, I have no idea, okay.

Well, yeah, I can kind of tell right off the bat 4 plus 4 plus 3 plus 3 equals 14,

well, that has four dice in it and I

only have three dice so, yeah, this is probably wrong.

But, the first thing I want do is, you know, sort of cut things down, okay?

And I also don't like this randomness okay?

This randomness is going to make it so that it does a different thing every time.

So, I'm going to actually change this here,

8:40

Okay, yes, now I have many fewer equations,

all right, So, now I've cut things down.

I've got repeatable behaviors here that inputs are always going to be the same.

I have fewer equations that I need to deal with, all right.

So, I have some more hope here of figuring out what's gong on, all right.

Well this print out that I've go here is not all that useful.

Let's print the length of the equations, how

many there are and for equations in equations.

Print tqn, all right.

Hopefully this now, okay, much more readable, much easier to understand.

I have eight equations all right and just for fun you know, let's put this back.

9:43

Alright, I know the equations are to big so let's see if i can figure out why.

Let's go up here to make equations.

Alright here we are making our equations, and first of all we generate all the

permutations of the dice and then we generate

all the sequences of operations that we have.

Alright, well, let's look at that.

So what are all the permutations of these dice?

Print dice

10:14

One three three one.

All that seems reasonable, right?

Okay.

If I have the dice one and three, all the

possible orderings of that is one and three, three and one.

All right, fine.

Now, let's print ops orders.

Okay, so, now I'm trying to get all the sequences of the operations.

And remember I cut this down to plus and minus to make my life a little bit easier.

Let's see that, alright.

We have plus plus, plus minus, minus plus and minus, minus.

Well that seems right, doesn't it?

11:04

Okay.

And let's scroll back up and yes.

I am getting plus, plus, plus, plus, plus, minus.

So, it is enumerating all the possibilities, all the sequences that I

can get with plus and minus but it's not the right size.

Okay?

So, I'll put this back to one and three.

11:31

Well, I look through this and, do you see the bug?

[LAUGH] Maybe, maybe not.

All right, but basically what's happening here is that I now immediately see this.

And you may not.

You may need to put print statements in here.

But again, for the sake of time, I'm going to jump to it.

I have a plus one in here that shouldn't be there.

[LAUGH] All right?

Let's run this now.

Okay, now we get plus and minus.

11:56

This seems Okay?

I have the single operator.

Okay.

The only way of doing it, if whether I have

plus or minuses, I can either adjust plus or adjust minus.

Okay.

Well, now I have got a complete, like error, down here.

okay.

Well that's because I wrote this silly string

equation, where I am going to print out the equations.

In such a way that it only works if my equation is a certain size.

Okay.

This is also a bug, right?

I should fix this.

Okay?

But let's ignore it for now, all right?

Instead let's go back to three dice and see if everything has been fixed.

12:30

Okay, so now my target looks right, my dice look right.

I got all the permutations, the sequences of operators are okay.

I now have 24 combinations.

When I look at these equations they look reasonable, all right?

And the result now though says the closest equation is 1 plus 3 plus 5 equals 9.

And let's look in the results here, 1 plus 3 plus 5 equals 9.

Is that the best I can do?

Well, yeah, it seems like it.

12:59

So we actually walked through a systematic process there to find that bug.

So I put things back now and let's see if everything works, okay?

Alright.

Now our target is 5.

We've got the Dice: 3, 6, and 6.

And 6 divided by 6 is 1 times 3 is 3.

Is that the best I can do?

Well, could be.

Alright.

Here's 42.

Now, here I'm not so convinced.

That the closest I can get to 42, with 5, 5 and 6, is 1.6.

That's clearly not true.

I could do 5 plus 5 times 6, all right?

That's 60.

That's much closer than 1.6.

All right?

Perhaps you can find something else.

Okay so, I don't think it's working yet, right?

My equations look okay now though.

So I think that I am making an equation and it's printing out

nicely 5 + 5 divided by 6 = 1.667, I think it's valued incorrectly.

So what's left here, right?

Find closest, all right.

Well, again, let's do the same thing, all right.

Let's make things consistent so I.

Don't have randomness going on here.

Six, seven, and let's make the dice almost, five, five, six.

Let's run that again just to confirm that I'm going to get the same thing.

I am.

Alright, so let's look at this find closest function.

Alright, here we are.

Find closest.

Now we want to be systematic here.

We, I, I know this works, right?

I wrote it.

Clearly, but let’s confirm how it works.

Right?

So, you can see what it does.

It, you know, sets the closest to B, infinity

and then it tries to find things that are closer.

So let’s print out what happens here.

Let’s print the equation.

Every time we find something that’s closer, let’s print it.

14:38

Okay, 16, 31.

No we're that close, we're down at 19 ha, and then we went

up to 60, then down, all right, clearly this is not working, right.

It's not getting closer and closer and closer to 42, right.

I shall only swap something in if it's actually closer

to 42, not just bouncing up and down, all right.

So, clearly something's wrong here, all right.

So, let's, let's print out some more, let's.

Trying to figure out what's actually happening

so let's print each time the equation.

15:24

which is the abs target minus equation minus 1.

Alright.

And let's print to blank line each time.

Alright.

Let's run through this.

Okay, I've got a lot of information here now.

Let's go back up.

Alright.

My equation gives me 16 and the closest is infinity.

The difference is 26.

All right.

Okay.

I've got another equation.

I got four out of the closest currently is 16 which

is the last time we saw the difference is 38 all right.

16, 16, 16 so when do we leave 16, here we go.

16 we go to 31, right because 31 was bigger, or closer to 42, rather.

Okay, now, here's the problem.

Right, right here.

Okay, our closest was 31.

We see 19, which has a difference of 23, and we take

17:08

So hopefully watching me debug this program

helped a little bit in understanding the

kinds of processes that you might go

through, to successfully debug a program right?

Remember the first step is understanding that there actually is a bug, okay?

So you do have to run and test your program,

and think about the output is it right or not?

Okay the second one is isolating the source of the bug and I sort of showed.

Hopefully by example.

A little bit of how you might go about isolating the source of the bug, okay?

You want to take the pieces of your program.

You don't want to try and figure it out, from the big giant part of your program.

Where you have big giant outputs.

You want to narrow down the inputs and the outputs, so they're much smaller.

So that you can deal with them.

You can look at them, and understand what's going on.

Then you want to look at smaller and smaller pieces of your program.

Then you want to confirm the truth.

You know that it works, you wrote it, but you need to confirm that, okay.

Because often it doesn't, right.

That's why there's a bug, okay.

So you can see that I printed some things out, I sort of looked at what I expected.

And I found out things were not the way that

I expected them, and that helped me isolate the problem.

Okay?

Once I've done that, I now can identify.

And you know, that's a little bit harder for you

to see inside my head, but looking at the code,

I can say, oh, yeah, this is the line of

code that's actually broken and here's how you fix it.

Now the bugs that were in here were relatively simple.

Your bugs might be this simple, they might not, okay?

But the process remains the same, right?

Recognize there's a bug, isolate the source of the problem,

identify what the actual problem is, and then fix it.