钟范东
● 问题提出
集合思想是数学的基本思想之一,即把一类事物看成一个总体。数学学科将集合概念作为高一学生学习数学的起点。随着《普通高中信息技术课程标准(2017年版)》的颁布及新教材的实施,计算思维在教学中得到极大重视。在Python编程中也有集合的概念,能否借助数学学习集合概念的有利时机,在编程教学过程中渗透集合思想,从而为培养学生的计算思维打开一条新的通道呢?
● 问题分析
在义务教育阶段,不论是数学还是信息技术,都侧重于对单个数据的处理过程。而在高中数学教学中,学生一开始就学习集合的规范写法,以及集合的性质、集合的运算。随着集合思想的进一步形成和完善,从集合角度思考问题是学生高中阶段有别于初中阶段的思维方式之一。
要从编程学习中让学生形成集合思想,就要先分析集合思想在计算机解决问题的一般过程中如何发挥作用,然后有针对性地调整教学内容和设计教学方案,采用适当的教学策略来培养集合思想。
在高中阶段的编程教学中,提高学生分析问题的思维能力的目标切合当前的教育目标:在分析问题时用上集合相关概念,在设计算法、编写程序的过程中用集合的方法,在运行调试阶段获得成功体验,引导学生将集合思想应用于解决新问题上。在编程技术的教学中,如果有目的地挑选编程语言中集合的相关知识,有针对性地训练使用集合方法设计算法的能力,指导学生进行设计算法、编写程序、运行调试三个步骤的配合,让学生在分析问题中逐渐形成集合思想,则能为在编程教育中培养学生的计算思维打开一条新通道。
● 设计教学方案
Python语言的知识范围虽然很广,但涉及集合的内容是有限的。以思维培养为导向,可以先从编程符号、概念、语法、运行调试等方面进行精心设计,再从知识和能力两方面助力学习者快速形成集合思想。数学的集合与Python语言中的集合还是略有区别的,下面简略地列举为编程学习而设计的内容。
1.基本编程符号
一般运算符号:+、-、*、/;特殊运算符:**、//、%、&、|;容器符号:()、[]、{}、""、'';关系运算符:>、<、>=、<=、==、!=、in;逻辑运算符:and、or、not;函数:len()、sum()、max()、min()、int()、str()等。
2.集合相关代码
字符串、range(n,m)等构造集合的重要来源。
集合元素的枚举:for x in A表示每次从集合A里取出一个元素装入变量x。
归属判断:用判断连接符号连接两个对象,如x in A和x not in A,判断元素x是否属于集合A。
集合元素的筛选:if<判断>,判断有两种情况,即成立与不成立,不成立时放弃该元素。
3.集合构造语法
对于集合的描述法,对照数学和Python代码如下页图1所示。
集合的构造语法:集合数据常用{}构造,如A={元素区 for区 if区}。
其中,元素区只能写成一个元素的形式,可用常量、变量或表达式。当有多个值时,可用()合成一个元素,各值之间用逗号隔开;for区:当集合内部涉及一个或多个变量时,必须为每一个变量写一次for…in…,指明每个变量的取值范围;if区:可写一个或多个判断。每个判断不仅可以比较两个对象,还可判断单个对象的有无内容(如if a表示判断a是否为非零值或非空集、非空列表等)。集合的构造语法在一个语句中就包括了循环for和判断if这两种编程的基本结构,因此用这种方法写代码显得很简洁。
4.集合例题与练习题目的设计
程序的编制和调试能力养成训练需要和知识学习融合进行。编写和调试程序是解决问题的实施阶段,是对所设计的算法的确认。设计例题与练习题必须通盘考虑计算机解决问题的一般过程,循序渐进。下面是训练形成集合思想的部分例子。
例1:构造集合A并用Python描述法表示。该集合的元素是20~30之间能被3整除的自然数。
>>> A={x for x in range(20,31) if x%3==0}
该题构造集合的方法與数学集合相似,能让学生了解range();对照比较数学与代码的集合写法,得到的结果是{24, 27, 21, 30},也可体现集合的无序性。
例2:输出1~100的自然数中是7的倍数的数(如图2)。初中学生未学过集合,一般要写出四个语句的程序。尝试用集合的方式改编此程序。
>>> A={x for x in range(1,101) if x%7==0}
该题能让学生了解集合描述法与一般程序结构的不同之处。
可进一步用函数print()将括号的内容显示到计算机的屏幕,这可以看成是计算机的动作。计算机的动作也可当成集合的元素,为拓展学生对集合的理解,出示代码如下:
>>> A={print("能被7整除的数:",x) for x in range(1,101) if x%7==0}
例3:小明在计算2的n次方时发现,当n>168时,计算出的结果都包含有“0123456789”十个数字。当n=168时,计算出的整数只包含九个数字,请你帮他找出这个缺少的数字。
>>> A={x for x in '0123456789' if x not in str(2**168)}
该题能让学生知道字符串也能枚举,了解str()的作用,对比数学的属于与不属于,in表示属于(元素在集合里面),not in表示不属于(元素不在集合里面)。分解执行①2**168,②str(2**168),③"0" in str(2**168),能让学生更好地理解计算机的运行能力,通过此题的学习,鼓励学生在以后的分析问题中善用集合的属于判断,敢用比较大的整数运算。
例4:某地发生一起案件,警方通过排查确定实施犯罪行为的是甲乙丙丁中的一个。这四个人的供词如下——甲:不是我。乙:是丙。丙:是丁。丁:丙在乱说。已知其中一个人说了真话,其余三个人说的是假话。请你根据已知信息判断到底是谁实施了犯罪行为?
>>> A={x for x in '甲乙丙丁' if (x!='甲')+(x=='丙')+(x=='丁')+(x!='丁')==1}
该题利用集合解决逻辑问题,能让学生知道字符串可以直接被程序处理而无需转换成数字,为判断结果参与四则运算提供示例,知道判断的结果就是0和1,能将判断直接运用到表达式中,鼓励学生在以后的分析问题中,形成用判断结果参加运算代替if语句的思维。
例5:古代数学家张丘建在《算经》一书中曾提出过著名的“百钱买百鸡”问题:鸡翁一,值钱五;鸡母一,值钱三;鸡雏三,值钱一;百钱买百鸡,则翁、母、雏各几何?翻译过来,意思是公鸡一只五块钱,母鸡一只三块钱,小鸡三只一块钱,现在要用一百块钱买一百只鸡,问公鸡、母鸡、小鸡各多少只?
>>> A=range(101) ; #说明:公鸡、母鸡、小鸡的个数都不会超过100,其他都交给列出的条件来判断了。
>>> B={(a,b,c) for a in A for b in A for c in A if a+b+c==100 and a*5+b*3+c/3==100}
該题用构造解集的方式解决问题,能让学生掌握通过分析问题确定变量初始范围的方法,知道集合里也可写多重for,知道多重for的实际枚举意义,掌握多个判断连接and的用法,当元素区有多个值时,可用()合成一个元素,各值之间用逗号隔开。
● 集合思想的扩展及意义
在Python语言中,对于集合A和B,它们的差集是A-B,交集是A&B,并集是A丨B。高中数学没有差集概念(大学才有),数学交集用∩,并集用U。由此,可以更贴切地与数学集体思想相融合。
除集合外,还有列表、元组、字典以及由zip()、enumerate()、open()等函数生成的可迭代对象。它们有一个共同的特点——都是由元素组成的,可把这些事物称之为“堆”。当集合的构造语法拓展成“堆”的构造语法后,简单地写一两行代码,就可以解决很多实际问题。笔者尝试在高中信息技术教学中引入“堆”概念,既方便了学生的理解,也能在数学集合教学的基础上,帮助学生从逐个处理数据和计算机动作,发展成从以“堆”来处理数据和计算机动作。若将数学和Python语言意义下的仅限于集合的集合思想,扩展应用到“堆”范围之上,则能为计算思维培养探索出新的方向。
苍山点题
不仅是编程教学,几乎所有的具有“可操作”的学习内容,如物理、化学实验,如音乐歌唱、美术绘画,甚至语文、外语的朗诵、演讲与写作,都需要“知行合一”。由此可见,要在编程教学中塑造更有深度的计算思维,还需要对编程的算法应用与设计创新角度的深度思维进行探索与总结。本期解码,聚焦大单元设计、跨学科学习策略,对计算思维与增量生长项目、数学集合思想等的深度融合进行了探索。
第一篇文章,作者以编程教学的项目课题研究为契机,根据落实学科核心素养的课标要求,从项目完成过程的视角分析项目类型,探究利用增量生长型项目实施大单元教学的有效方法。基于教学实践,分析增量生长项目的自身发展逻辑和生长路径,合理设计学习流程,优化教学实施过程,引导学生掌握从现实问题切换到计算机领域的科学方法,逐步培养学生的计算思维、信息意识和数字化学习能力等学科核心素养。
第二篇文章,作者在高中编程教学中,精心设计Python语言的学习内容,借助数学学习集合概念的有利时机,将数学中集合的概念与计算思维结合起来进行探索,为培养学生从逐个数据思考问题发展成以整体的“集合思想”思考问题,打开了一条新的通道。学生通过这样的编程学习,能逐渐形成集合思想的观念体系,为初步感悟大数据、机器人、人工智能等思维方式打下良好的基础。
在信息技术和信息科技课程中,如何进行计算思维的不同深度、层次的培养,如何进行人才培养的长远的规划,这些都是值得一线老师不断探索的问题,期待大家取得更多有深度的探索成果。