Debug in Scratch —— Part 2

Scratch 少儿编程 916浏览 0评论

友情提示:视频教程观看时请手动设置清晰度。

Debug in Scratch —— Part 2

  

     尽管Scratch不像Python、Java有专门的异常处理方式,但是我们可以充分发挥人的主观能动性,自己发现、自己总结方法来对程序进行调试、排错。

本文将继续介绍在Scratch中调试程序的方法。Part 1 传送门 《Debug in Scratch —— Part 1》


 

5、延时法

 

通过【等待()秒】积木给程序添加延时。由于循环执行速度比较快,可以把【等待()秒】放在循环中,降低程序运行速度,方便定位BUG出现的时机。

 

【等待()秒】还有一种用法,就是用来处理程序无序并发执行时引发的BUG,参见《控制Scratch异步代码的执行顺序》。

 

优势:

①方便灵活

 

劣势:

①准确度较差,不一定能精准排错,还需要结合别的方法来排查程序错误。

②时间不可控,若时间设置得较短,可能还没检查完就开始执行后续程序了,设置得较长又浪费时间。

6、断点法

代码在Scratch中实现打断点的功能。

 

Debug in Scratch —— Part 2

打断点

程序将会正常执行,至断点处停下,按下空格并抬起后继续执行,类似Python调试窗口中“step”按钮的效果,不同之处是会运行至下一个断点处。

 

—— 参考文献:《Python 真好玩 教孩子学编程》  作者:刘凤飞 ——

 

Debug in Scratch —— Part 2

断点效果

优势:

①可控性。程序执行速度较快,单处代码往往一闪而过,来不及检查或做更多的调试工作。程序执行到断点处会停下并等待用户操作,用户可以进行调试,若无误则按空格确认,继续执行程序。

②灵活性,哪里可能有问题,断点就打在哪里,可以逐行检查。

劣势:

①只是一种辅助排查方法,还需要结合其他方法来进行Debug.

 

7、黑盒测试法

“数据代入,逐行分析,这是最万能的调试思路,要有足够的耐心。”

这种方法其实一般人都会使用,常见到甚至没有意识到自己正在使用。仔细一想,好像也可以算是一种方法、一种套路,简单,但管用。

其实这种方法在数学上也经常会使用,用一个常量代替等式中的变量,计算结果是否相等。在编程时,简单地代入一个常量,然后逐行地心算执行结果,最后就能检验出整段代码的逻辑是否正确。尽管这是一种充分但不一定必要的情况(p事件可以推导出q事件,但q事件不一定能推导出p事件),但是实际使用时确实是十分方便。由于不需要了解程序内部逻辑,只需要关注输入和输出的结果,因此我把这种方法称之为黑盒测试法。到这里,数学老师一定会想要提醒他的学生。是的,在编程中,也要,且更要注意一些特殊值,具体来说就是、0、负数、浮点数、边界值以及不合法的数据类型。

 

优势:

① 简单、方便、直接,不需要考虑内部逻辑,可以看做程序调试过程中的“第一道工序”,是一种布尔型的检测方法,即,它可以且可以告知使用者,这段程序是否有错误。

劣势

①局限性,仅可以得知是否有错误,错误出在哪里不得而知,必须配合其他方法深入内部进一步排查。

②在测试时需要注意,是否已经将所有可能的特殊值都考虑周全了。

 

8、克隆体脚本

 

初学者在使用克隆功能时往往会出现很多BUG,且难以解决,究其根本,还是因为克隆体的一些局部的参数、行为是使用者无法直接看到的。比如在一个普通角色中出现BUG,你都可以用本篇以及上一篇中的各种方法进行调试。但是克隆,你连克隆体的脚本都看不到,谈何调试?如果是角色,可以勾选【x坐标】积木前的单选框,在舞台中直接观察角色x坐标的实时变化,但是x坐标是局部属性,在外部是无法直接访问克隆体的局部属性的。且克隆体都是临时存在的。

在这里介绍一种能直接看到克隆体代码、直接访问克隆体局部属性的方法,这种方法也是我偶然才发现的。

访问方法:和一般角色一样,在舞台中双击克隆体,就能将当前的编辑对象切换成所点击的克隆体

 

Debug in Scratch —— Part 2

访问克隆体代码

(提示:当角色区的蓝色边框在角色上时,表明当前编辑对象是这个角色,当蓝色边框在舞台背景区上时,表明当前编辑对象是舞台,边框既不在角色也不再舞台背景区上时,表明当前编辑对象是某个克隆体)

 

更改克隆体中的代码其实是不可取的,因为每个克隆体的代码都是和本体绑定的,始终保持一致,修改任一克隆体的代码都会使本体代码发生变化。我们只能十分小心地、运行个别积木、代码块,或者是打开其局部属性的显示器进行调试。不过这样就足够了。

 

Debug in Scratch —— Part 2

克隆体代码调试

克隆体代码的特性

① 每个克隆体的积木和本体都是时刻绑定的,在任一克隆体对代码进行增、删、改,本体和其他克隆体都会发生同样的改变,反之亦然。

②不同克隆体的显示器可以同时显示

③注释没有被绑定,本体可以有本体的注释,克隆体可以有克隆体的注释,且注释内容可以不一样。在使用这个方法调试时可以通过添加注释来识别克隆体,以免因对象选择错误而出错。

优势:

①是唯一一种可以直接访问克隆体的脚本和局部属性的方法

劣势:

①容易因对象选择错误而出错

②是一种辅助调试方法,在切换到克隆体后,还需要结合其他方法进行调试。

 

题外话

基于克隆体的特性①,现在对克隆体也应该有一个全新的认识了,也就不难解释克隆体很多奇怪的行为了,如指数级克隆产生的原因。克隆体其实就是一个临时的角色,每个克隆体都有自己的代码,只不过是复制本体的。试想一下,本体中有一个【当接收到()】积木,克隆体中自然也会有一个【当接收到()】积木,而【当接收到()】积木的作用就是使当前对象接收消息,那么克隆体凭什么不能接收消息呢?每个克隆体都接收消息,初学者在使用克隆时自然容易出BUG咯。【当接收到()】积木如此,【当按下()键】是如此,事件模块中的其他积木亦是如此。那么【当绿旗被点击】呢?都说了人家是临时角色,点击绿旗的瞬间,程序重启,旧克隆体全部删除,新的克隆体还没产生,怎么会受影响?至于【当作为克隆体产生】这个积木,现在看来,它的作用不是让克隆体做什么事,而是让本体不要做某些事,充其量就是个标记变量“isClone”罢了。

    如何?看到这里是否对克隆有了全新的认识?

 

9、那些随着版本更迭被遗弃的调试方法

 

①Scratch 2.0的显示消息的发送者和接收者功能

Scratch2.0中可以右击消息积木块,选择显示消息的接收者或是发送者

 

Debug in Scratch —— Part 2

消息积木右击菜单

Debug in Scratch —— Part 2

利用消息的接收者和发送者功能排错

 

显示消息的发送者和接收者这个功能是非常实用的。消息决定了程序的执行顺序,决定了程序的流程走向,作为程序的阅读者,必须要理清程序的流程。在大型程序中,无数多的角色,无数多的消息,手动去逐个角色点击、逐段代码寻找消息接收者/发送者无疑是一件很恐怖的工作,这时候一键显示接收者或发送者就至关重要了。这大大简化了程序阅读时的困难。

然而在Scratch3.0中,这个功能已经被取消了,不知道是临时的还是永久的,也不知道是scratch team技术受限还是有更好的替代方式?反正至少我是不希望在Scratch3.0中阅读别人的大型程序的。期待st能推出这个在我看来必不可少的功能,也期待有更精致的UI.

 

②Scratch 1.4的单步执行模式

 

对于初学者来说,程序的执行过程是比较抽象而难以理解的。在 Scratch 1.4中有这样一个功能,能放慢并且显示程序的执行过程。

Debug in Scratch —— Part 2

Scratch1.4的单步执行功能

 

来看一下那令新版本用户嫉妒的效果

Debug in Scratch —— Part 2

Scratch 1.4的单步执行功能

无需太多的言语,【广播()并等待】积木的作用是不是一目了然?还是希望在3.0未来的版本中单步执行功能可以返场吧。

9.5、公众号信息

Debug in Scratch —— Part 2

10、拆解法

 

将某段代码逐层拆分,逐个检查,直至找到错误。

Debug in Scratch —— Part 2

将小数保留指定位数的程序出现BUG

下面来看一下利用拆解法排查BUG的完整过程

 

Debug

至于BUG产生的原因,之前有一篇文章已经专门分析过了,想补课的同学可以点击传送门《每个Scratcher都应该知道的浮点运算》。

优势:

①可以准确地知道每一个的执行结果。

 

劣势:

①对使用者的要求较高,使用者思路需要十分清晰,在使用时需要清楚地知道自己在做什么,自己想要知道什么,这么做能得到什么,是否会有别的干扰因素等等。

代码比较复杂时可能会导致……拆完后拼不回去了,所以使用者一定要思路清晰,最好是截个图做个备份。

思维方式:

这是一种自顶向下,再自底向上分析问题的方式,也可以说是从整体到部分,再从部分到整体的思维方式。

 

哲学与编程:

举个生活中的例子吧,手机充电时,发现电充不进(整体)这时候换个充电口,如果可以正常充电了,说明是刚才的充电口有问题(部分),只要更换插线板就可以了;如果还是无法充电,这时候可以向别人借一个充电器(头),如果可以正常充电了,说明问题出在充电器上,只要换个充电器就可以了;如果还是无法充电,那再把别人那根充电线也借来,如果可以正常充电,说明问题出在你的充电线上,只需要换根充电线就可以了。如果还是无法充电,这时候借用别人的手机来充电,如果充进了……说明你得修手机了……至于到底是手机电板坏了,还是哪里坏了,一般人就无法确定了,得送到手机店去维修(底层代码)。

 

“整体和部分是辩证统一的,整体居于主导地位,统率着部分,具有部分不具备的功能,部分离不开整体,要求我们树立全局观念,立足整体,统筹全局,实现最优目标。整体由部分组成,部分制约整体,关键部分的功能及其变化甚至对整体的功能起决定作用。要求我们重视部分的作用,搞好局部,用局部的发展推动整体的发展。”

 

哲学指导生产活动(包括编程),编程也体现了哲学思想。在编程中形成的思维方式也可以指导生活(如上文中的手机充电)。联系是普遍的,哲学、编程与生活存在着一种微妙的联系……

转自公众号:
Scratch格物堂

您必须 登录 才能发表评论!