How to debug?
-
Introduction
Debugging is probably the most challenging process for most students. When our program “does not work”, we often feel helpless and frustrated.
However, everyone must learn how to debug, as no one can guarantee to write the correct program on the first try. In the future, where AI writes most of the code, programmers will review and debug AI-written code much more than write code themselves.
To help you get started, we will discuss how to think about the debugging process and a few techniques. After you practice these basic techniques for a while, debugging will begin to feel like a fun puzzle game.
Two Ways of Thinking: “Wrong” vs “Different”
When a program has a “bug,” new learners tend to think “This program is wrong,” and then try to find which part is wrong. However, that does not help us solve the issue because, most of the time, our program is running correctly, just not the way we expect.
Instead, we should consider it this way: The program is doing something different from my expectations. This new way of thinking will make a massive difference in debugging.
Searching for the Bug Topdown
If we think of bugs as the difference between expected and actual outcomes, then debugging is simply about locating where that difference comes from.
Sprite Level
We can usually narrow down the issue gradually, starting at the sprite level.
For example, suppose the program has 3 sprites, then we first need to decide which sprite is most likely causing the difference. For example, suppose Sprite A is supposed to broadcast a message, which triggers Sprite B to move upon receiving the message. If Sprite B is not moving, then we need to find out whether Sprite A is not sending the message out, or Sprite B is not handling the message correctly.
Stack Level
Suppose we have picked Sprite B, then we look at the stacks of blocks in that sprite. For example, if that sprite has 3 stacks of blocks, then we need to determine which stack is doing something unexpected. Suppose the top stack is for initializing variables and sprite positions, the middle stack is for handling a message, and the bottom stack is for handling key press events. Then we should probably start with the middle stack.
Block Level
After we have narrowed down our search to one stack, the next question is which specific blocks are not producing the outcome we want. For example, if the stack has 10 blocks, then we need to read through them, and determine which block is causing the difference. There can be many reasons, such as the wrong blocks being used, wrong input parameters, wrong logic, etc.
Retry
Of course, we might be wrong in anyone of these steps, and we would have to pick a new path. For example, if it turns out Sprite B is doing exactly what we want, then we would have to investigate Sprite A.
Common Search Techniques
Now that it is clear debugging is all about searching, here are a few commonly used techniques to help us in the searching process:
Logical Deduction
Most of the time, we can simply rely on logical deduction to identify bugs. Essentially, we need to ask ourselves the most likely reason for the issue. For example,- If some sprite is not visible, then it is most likely hidden or moved off the stage;
- If there is no response when we press a key, then we should focus on the code that handles key press events;
- If a sprite is moving in an unexpected direction, then we probably set the moving direction incorrectly.
This may not be easy for beginners, but with practice and experience, this will become our best tool.
Simplifying the Program
Most of the time, most blocks in a program are not related to the bug at all. So we can temporarily remove some parts of the program to narrow down the search scope. Fortunately, that’s very easy to do in Scratch, since we just need to detach some blocks.For example, suppose a stack of blocks carries out 4 tasks one by one, but we are not sure where it starts to behave differently than we expect. In this case, we can detach all the blocks except those for the first task. Now, if we run this simplified program, we can check if it is doing what we expect it to. If so, we add back the blocks for the second task, then run the program again. We can keep doing this until the difference starts to appear.
Logging
Another very commonly used technique is “logging”, which means making your program write down important information as it runs, such as the value of a variable, or which task your program is working on. This can be done using the print block in the CreatiCode playground.Logging is helpful because it helps us understand the program flow better. Most often, we will find out the issue comes from not really understanding what exactly our code is doing. Since a program runs through many blocks quickly, logging gives us a “slow motion” view of what happens.
We can answer many questions by logging, such as:
- Did that part of the program run or not run?
- What’s the value of this variable when the issue occurs?
- What’s the sequence of operations?
- How long does an operation take? (by logging timestamps)
Explaining Your Code To Another Person
If you can find another person who is willing to listen to you (such as your teacher or a classmate), you can try to explain your program to them. Explaining your code line by line can often force you to focus on what the code is actually doing instead of what you want to achieve, and you will realize the difference between them as you talk.In fact, people have found that this method is very effective even if the person you talk to doesn’t say anything, as the key is for you to hear yourself. So some people simply use a “rubber duck” (or any cute animal) as the listener, and explain the code to it.
Step-by-Step Mode
For beginners debugging a fairly small program, we recommend running the program in the step-by-step mode.
In this mode, the program will pause after running each block, so it clearly shows the workflow of the program. Also, while the program is paused, you can check the value of any variable or read the position/direction of any sprite.
Breakpoint
Another similar technique is using the breakpoint block.
In this mode, the program will run as usual until it arrives at the next breakpoint block. The program will then pause until you continue to run it. While the program is paused, you can check the value of variables and the state of the sprites. For more complex programs, this method is much faster than the step-by-step mode. You can add as many breakpoints as you like at anywhere in the program.
Debugging Example - Water Simulator
As an example, let’s discuss how to debug this project:
play.creaticode.com/projects/67166007037517b65095ef7d
- Step 1
First, let’s establish the difference between the expected and actual outcomes. When we press down the mouse pointer, we expect a new ball to be generated. However, when we try it, we don’t see that.
Next, Let’s try to narrow down the issue. There are 2 sprites, “Ball” and “Bucket”. The bucket is visible and spinning as expected, so the issue must come from the “Ball” sprite.
There are 2 stacks of blocks in the Ball sprite. The first generates new clones of itself, and the second initializes each clone. Now, it is less straightforward to determine which stack contains the issue.
- Step 2Now let’s apply some logical reasoning. Since we are not seeing new balls, there can be 2 possible reasons:
- New balls are not generated
- New balls are generated, but somehow we can’t see them.
This is a good time to use the logging tool, since it can easily tell us whether new ball sprites are indeed being generated. For example, we can add the print block like this:
Now, if we run the program again and click the mouse button a few times, we will see these messages in the console panel at the bottom of the playground:
That means the new ball sprites are being generated, but somehow, we can’t see them.
- Step 3Now, let’s dig further. What are the most likely reasons we don’t see the new clones? There are at least 3 possibilities:
- The clone is hidden
- The clone’s size is too small
- The clone’s position is outside the stage
If we add some more “print” blocks to print out the size and position of every new clone, we would be able to eliminate #2 and #3. We need to focus on why the new clone is hidden.
- Step 4At this point, we can simply re-examine the Ball sprite to check why the new clone is hidden. To make sure we don’t miss any details, we can use the “robber duck” technique. Let’s try to describe our program to a duck like this:
- When I click the green flag, I first initialize the physics engine with some gravity
- Then I broadcast the “add bucket” message, which will tell the Bucket sprite to add the bucket
- Then I hide this original Ball sprite, so no one sees it…
At this point, we would realize we are hiding the original Ball sprite at the beginning, so all its clones are hidden by default!
Therefore, the issue can be easily fixed by adding a “show” block when the clone is born:
Debugging Challenges
Below is a list of programs demonstrating commonly seen bugs in Scratch projects. You can practice debugging with them.
Problem 1
Project: play.creaticode.com/projects/67f8e7e6b3d4548bcb8c0770
Question: Why doesn’t the elephant count to 5?
Difficulty: 1Problem 2
Project: play.creaticode.com/projects/67f8ea6cb3d4548bcb8c0cf0
Question: Why does the elephant only count 1?
Difficulty: 1Problem 3
Project: play.creaticode.com/projects/67f8eb19b3d4548bcb8c0eaf
Question: Why doesn’t the marker draw a square?
Difficulty: 1Problem 4
Project: play.creaticode.com/projects/67f8efadb3d4548bcb8c143c
Question: Why doesn’t the elephant say 4?
Difficulty: 2Problem 5
Project: play.creaticode.com/projects/67f8f465b3d4548bcb8c1a40
Question: Why doesn’t the elephant turn when I press SPACE?
Difficulty: 1Problem 6
Project: play.creaticode.com/projects/67f8f546b3d4548bcb8c1b3f
Question: Why doesn’t the elephant move when I press the green flag?
Difficulty: 1Problem 7
Project: play.creaticode.com/projects/67f8f9b6b3d4548bcb8c1eea
Question: When you click the elephant at the center, why doesn’t x go up by 1?
Difficulty: 2Problem 8
Project: play.creaticode.com/projects/67f8fbc6b3d4548bcb8c20f7
Question: Why doesn’t the elephant glide right first?
Difficulty: 1Problem 9
Project: play.creaticode.com/projects/67f8fe25b3d4548bcb8c2329
Question: Why doesn’t the ball keep moving to the right?
Difficulty: 1Problem 10
Project: play.creaticode.com/projects/67f90048b3d4548bcb8c27c4
Question: When you click the elephant, why doesn’t it turn right?
Difficulty: 1Problem 11
Project: play.creaticode.com/projects/67f900d2b3d4548bcb8c2920
Question: Why doesn’t it count 10 to 1?
Difficulty: 1Problem 12
Project: play.creaticode.com/projects/67facc1401eb9f071783b6d2
Question: Click “Add Clone” 2 times. Why are 3 more elephants added?
Difficulty: 1Problem 13
Project: play.creaticode.com/projects/67facd7801eb9f071783b821
Question: Why doesn’t the elephant say the factorial of 5?
Difficulty: 2Problem 14
Project: play.creaticode.com/projects/67fb1cea25723bde92be45ac
Question: When you press W and D at the same time, why doesn’t the car face the top right direction?
Difficulty: 3Problem 15
Project: play.creaticode.com/projects/67fb27e190fe4ee2d3bf2b47
Question: When the basket touches the ball, why doesn’t the score increase by 1?
Difficulty: 3Problem 16
Project: play.creaticode.com/projects/67fb355225723bde92be4ffd
Question: Why don’t I see a continuous trail as the mouse pointer moves?
Difficulty: 3Problem 17
Project: play.creaticode.com/projects/67fbb76625723bde92be982b
Question: Why doesn’t the beachball get shot away when touching the basketball?
Difficulty: 3Problem 18
Project: play.creaticode.com/projects/67fc6adf90fe4ee2d3bfaf40
Question: Why does the game end when the player picks the correct color?
Difficulty: 3Problem 19
Project: play.creaticode.com/projects/67fc753490fe4ee2d3bfb1f6
Question: Why can’t the green dot move up or to the right?
Difficulty: 3Problem 20
Project: play.creaticode.com/projects/67ffabb3a627c734d9287241
Question: Why are the values of variables a and b not swapped?
Difficulty: 3
Debugging Challenges for 3D Projects
All programs below include some commonly seen bugs in 3D projects.
Problem 1
Project: play.creaticode.com/projects/67fada6125723bde92be279c
Question: Why no 3D box is created?
Difficulty: 1Problem 2
Project: play.creaticode.com/projects/67fb18af90fe4ee2d3bf22c3
Question: Why is only the green box created?
Difficulty: 1Problem 3
Project: play.creaticode.com/projects/67fb19f825723bde92be42f1
Question: Why doesn’t the box rotate around the center?
Difficulty: 2