From Test-Scratch-Wiki

Translate: - English - 中文 

A common problem for Scratcher is when a 程式 that may seem to be flawless ends up not doing what is expected, or getting highlighted in red. These are usually normal human errors and can be fixed. This is commonly known as "debugging" which originated when Grace Hopper in the early 20th Century got a bug out of her computer.

Inspecting Scripts

Inspecting a script that does not work is often not easy. Finding a problem with a script you have written is difficult because it makes sense to the writer. Often, thinking as if you are the computer will highlight the issue. For example, to find the sum of the fractions 1/2+1/3+1/4+…+1/100 one may use the following script:

變數 [n v] 設為 [100]
變數 [total v] 設為 [0]
重複直到 <(n) < (1)> 
  變數 [n v] 改變 [-1]
  變數 [total v] 改變 ((1) / (n))
end

This will not work, because on inspecting the script, we see that the "n" variable will be equal to 0 on the last iteration (loop/repeat), and will cause a zero division error.

Other issues can occur when actions do take place, but are not seen by the user. For example if a sprite is hidden or has a ghost effect of 100. A practical example is a continuation of the script above:

說出 [I have found the sum!]
說出 (total)
說出 [Wasn't that great?]

The script will just say "Wasn't that great", because the previous two actions happen in a split second, or sometimes, within a single render cycle of the evaluator. To fix these problems, you should use Single Stepping, which slows down all scripts.

Sometimes, the error is purely logical, and appears sensible only at the moment. These are often the hardest to track down, because there is no true "error". For example, accidentally inserting the wrong variable, or changing the order in subtraction will mess up a script without giving a trace. The best way to find these mistakes is to ask a friend. Walk through the entire program, block-by-block, and make sure your friend understands each step. If there is a logical mistake, he or she will probably catch it.

Preventing errors

  • The best way to prevent silly mistakes is to have neat, organized code. Order scripts by their functions or order of evaluation will help find mistakes and prevent them.
  • Leave comments wherever you had to spend time to get something to work right; this way, if it breaks again, you can refer back to what worked before. Anyone with enough experience should be able to understand your script at first glance.
  • Do not blindly copy scripts from other projects, unless that was the intention of the project. Other than moral copytheft issues, chances are the script will not work in the context of your program. To learn how to make easy, integratable tools, see 分身的进阶用法.

值的检查

If a value needs to be known in order to determine whether or not a script is functioning, there are a few ways to find it.

Using the 说出 () block. The say block can be used to constantly checking a value.

重複無限次 
  說出 (((var1) + (var2)) * (var3)) // Outputs the value of (var1 + var2) * var3
end

Updating a variable. A variable can also be updated constantly.

重複無限次 
  變數 [check v] 設為 (((var1) + (var2)) * (var3)) // Outputs the value of (var1 + var2) * var3
end

These methods can also be used to check a boolean:

重複無限次 
  說出 <碰到 [角色1 v] ?> // Will say whether or not the sprite is touching Sprite1
end

Testing Code

Testing a large, complex project is daunting, because every change can potentially wreck something.

Often, the best way is to simply run the project again and again. However, large games or animations would be painful to debug like this. Instead, you can introduce certain testing codes, which can be removed in the final release. For example, to test level 27 of a game, add a script where when "space" is pressed, the game goes to the next level.

To make sure your code remains functional, automate certain tests. For example, scripts that should return a numerical answer can be automatically tested against some built-in cases:

定義 get cube of (5) //imagine this function was implemented
如果 <<(result) = (125)> 不成立> 那麼 
  說出 [Oops!] (5) 秒
  說出 [error with input 5] (5) 秒
  停止 [全部 v]
end

定義 test CUBE with (n) expect (k) //You can even automate this block
get cube of (n)::custom
如果 <<(result) = (k)> 不成立> 那麼 
  說出 [Oops!] (2) 秒
  說出 (n) (2) 秒
  停止 [全部 v]
end

當 @greenflag 被點擊
test CUBE with (1) expect (1)::custom
test CUBE with (2) expect (8)::custom
test CUBE with (3) expect (27)::custom

Common causes of errors

Invalid operations

Main article: Script#Script Errors

Often, Scratchers write programs with a script similar to the following:

x 設為 (10)
重複無限次 
  x 改變 (-1)
  說出 ((1) / (x座標))
end

This script will cause an error after the 10th repeat of the forever block, when x = 0, as nothing can be divided by 0 in Scratch 1.4. (Division by 0 actually should return infinity, because to make any number out of 0s, you would need infinite 0s.) When this occurs, the script will be highlighted in red and the ()/() block will turn red. To counter this error, the best way would be to start with x = 10.0001 rather than 10. This way, x will never reach 0, it will hit 0.0001 and -0.9999.

Similar problems occur with square roots, logarithms, and trigonometric functions:

x 設為 (10)
重複無限次 
  x 改變 (-1)
  說出 ([sqrt v] 數值 (x 座標)) //  this will error when x = -1.
  說出 ([sqrt v] 數值 ([abs v] 數值 (x 座標))) //  this will not error as abs x is always positive.
end

Order of Commands

The most common problem for Scratchers is for the commands to be in the wrong order. For example, to make a 角色 lunge at another sprite, a Scratcher uses commands:

面朝 (45 v) 度
等待 (0.5) 秒
滑行 (2) 秒到 x: (54) y: (0)
面朝 (90 v) 度

but it does not look like the sprite is lunging.

A good solution for this problem is to just move around the commands until the script works. Ex., to make the sprite lunge, the Scratcher moves the "point in direction 90" command to right after the "wait 0.5 secs" command, thus making the sprite look like it's lunging:

面朝 (45 v) 度
等待 (0.5) 秒
面朝 (90 v) 度
滑行 (2) 秒到 x: (54) y: (0)

Timing

Another common problem for Scratchers is the timing of commands. This is often seen in 专案 that involve 2 scripts cooperating without 广播 or 变量, such as in the 示范专案 Joke. When timing is not perfect the entire project could be thrown off. But do not worry, here are some ways to solve that problem:

广播与变量

Using 广播 and variables will allow the scripts to coordinate with each other. 广播 involve 半圆形积木, so be prepared for a lot of scripts. Using variables will definitely save you scripts. If you use variables in a project like Joke, you'll probably be using the "等待直到 ()" command. Otherwise you might be using the "如果" command or possibly the "[[Zho:重复直到 ()(积木)|重复直到" command. Either way, the scripts will be more accurately coordinated.

Careful Timing

If you really do not want to use 广播 or variables you could just adjust the amount of time between commands. Use the "等待 () 秒" command. This would be easy for a project like Joke but not for a complicated 游戏类专案. Other methods recommended.

Repeated Process

This method is mainly for very complicated games. To make an accurate detection you might want to repeat a test for a few times before activating a reaction. It may be unnoticeable but it takes a small amount of time to run a command. If you repeat a test command, it will give the detection a little bit longer to change itself. You can see this by downloading this project.

Timer

You may also make commands revolving around the 计时器. Scratch's timer can be reset and manipulated, so you can do a lot with it.

Incompatibility

The third and least common reason for scripts not to work would be that the commands just do not work with each other. When this happens, the script will be highlighted in red. The sprite is "stumped". When this is the case there really isn't anything to do about it except to rebuild the script completely, with a different approach.

當 @greenflag 被點擊
說出 [hello] (2) 秒
如果 <visible?> 那麼 
  說出 [I see you] (1) 秒
end

相关积木

Main article: Obsolete Blocks

When using older versions of Scratch, you may find 积木 labeled "obsolete!". These are usually blocks in the newer versions of Scratch, and are not compatible with older versions. Using these blocks in the older versions will often cause the script to fail.

In 2.0:

當 @greenflag 被點擊
分身 [自己 v] 建立
計時器重置

In 1.4:

當 @greenflag 被點擊
obsolete!
計時器重置

Blocks like "say nothing" are hidden in Scratch 1.4, but will not cause a script error.