当数学遇上编程,所有的边界都打破了

本文为作者原创,欢迎分享,若需转载请联系微信(ddupxyz),谢谢!

用此文向尊敬的 Seymour Papert(西摩.派珀特)致敬!作为一名教育家、数学家和人工智能专家,Papert 在他 30 年前的著作《因计算机而强大》中就已经不可思议地把通过编程去学习的本质讲得非常清楚了!


上面这句话源自 1995 年的纪录片《乔布斯:遗失的访谈》(Steve Jobs: The Lost Interview)中对乔布斯的采访。

很多地方,尤其是各类编程机构都在引用乔布斯这句话,作为宣传用语,但很少见到有人真正从实践上去解读或印证这句话背后的意义:编程教会我们如何思考!

我们在创业做青少年编程教育之初,也用了一句类似的话作为我们的教学理念:

Learn to code, but code to learn
学习编程,更是通过编程去学习。

通过这五六年的教学实践,对这句话的理解也更加深刻了,希望接下来通过一系列文章和大家分享一下我们对 「通过编程去学习」 的看法和实践,也算是对编程教会我们如何思考这个命题的回应。


这是第一篇,聊一聊编程与数学的关系:学编程,更是通过编程去学数学。文章比较长,我会尽可能通过一些示例把这个话题讲清楚,聊透。

注:下面的内容中,涉及到具体案例,都是通过 Scratch3 来演示的,Scratch3 是由麻省理工学院媒体实验室专为孩子设计的图形化编程语言,利用可拖拽的积木块来代替键盘输入的纯代码指令,让写程序更像搭积木,孩子们可以创建自己的互动游戏、故事和动画,非常适合孩子编程入门学习。

数学遇上编程,是件非常美妙的事情,下面这幅简单的示意图呈现了编程对数学带来的帮助,实际上,这种帮助是相互的,两者相遇,无论是对于编程学习,还是数学学习都有非常好的促进作用。

我下面的文章内容,也会按照图中的几个模块展开讨论。

一、培养数感

在数学课标中,明确要求:教师在教学中要培养学生的数感,并且数感排在数学素养 10 个核心概念的首位。可见数感培养的重要性。

那如何培养数感呢?有生活中有很多种方法,而一旦有了编程,数的应用无处不在,对数感的培养完全是潜移默化的。

1. 数的表示

数字的意义,在小学刚开始学数字时,最常见的一种方式便是物与数的对应,1 个苹果、 2 个梨子、10 个人。

在 Scratch 编程的世界里,数字往往与角色相关,它所表示的意义更加丰富、直观。比如说,90 这个数字,在不同的场景下,可以代表完全不一样的含义。

  • 移动 90 步
  • 90% 的比例大小
  • 也可以是指 90 度方向
  • 也可以是旋转 90 度角
  • 还可以表示一种接近透明的状态
  • ......

在运用编程去创造的过程中,数字不仅仅是抽象的数字,更是表示了一种非常具体的状态,可以说,编程对于数感的培养不仅更有趣,而且在潜移默化中让我们对数的理解更加深刻。

2. 数的估算

在解决实际问题的过程中,数量的大小往往并不是精确的,也不需要精确,这时候就需要我们去估一估、算一算,在估算中,内化数感。

比如说,我们有一堂课是要完成下面这个开心农场的作品,完成效果如下图所示:

在空旷的农场放养一些鸡,鸡是通过 Scratch 中的克隆功能生成,正常情况下,鸡活动的范围应该是房屋右侧面的空地,它不会跑到房子上去,也不会跑到后面山上去(不符合常理),我们编程实现的过程就自然需要对位置范围进行估算。

这里的估算很有意思,要完成估算,有两个前提条件:

  • 一个是要理解 Scratch 中舞台大小及位置如何表示
  • 一个是要知道在 Scratch 中如何去估算位置范围

如下图所示,黄色的坐标轴显示了在 Scratch 中舞台的大小与位置定位;而绿色的框则是我们大概标识出来鸡的活动范围。

对坐标的表示稍微熟悉后,我们可以尝试估算了,拖动角色(这里的母鸡)到绿框的边角,通过角色的属性观察去得到一个大致的估算范围(x 与 y 的值)。

实际上,在开心农场这个作品中,还有好几个地方都需要用到估算,比如说,克隆多少只鸡出来合适?鸡离我们的远近会有一定的透视比例缩放,大概缩放多少合适?

在我们带孩子学习编程、创作作品的过程中,有太多的地方都需要孩子们有一定的估算能力,坦克大战游戏中坦克炮管的攻击范围、气球升空时的移动速度、贪吃蛇进阶时需要增大的比例,等等。

数无处不在,有数的地方,就有运算、有比较、有估算,何愁对数感的培养不会好!

3. 对大数的感受

在计算机出现之前,对大数的认识,尤其对于孩子,大都停留在想像之中,并没有一个实际的对比感受,毕竟在生活中大部分人都很少有机会去接触到超大数的应用场景。

而有了计算机后,我们完全可以利用编程去模拟对大数的运算,也很容易通过数字的变化过程来感受大数究竟有多大。

下面是一个我们在课堂中经常会讲到的经典折纸问题

首先鼓励孩子们拿出一张普通的 A4 纸去折一折,看他们能将这张纸对折多少次?大家尝试过后,通常只能对折七八次。从而引出这样一个问题:

如果有一张无限大的这样的白纸,将它对折 20 次,它会变得有多厚呢?如果对折 30 次呢?

在课堂中问这个问题的时候,孩子们的回答五花八门,从大部分孩子的回答情况来看,一般都不会很厚,大概也就几十厘米吧,不太会超过一人高。

有了计算机和编程,这个问题我们完全可以通过一段非常简短的程序模拟出来。

通过查阅,知道一张普通白纸的厚度大概为 0.1 毫米左右,如果用米作单位也就是 0.0001 米,写出的程序如下图所示。

可以看到,当对折 23 次后,厚度就达到了 838.86 米,竟然超过了目前世界的最高楼:位于迪拜,总共 828 米的哈利法塔,这是大家完全想像不到的!

惊讶之余,引出另一个问题,再让大家猜一猜,我们对折多少次后,纸的厚度就可以超过世界最高峰珠穆朗玛峰的高度(8848 米)呢?

再编写一段程序,经过测试,只需要对折 27 次,纸的厚度就已经有 13421.7728 米了,远远超过珠穆朗玛峰的 8848 米了。

而在实际生活中,我们没办法找到这么大的纸,就算有这样的纸,用人力去完成这样的对折也不太可能,但只要你懂一点编程,写一段上面的程序并不是一件困难的事情,我们带着二三年级的孩子学习,完成这段程序也是一点都没问题的。

实际上,每对折一次,纸张的层数翻倍,纸张的厚度也要翻倍,而且这个厚度会随着对折的次数增加得很快!很快我们就没办法继续对折了。对于稍大年龄的孩子,我们还会告诉他们,这其实是数学中的一种指数增长效应,而指数增长是非常快的。

2011 年,一位美国的中学老师 James Tanton 带着他的学生在麻省理工学院的无尽走㾿(infinite corridor)用超过 16 公里的厕所卷纸做了对折的实验,最终成功对折了 13 次,下图是他们当时参与对折的人员合影。

有趣的是,这位 James Tanton 老师,正是我非常喜欢的爆炸点的发明人,这里还有我写的两篇关于爆炸点的介绍:

  1. 花 15 分钟,重新认识数的表示与运算
  2. 爆炸点系列-负数的引入及运算

二、感受几何与空间

通过编程去帮助理解几何与空间,这是最适合不过的了,大家或多或少都听过或看过不少这方面的例子。下面我们一起再来看看~

1. 坐标与位置

当我们利用编程去完成一些作品时,所有我们能在舞台上看见的东西,都是有一定的空间位置关系的。

最简单的,我们要将一个角色放到舞台中央,就需要知道 舞台中央 这个位置如何去表示?

这个位置的表示其实就是数学中的坐标,不过我们不会去强调坐标这个抽象的数学概念,而是通过移动和变换角色的位置去体验 xy 这一组数的变化,从而更深刻的去理解这组数与角色位置之间的对应关系。

根据实践经验,孩子在编程创作的过程中,对这种对应关系会越来越熟悉,到后面坐标就只是一个名称而以,他们甚至不觉得这是一个抽象的数学概念,这正是编程带来的非凡作用!当孩子以后在数学课程中学习到坐标概念时,应该会非常亲切,脑袋中闪现出来都是一些具体的场景和例子,一点也不会觉得抽象。

2. 运动与方向

在知名的袋鼠数学思维挑战竞赛(Math Kangaroo)中出现过这样一道数学思维挑战题:

对于小学低龄段的孩子来说,尽管他们辨别左右没问题,但要在运动的过程中去判断转弯方向,还是有点难度,因为需要他们将自己代入小猫的角色,而且每次是否左转或右转都取决去当前的位置与方向。

如果我们通过编程去完成,在编写代码的过程中,很自然的就会把自己代入小猫这个角色,这样的过程可以很好的帮助孩子去理解运动与方向的概念。

下图是我们在 Scratch3 让小猫去完成的同样路线,左转和右转不再是靠想像,而是实实在在把自己代入小猫这个角色,通过左转和右转指令去控制小猫前行。

甚至你可以发现,最终小猫是面朝下的,如果不转弯,它会一直朝下前行。

程序写完,只要效果达到,至于右转多少次,左转多少次,看程序就一目了然了。

3. 几何图形与特点

众所周知,通过编程去画图是非常有助于理解数学中的几何图形及其特性的。在 Scratch3 中,我们可通过画笔模块去绘制各种几何图形。

动态的多边形绘制,是我们经常在课堂中使用的一个例子,整个过程从简单到复杂,逐步演进。

  • 绘制基本的线段
  • 绘制正方形
  • 绘制三角形
  • 绘制五边
  • 绘制多边形

要正确的绘制出这些几何图形,从数学的角度来看,关键点在于要清楚要绘制的多边形的边数与每次旋转角度之间的关系。

这个关系在中学阶段是有公式去计算,但在小学阶段,我们不知道公式,怎么办呢?可以通过尝试  → 修正  → 再尝试  → 再修正 这样的迭代过程去一步步逼近最终效果。先尝试画正方形,再画三角形,再画五边形 ……

从我们的教学实践数据来看,通过试错,大部分孩子是完全可以理解重复次数与旋转角度之前的关系的

重复次数(边数) x 旋转角度 = 360 度

实际上,在传统的学校教育中,这样的内容要在小学高年级甚至中学阶段才会接触到。而通过编程,左转、右转,90°、60°、360° 这些概念对于二三年级的孩子来说也没有任何难度,旋转方向与角度在他们的头脑中的印象,比一些中学生还来得深刻。

三、呈现规律与模式

在很多方面,数学 - 特别是有关空间、运动和重复行为的数学 - 是非常适合儿童的。
-- 西摩.佩珀特

重复本质上就是规律与模式,而规律与模式是编程与数学中的一个非常核心的共同主题,规律与模式也是体现数学与编程之美的核心所在。

1. 循环与乘法

我们从数学中最简单的乘法运算来看,大家都知道:乘法就是重复的加法。乘法其实就是加法的一种简便运算

如:5x3 = 3+3+3+3+3,也就是 5 个 3 相加。

其实,如果用编程来理解,可以更加深刻,下面是一段刚学 Scratch 编程的孩子就能写出来的程序。

每次走 3 步,一共重复执行 5 次,一共也就是走了 5 x 3 = 15 步,这不就是乘法吗。

这里的重复执行积木块内部,还可以添加其它代码。比如说,我希望每移动 3 步停 2 秒钟,就可以这样。

本质上就是走 3 步,停 2 秒,这个组合动作一共重复了 5 次。

如果简化并抽象成数学符号表达,应该就是:5 x (3 + 2),也就等于 25,不过这里因为 3 代表的是步数,2 代表的是秒数,所以不能直接加起来。

在这里,编程为抽象的数学符号和概念找到了一种非常好的应用表达方式。本质上他们是可以互换的,理解了一点,不仅有助于我们编程学习,更有助于我们的数学学习。

2. 几何图形与循环

一个数学的头脑,最显著的特色不是逻辑,而是美感。
-- 《因计算机而强大》

在前面的几何与空间小节,我们利用编程去绘制了各种几何图形,通过编程,可以很好的帮助我们去理解图形、角度和旋转。

在前面创建的几何图形基础上,如果再以不同的方式让它们重复起来,一种特别的美便呈现出来了。

仅仅调整重复次数和旋转度数,效果就很不一样了,这是一种由数学带来的秩序之美、法则之美,而且这种美通过编程以直观的方式呈现在我们眼前,这种感觉是非常棒的!

下面左右两幅图案唯一的差别是循环的次数和旋转角度的不同

配合上变量,封闭的多边形就变成了下面的直角螺旋线,旋转的角度再稍微变化一点,出来的螺旋线图意想不到的漂亮哦!

当然,几何图形并不限于上面这种规整的、常见的一些图形,下面这样的图形是不是也直接就可以看到一种重复的规则之美呢!

以前我们读书的时候,要画几何圆形,需要借助直尺、三角板和圆规,而现在我们有了编程,我们就是拥有了一只真正的魔法画笔,只要你的想像力够,什么几何图形都不在话下!

四、帮助理解数学概念

任何一门学科,在孩子的任何发展阶段,都能以某种智识上诚实的方式,有效地教授给任何孩子。
-- 杰罗姆.布鲁纳(Jerome Bruner)

在传统学校教育中,知识就像一个管道一样,整整齐齐,规规矩矩按顺序排好,按步就班的输送给孩子。

在大量的教学实践中,越来越能体会到布鲁纳这句话的价值所在。

至少,好一些数学概念在学校里还没有涉及到,但在我们的教学实践中,孩子是完全可以理解的,这些概念在他们的脑袋中已经有了具体而真实的使用经验,当他真正在学校里再去学习这些抽象概念的时候,那种任督二脉被打通的感觉是非常棒的。

我们选取几个比较典型的例子来看看。

1. 组合

没有材料,也没有激励,孩子只能被迫以抽象的和摸索的方式来处理。
-- 《因计算机而强大》

在《因计算机而强大》一书中,Papert 提到一个组合实验,给孩子们若干彩色的珠子,让他们来对这些珠子进行所有可能的色彩组合。不可思议的是,在进入五六年级之前,大多数孩子都没办法系统地、准确地完成这个操作。

Papert 提到,问题出在我们文化的本质,而对于经常接触计算机和编程的孩子来说,找出珠子组合其实就是编写一个简单的嵌套循环程序:首先选出一种颜色,再挑选出所有可能的第二种颜色,然后重复执行这个过程,直到所有可能的第一种颜色全都选过一次。

我们用一个类似的,大家更熟悉的小学奥数例子: “鸡兔同笼” ,来看看用编程手段去解决和理解组合问题是多么简单。

这里我们就不细讲各种 “鸡兔同笼” 解法了,后面在讲人脑与机器脑的不同思考方式时还会讲到这一点。

很少人会把 “鸡兔同笼” 看作一个组合问题,其实如果我们把问题换一种说法,大家就明白了,有 35 个头,有 94 条腿,请问将这些头和腿组合起来,刚好有多少只鸡,多少只兔呢?

用编程去解决,思路也很简单,我们从 35 个头中选一个出来,假设它是鸡,那剩下就全是兔了,然后把它们所有的脚算一遍,看是不是刚好有 94 条腿,如果是的话就结束。如果不是的话,就从 35 个头中选两个出来,假设它们是鸡,依次类推 ...... 直到找到的组合刚好是满足 94 条腿。

组合问题本质上是一个枚举问题,简单的组合问题可以通过列表来完成,但对于数量比较大的组合问题,通过编程中的嵌套循环去解决是再合适不过了。

2. 微分

微积分对于大多人来说,那都是高中甚至大学的课程,甚至读了大学的很多人至今也没弄懂过。怎么会在小孩子的数学内容中出现呢?小孩子能懂吗?我们直接通过例子在体会一下。

前面在通过编程去画多边形时,大家可能已经发现了,随着我们的边数越来越多,整个多边形的形状已经开始慢慢接近圆形了。

实际上,当我把重复的次数(也就是多边形的边数)设置为 60 的时候,画出图形已经差不多是一个圆形了。

很神奇吧,实际上它仍然是一个多边形,只不过当多边形的边数越来越多时,每次甲虫转的角度也越来越小,我们从视觉上看到的就是一个圆了。

同样的,我们前面见过的直角螺旋线图,将重复次数变多,旋转角度变小,线就会越变越光滑,最后就演变成下图右侧这样像蚊香一样的圆形螺旋线了。

如果觉得还不够,再做些改变,把数学中经典的斐波那契数列用图形呈现出来,下面是呈现的过程:

如上图所示,半透明的白色线条是由边长为斐波那契数列的数字组成的正方形,而亮黄色曲线则是将边长和旋转的角度作了改变后(边数变大,旋转角度变小),最终形成的斐波那契螺旋曲线,又叫做黄金螺旋线,非常漂亮!

其实微分的本质是从有限到无限,而传统的学校教育手段,无限这个概念很难去传达,因此很难理解,而通过编程,这一切变得非常简单了,略过复杂的概念与符号,所有抽象的知识被赋予了具体的形态,没有去学微积分,但实实在在触碰到了微积分的本质,从学习的角度来看,这一点刚好是非常重要的。

五、思考如何思考

计算机提供了一种非常具象的、实实在在的、特别的思考方式,它让我们更容易理解“思考方式”究竟是怎么一回事。
-- 西摩.派珀特

本质上,计算机和人脑的思考方式是不一样的,在通过编程去学习的过程,你会慢慢体会到这种差别。学习编程也有助于孩子去思考关于思考的问题,学习关于学习的问题

1. 调试策略

在传统的学习中,孩子学习遇到阻碍,他们往往被告之的一种学习模式是:要么他 “是正确的”,要么他 “做错了” 。

而当他们开始编程时,很快就会发现程序几乎不可能一次性就写对,而要成为编写程序的高手,就要不断培养他们发现问题及解决问题(修正错误)的能力。

计算机给我们提供了一个足够容错的试验环境,在这个环境中,鼓励尝试与犯错,通过不断迭代来优化。

实际上,从刚开始学习编程,我们就希望告诉孩子,你们解决问题所编写的程序可能并不是完美的,甚至程序中含有 Bug(错误)也是正常的,我们的需要做的就是不断地清晰描述自己的策略,并有意识地不断改善它们。

调试策略对于孩子的学习成长也有帮助,可以让他们意识到,做一件事不可能一开始就是完美的,而是会有一个不断改进、不断优化的过程,这也可以培养孩子一种积极的、渐进式成长的态度

2. 不同的思考方式

让孩子有机会选择自己的思考方式,实际上是训练他们选择思考方式的能力。
--- 西摩.派珀特

从小到大的学校学习过程中,我们其实很少去思考我们是如何思考的这件事情。

而运用编程去解决问题,它会迫使我们去解构思考的各个环节,去思考机器是如何思考的,自然地,也会帮助我们去认识到人脑与机器脑思考的差别。

来看一个我们在真实课堂中的教学例子:累加求和。

当我们在课堂问到一个这样的数学问题:

求:1+2+3+ ... +100 = ?

大部分同学都听过天才数学家高斯的故事,首尾相加的和再除以项数的一半,甚至有些同学不假思索就可以回答出:5050 。

甚至有同学更厉害,直接给出了求和公式:

好吧,这是标准的、纯粹的数学解答方式。

接下来我们让孩子们用编程的方式来解决同样的问题:

给一个数,求从 1 加到这个数的总和?

该怎么来写这个程序呢?

① 人的思考方式

很多同学很自然的写出了下面这样的程序。

程序很简单,运行结果也没问题。但我们会告诉孩子,这样写当然没什么问题,但这是人脑的思考方式,并不是机器脑的思考方式。

人很聪明,所以会总结出像上面这样的数学公式;而机器脑很笨,看起来只会一些非常简单的计算,但它的厉害之处在于,它比人脑计算得更快,计算的量更大,它可以一秒钟内就完成成千上万次这样的简单计算,这一点人脑就远远赶不上了。

② 机器的思考方式

我们来看看机器脑怎么去解决这个问题,非常简单,一个一个加呗。

尽管这个程序比较长,理解起来却很简单,就是从 1 开始,一个一个加到结果中去,循环完成后,结果就是我们最终得到的数字之和。

程序很听话,而且运算速度很快,哪怕你输入一个 10000,它也会立刻帮你计算出来从 1 加到 10000 的结果。

③ 融合思考法

有没有既能利用人脑的特点,也充分利用机器的特点,把两者的优势结合起来的方式呢?当然有。

假如我们用符号 sum(n) 表示从 1 加到 n 的和,求 sum(n),我们只需要知道 sum(n-1) 就行了,因为我们可以用 sum(n-1) 来表示出 sum(n)

sum(n) = sum(n-1) + n

这是一种数学上的表达式,要求 sum(n),只需要知道 sum(n-1),要求 sum(n-1),只需要知道 sum(n-2) 就行了,一直往下,最终只需要知道 sum(1) 就行了,而 sum(1) = 1,问题就解决了。

这种方法在数学中被叫做归纳法,一般要到高中才学。而在编程中有个特别的名称:递归,两者本质上是相同的。

递归的方法其实好理解,但用人脑去计算其实不太方便,而编程刚好特别适合这种重复、有规律的计算方式。

上面求和的问题如果在编程中用递归来解决,代码如下图所示:

同一个问题,三种解法,代表了三种完全不同的思考方式。计算机编程的「魔力」给我们提供了一种强有力的工具,让孩子可以去选择自己的思考方式,实际上也是在训练他们选择思考方式的能力


六、与数学课标的关系

教育部在 2022 年 4 月印发了最新版的义务教育课程标准,其中数学课标里有一段对小学阶段和中学阶段的数学核心素养作了很精彩的说明。

小学阶段侧重对经验的感悟,初中阶段侧重对概念的理解。

小学阶段,核心素养主要表现为:数感、量感、符号意识、运算能力、几何直观、空间观念、推理意识、数据意识、模型意识、应用意识、创新意识

中学阶段,核心素养主要表现为:抽象能力、运算能力、几何直观、空间观念、推理能力、数据观念、模型观念、应用意识、创新意识

如果对应上面对编程与数学关系的描述及示例呈现,可以发现,将数学与编程结合,可以非常好的覆盖对课标中核心素养的培养,可以说,有了编程的助力,数学学习就像插上了翅膀,不仅可以飞得更快,还可以飞得更高。


七、学编程还是学数学?

为了践行 **「学编程,更是通过编程去学习」**的教学理念,我们还专门开设了 当数学遇上编程 这门课,很多家长看到后经常会有这样的疑问:那孩子到底是在学编程还是学数学呢?会不会搞得四不象,结果数学和编程都没学到?

有这个担忧是正常的,希望我上面的长篇赘述已经解决了你的大部分疑问。

打个总结,如果简单来回答这个问题,那就是:

我们既是在学习编程,更是在通过编程在学习数学,两者是相互促进的。

如果较真一点,我会说,其实这个问题本身就有问题!任何一门学科都不是孤立的,只是在现代学校教育体制下,为了便于教学才有了分科,越分越细后,不同的科目也越离越远了,实际上学科之间应该,也是可以相互融合,相互促进的,我们要把不同学科当做一个有机的整体来看。

计算机编程为我们提供了一种丰富的文化环境,在这种环境下,每个学科都可以得到更多滋养,生长得更好。尤其数学、物理、艺术这些学科,后面我还会通过更多的文章去聊如何通过编程去学习这些学科的教学实践。

八、参考资料

  1. 《因计算机而强大》,作者 Seymour Papert(西摩.派珀特),特别推荐
  2. 《乔布斯:遗失的访谈》,一份 1995 年对乔布斯的访谈,非常珍贵,当时他还没重返苹果,从访谈中可以看这位苹果创始人的思想与远见
  3. 花 15 分钟,重新认识数的表示与运算,一篇介绍 Exploding Dots 的文章
  4. 在几何图形与循环部分引用了一张实物拼图,源自 Hana Murray 的推特

关于通过编程去学习这个话题,如果你有更多有趣的话题想要交流或分享,也欢迎联系我,聊一聊,期待有更多深入的讨论!

本文章也会保持持续更新~ 欢迎大家关注!

如果有孩子想要上「当数学遇上编程」这门课,或想了解更多详情,都可以通过下面的微信联系我!