S9G3 小学进退位计数器
这次以小学的进退位计数器为例,来展示用脚本按钮来控制进位器的数珠的变化。主要使用 SetValue 与 If 来控制算珠的加减与进退位。除了脚本指令,最重要的是问题拆解的思维,让我们用数学语言来描述现象。

一、将数字转化为数珠串

说明:这节主要建立位值列表 ns={1,7,2,9} , 并且将这转为数字 n 。同时用序列来绘制四堆数珠 nns 。
操作
ns = {1,7,2,9}
ds = {1000,100,10,1}
n = sum(ns*ds)
# 利用双层序列来绘制数珠 nss。
nss=Sequence(Sequence(Circle((2*d,k-0.5),0.5),k,1,ns(d)),d,1,4)
# ls 水平线
ls=Sequence(Segment((0,k),(10,k)),k,0,30,5)
二、制作加减按钮

说明:这节主要新增 +- 按钮来用脚本控制每一串数珠的变化。
在个位 + 的脚本为 SetValue(ns, ns+{0,0,0,1}) ,这是用 SetValue 来改变 ns 的值。其中 ns+{0,0,0,1} 为让个位加 1。

而 - 按钮的脚本要留意,其值不可为负。以千位的 - 脚本为例: SetValue(ns, If(ns(1)>0,ns+{-1,0,0,0},ns)) 。通过 If 判断千位至少大于 0 时,才能对千位减 1。

步骤:
SetValue(ns, ns+{0,0,0,1}) # 个位的『+ 』脚本
SetValue(ns, ns+{0,0,1,0}) # 十位的『+ 』脚本
SetValue(ns, ns+{0,1,0,0}) # 百位的『+ 』脚本
SetValue(ns, ns+{1,0,0,0}) # 千位的『+ 』脚本
SetValue(ns, If(ns(4)>0,ns+{0,0,0,-1},ns)) # 个位的『-』脚本
SetValue(ns, If(ns(3)>0,ns+{0,0,-1,0},ns)) # 十位的『+ 』脚本
SetValue(ns, If(ns(2)>0,ns+{0,-1,0,0},ns)) # 百位的『+ 』脚本
SetValue(ns, If(ns(1)>0,ns+{-1,0,0,0},ns)) # 千位的『+ 』脚本
三、制作进位退位按钮

说明:这节主要新增进退位按钮来用脚本控制每一串数珠的变化。
以个位的进位为例,通过 SetValue(ns, ns+{0,0,+1,-10}) 可将个位少 10,十位多 1,来达到进位的效果。但要确保个位至少有 10 个数珠,才能满十进一。因此,进位脚本要加入 If 判断 SetValue(ns, If(ns(4)>9,ns+{0,0,+1,-10},ns)) 。
而退位的脚本也是类似,需要检查至少有一可退位。以千位的退位为例,通过SetValue(ns, If(ns(1)>0,ns+{-1,+10,0,0},ns)) 。

步骤:
SetValue(ns, If(ns(4)>9,ns+{0,0,+1,-10},ns)) # 个位的进位脚本
SetValue(ns, If(ns(3)>9,ns+{0,+1,-10,0},ns)) # 十位的进位脚本
SetValue(ns, If(ns(2)>9,ns+{+1,-10,0,0},ns)) # 百位的进位脚本
SetValue(ns, If(ns(3)>0,ns+{0,0,-1,+10},ns)) # 十位的退位脚本
SetValue(ns, If(ns(2)>0,ns+{0,-1,+10,0},ns)) # 百位的退位脚本
SetValue(ns, If(ns(1)>0,ns+{-1,+10,0,0},ns)) # 千位的退位脚本
四、绘制进位退位框

说明:为了让进退位时,显示数珠的改变。加入序列 nds 来显示这 10 个进位的小圆圈。而bcs 的位置利用 bdx,bdy 来记录,并用 nd = 1,2,3,4 来切换每位的脚本。但这个进退位的 bcs 不是一直都处于显示状态,所以需要一个真假值 backFlag 来切换其显示。

以百位退位为例,在百位退位按下后。先设定 nd=2, 并用 If( ns(nd)>0, ... , ...) 检查是后可退位。若可退位,则将 backFlag 设定为 True。并同时设定 bdx = nd+1,bdy = ns(nd+1)-9。来设定 nds 的位置。其中 nds 表示十个红色小圈,其指令为 nds=Sequence( Circle( (2*ndx,k-0.5),0.5) , k, ndy,ndy+9) .

以百位的进位为例,先设定 nd 为 2,接着检查是否有满十才能进一。若有的话,再设定 backFlag 为真。并且设定 ndx 为 nd,而 ndy 为 ns(nd)-9。来显示将要进位的 10 个小红圈。

接着再设定重置按钮与数值 n ,并将 +,- 的按钮加入 backFlag 为 False 的设定就可完成这进退位计数器。

步骤:
# 设定红色小圈 nds 序列的相关参数
ndx = Slider(1,4,1)
ndy = slider(1,30,1)
nds=Sequence( Circle( (2*ndx,k-0.5),0.5) , k, ndy, ndy+9) .
nd = Slider(1,4,1)
# 退位脚本(以百位为例 )
SetValue(nd,2)
SetValue(backFlag,If(ns(nd)>0,True,False))
SetValue(ndx,nd+1)
SetValue(ndy,ns(nd+1)+1)
SetValue(ns,If(ns(nd)>0,ns+{0,-1,+10,0},ns))
# 进位脚本(以百位为例 )
Setvalue(nd,2)
SetValue(backFlag,If(ns(nd)>9,True,False))
SetValue(ndx,nd)
SetValue(ndy,ns(nd)-9)
SetValue(ns,If(ns(nd)>9,ns+{1,-10,0,0},ns))
# + 脚本(以百位为例 )
SetValue(ns, ns+{0,1,0,0}) # 千位的『+ 』脚本
SetValue(backFlag,False))
# - 脚本(以百位为例 )
SetValue(ns, If(ns(2)>0,ns+{0,-1,0,0},ns)) # 个位的『-』脚本
SetValue(backFlag,False))
# 重置脚本
SetValue(backFlag,False))
SetValue(ns,{0,0,0,0}))
小结
此节的脚本指令较多,最想和大家分享的是问题拆解的思维。对于每个操作显示,都要拆解为按钮来触发位值的改变。
在写脚本时,要留意程式触发的条件限制。例如,退位、进位时,要留意是否有足够的数字可以进退位的转化。
在显示进退位的红色小圈时,关键在于能拆解为描述红圈的位置。
本节主要的脚本就是 setValue 与 If 的搭配使用,最重要的还是在练习用数学语言来描述现象,让电脑可理解我们要它执行的操作。
相关链接
【GGB】https://www.geogebra.org/classic/xtjr8wzj
【Bili】https://www.bilibili.com/video/bv1xv41177Qk
【youtube】https://www.youtube.com/playlist?list=PLXH05kw-i_5Im8iCK_hHB86v9e5E5Ewl2