方 磊
(湖北文理学院 数学与统计学院,湖北 襄阳 441053)
根据2022年10月TIOBE编程社区指数(编程语言流行程度指标)可知,Python语言(17.08%)占据编程语言排行榜首位,排名超过C语言(15.21%)和Java语言(12.84%)的使用率(1)TIOBE.https://www.tiobe.com/tiobe-index/。目前,我国高校越来越多的专业将Python语言作为程序设计教学语言,一般在大学一年级开课,其中实训占一半以上学时。实践训练是Python语言程序设计教学中的主要活动。
从Python语言程序设计实践训练所涵盖知识点来看,分为单个知识点的验证性训练、多个知识点相结合的应用训练、面向小型应用系统的综合性训练等。这三类训练难度依次增大,旨在通过训练让学生深化知识理解、拓展知识范围、提升编程能力,达到编程的综合运用目的。但是,在实践中存在以下不足:1)学生能够完成单个知识点的验证性训练,一旦遇到较为复杂的问题就束手无策;2)训练涉及各个不同主题,其中有些主题的知识点较多,背景较复杂,学生付出了较多的时间精力,训练效果却不明显。3)学生往往按照老师的操作指令和训练模板开展综合性训练,最终取得的实训效果不理想。导致这些不足的主要原因在于训练主题的内在联结度小或者缺少关联性,学生对训练主题内涵、知识点把握等呈现零散状态,不能及时地将单个知识点训练内化到自己的知识结构中并完成知识体系的联结与整合。以至于学生做了较多的练习,却无法形成自己的知识体系框架,达不到知用合一的实训效果,更难以提高解决实际问题的能力。因此,如何让学生在有限的时间内由易到难、由浅入深地系统性掌握Python语言程序知识框架与设计是实训课中需要迫切解决的问题。本文基于支架式层次教学方式对Python语言程序设计实训展开必要的探讨。
支架本是建筑施工中使用的脚手架,为建筑施工提供了必要支撑。实训教学引入“支架”概念,是指为学生学习程序设计提供必要的支撑,协助学生层次渐进地建构自己的知识和经验[1]。支架式教学则是提供一种概念框架来帮助学习者逐层建构新知识的过程。为此,先要把较复杂的综合性主题分解成若干单个知识点,通过对各单个知识点的运用掌握以便把学习者的理解逐步引向深入[2]。支架可以在策略选择、问题思考、行为判断、效率提高以及如何使用工具等方面给予学习者以适当的帮助[3]。支架式教学的理论基础是“最近发展区理论”和建构主义理论。
前苏联心理学家维果茨基认为,个体的发展状态存在两种不同的水平:实际的发展水平和潜在的发展水平。实际的发展水平是个体能够独立完成学习任务的能力水平,潜在的发展水平是个体在他人的帮助下才能够完成任务的能力水平,两者之间的区域是“最近发展区”。“最近发展区”理论认为教师教学应以潜在的发展水平为目标,在学习者的最近发展区搭建学习支架、开展教学[4]。“最近发展区”在学习者成长中会被不断更新,当学习者能够独立完成先前在“最近发展区”内的任务时,那么他的实际的发展水平已经进展为一个更高的水平区域,因此教师要不断找准新的“最邻近发展区”,搭建一系列帮助学生自主建构知识的学习支架[5]。
建构主义理论的代表人物有皮亚杰、维果茨基、科恩伯格、斯滕伯格、卡茨等,建构主义理论认为认知发展受同化、顺应、平衡三个过程的影响,同化是学习者把新的信息整合到自己原有认知结构内的过程。顺应是个体的认知结构因新的信息而重构的过程。个体在不断同化和顺应的过程中建构自己的认知结构并达到与周围环境的平衡。个体的认知结构在平衡-不平衡-新平衡的过程中不断地得到提高和发展。建构主义理论强调学习是主动建构自己知识体系的过程,知识或意义是学习者在新旧知识经验之间反复的、双向的相互作用过程中建构的[6]。教学是引导学生从原有的知识经验中生长出新的知识的过程,教师是学生主动建构意义的促进者、合作者和指导者[7]。
此模式是从一个主题(问题)出发,通过基础训练、拓展训练、综合训练、探索训练逐层对实训增加新的要求,把若干知识点训练分批次纳入到整体训练系列中。基础训练用于掌握基本知识点,实现熟练写出基础代码的目标;拓展训练是在基础训练上增加新要求,扩充单个知识内容,使学生在应用中拓展知识理解、建构知识框架;综合训练将基础训练和拓展训练整合为一个较大主题,进一步实现知识结构融合;探索训练是在具备一定知识储备和实践技能之上,通过提供对其它较大主题材料的训练,达到对前三个阶段训练所掌握的设计技能的融会贯通,强化自主程序设计能力。一个主题四个层次体现出训练的阶段性区分、难度逐层增加,循序渐进地提升程序设计能力的教育思想。
一个主题是将同一个设计问题贯穿于一系列实训过程中。对教师而言,有利于建立训练示例之间的关联性;对学生而言,可以基于前面训练成果逐步添加训练内容、增加训练难度,学生在一以贯之的主题下充分地思考、内化吸收知识,建构知识框架,进入更高的训练层次,从而掌握系统化的知识和技能,形成程序设计的逻辑体系。
“素数判断”是程序设计教学中的一个知识点,在程序设计中涉及多种流程控制,涵盖一系列知识内容的编程训练项目,下面以“素数判断”为例来解析一个主题四个层次的支架式程序设计训练模式。以素数判断为例的一个主题四个层次训练如图1所示。
图1 一个主题四个层次训练演变进化图
基础训练是为学生解决较复杂问题提供基本的程序设计知识和能力支撑。学生通过训练可熟练写出较简单的程序语句,运用流程控制,将问题的解决方案用Python语言表达出来,理解程序语句的内涵及应用场景、多样化地用程序语句实现算法设计。
3.1.1 循环for语句的训练
示例1:利用for语句判断用户输入的一个正整数(>1)是否为素数,如果是则输出该数是素数。
以示例1为训练起点,通过训练,使学生独立地写出顺序、选择、循环结构的简单语句,逐步迁移到多种结构混合应用的层级,实现对程序IPO结构(输入、处理、输出)的分辨能力,理解流程控制内涵,建构程序结构基本概念、程序语句的适用规则。通过示例1的训练达到如表1所示的能力水平。
表1 示例1训练的知识及能力
3.1.2 在循环for语句基础上拓展else子句训练
示例2:利用for循环和else子句判断一个数是否是素数,并优化程序设计代码。
示例2引入知识点else子句,通过合并语句来优化代码,使代码更简洁。
示例2引发学生认识else子句应用场景,建立for循环与else子句间的关联,认识和理解循环结构、选择结构的内在逻辑及代码实现,将else子句整合到已有的循环结构、选择结构中去。
3.1.3 训练Python的while语句基于上述训练和认识,再采用while循环来判断素数,引导学生思考while循环结构中循环体、循环控制条件、循环跳出环节的程序设计。
示例3:使用while循环判断一个数是否为素数。
示例3引导学生认识for循环和while循环的程序语句的区别、循环体的区别、适用情况的区别,将标志量、while循环及循环条件的控制手段等内容扩充到学生已有的知识结构中,进一步丰富对循环结构的深入认知。
3.1.4 训练while语句、else子句及使用命令行参数以示例3为生长点,扩充else子句及命令行参数训练。用户交互方式是影响用户体验的一个因素,掌握不同的用户交互方式是程序设计的一项任务。
示例4:使用命令行参数、while循环和else子句来判断一个数是否是素数。
示例4将else子句配合while循环语句使用(示例2中else子句配合过for循环语句),帮助学生联结起else子句的两种运用,扩展对else子句的认识。同时,示例4应用命令行参数交互方式实现用户交互,增加了学生的用户交互手段。
通过围绕4个示例逐层拓展的基础训练,将各知识点逐渐扩充到程序设计语言应用中,学生采用不同的程序设计方法解决同一个问题,对循环语句进行比较运用,深化程序设计中的for循环、while循环、else子句,选择结构异同点的区别认识。因此,基础训练是通过单项程序语句的多次训练,让学生以一个设计主题为出发点,采用多种途径反复训练,从而提高程序代码的编写水平和熟练程度,强化基础问题的理解深度,渐次地拓宽加深学生知识的“最近发展区”。
经过基础训练后,学生比较熟练地运用程序设计语言解决素数问题,正确的编写代码、调试小程序,为下一步编写较复杂的程序积累了经验,为提高训练层次打下了基础,做好了铺垫。因此,依托基础训练的积累,有针对性地提高问题的复杂度,增加程序代码的编写量。
3.2.1 判断一系列数是否为素数该示例试图从判断一个数为素数拓展到对一批数为素数的判断,逐步提高问题的复杂度。
示例5:判断一个区间(例如[100,300])内的素数,输出区间内的素数及其个数。
示例5可引发学生思考:重复一个操作流程,需要怎样的流程结构和程序语句;增加循环层次的多层循环是独立的还是关联的;若有关联该会建立怎样的关联。对此,学生调动已有的经验、知识、技能并进行重组,以求解决新的问题,引导学生在已有技术知识经验的基础上建构新的知识结构。
3.2.2 用户多次判断素数直到输入退出指令示例5实现了循环判断指定区间素数的一次运行,示例6要求程序在一次运行中多次判断素数,判断次数由用户输入退出指令确定。
示例6:请用户输入一个整数(>1),判断是否为素数,直到用户输入Q或q退出指令为止。
示例6要求学生思索和解决的问题是:将运行程序的结束权交给用户随机输入退出指令,目的是增强用户在程序运行过程中的交互性,随时体现用户运行程序的意愿与要求。学生经过思考、编写代码、调试运行,认识到程序设计中充分体现交互功能的重要性,通过训练实现学生能写出强交互性程序的目标。
3.2.3 设计函数完成素数判断的程序当一段代码需要被重复执行时,将其设计为一个函数,可以实现代码的重用。示例7要求学生在具备上述能力前提下编写一个具有判断素数功能的函数。
示例7:设计一个函数实现对素数的判断,若为素数,函数的返回值为True,否则为False。
示例7的目的是拓展学生认知和学会设计函数API(application program interface)、函数体算法,正确运用函数语法规则。学生可改造示例1至示例4代码后迁移到函数内部。经此训练,使学生熟知函数名称、函数参数、函数返回值等概念,熟练写出相应的Python语言代码,掌握在不改变函数接口条件下的多种编写函数体的方法,体会函数在程序设计中的作用。
函数是模块化程序设计的基本构件,示例7为学生学习模块化程序设计做好了铺垫。
3.2.4 随机数和列表应用训练以上示例中的程序数据是由用户输入,示例8训练要求数据由计算机生成。
示例8:计算机产生20个2—100之间的随机整数保存于列表中,判断这些随机整数是素数还是合数并保存于列表中,输出这些随机数与判断结果。
示例8引导学生思考:产生特定区间内的一个随机整数;产生多个随机整数;数据保存到列表的方法;利用示例7的函数方法解决示例8的问题并用代码实现,进一步加深函数应用理解。
同时,教师可以提出更广泛的问题:随机数如何产生;什么是随机种子。用来扩展学生对随机数的认识,为学生建构随机数产生机制的认知体系。
3.2.5 检查输入数据,确保程序接收到符合要求的数据学生熟练掌握了以上知识结构体系,可考虑训练用户输入不合规格数据的编程问题。用户一旦输入负数或非数字符号,程序则会发生运行错误,导致用户体验不好。所以,应全面考虑对用户的输入做合法性校验,引导学生设计和编写更严密的程序。
示例9:用户输入一个整数(>1),判断是否为素数,要求程序接收到的输入数据是合规数据。
在程序设计中学生应当高度重视:凡是接收用户输入的数据,应先判断输入的数据是否合规,保证数据源的正确性。示例9训练学生在程序中实现对用户输入数据的控制和判断,需要综合运用循环结构语句与选择结构语句等程序设计方法。如此训练,进一步关联与组合学生已掌握的知识应用,强化学生对输入数据的检验意识。
3.2.6 异常处理应用保障程序接收到合规数据也可以通过异常处理来实现。
示例10:在判断一个正整数是否为素数的程序中引入异常处理。
示例10明确要求学生会运用Python语言的异常处理机制,即用“try...except...”语句捕获特定异常并执行相应处理,使程序具有更友好的用户体验。在示例10训练中,教师引出常用的异常类,拓展学生对异常处理的学习,建立异常处理的知识结构。
3.2.7 保存数据于文件中以上程序在运行时,数据输入由用户提供;输出数据只显示在运行过程中,程序运行一旦结束就丢失了。而解决实际应用问题,一般要求从文件中读取数据,程序设计需要具备保存数据功能以方便数据再利用。示例11训练在程序设计中实现文件操作,进一步完善程序功能。
示例11:从文件中读取数据并找出素数,将素数保存于新文件中。
示例11要求学生利用文件保存数据,掌握打开、读取、保存文件等相关操作,了解文件打开模式,认识Python数据文件类型与编码格式,按要求格式将数据写入文件,加强学生在编程中对文件的操作和利用。
综上11个示例,示例1至示例4是最基本的程序语言代码,是支架层次训练中的最底层;示例5至示例11,是依托底层程序语言代码,经基础训练迁移到拓展训练,在拓展训练示例代码中不断引入新的程序设计要求。因此,拓展训练的每个示例都是基于基础训练引入新要求,加深拓宽了示例内涵。目的在于经过基础训练逐层向拓展训练加深,逐步提高学生解决问题的知识水平,渐次扩展学生的知识结构。总之,通过拓展训练后,学生既巩固了基础训练的知识内容,又依据拓展训练建构更高层次的知识体系。
经过示例1至示例11的基础训练和拓展训练,学生掌握了一系列通过编写Python程序语言代码解决问题的方案,熟悉了相关示例所涉及的知识内容与结构体系。下面以此为支撑开展示例12和示例13的综合训练,通过进一步提高程序设计要求与难度,使学生将编程活动上升到程序设计思想的养成层面,让学生逐步形成模块化程序设计思想,以期编写和调试长代码程序。
示例12:设计程序实现如下功能:由用户输入一个正整数,判断是否是素数,直到用户输入q或Q指令退出程序。要求:1)保证程序接收到的输入数据符合规格;2)将用户输入且判断为素数的数据保存于一个文件中;3)使用函数实现素数判断;4)程序自动运行,直至用户输入q或Q指令退出。
示例12将拓展训练中的多个示例结合起来,训练学生把相关的程序代码组装成为一个小型应用程序,从而形成一个较大的应用开发程序。
示例13:以示例12训练为基础,为达成模块化要求目的,在程序中设计一个菜单可实现如下功能:1)输入数据;2)判断素数;3)保存素数;4)退出。便于用户按菜单进行交互操作。
在示例13中,增加了菜单程序设计,使开发的程序具有强交互性,为较大型程序开发应用做准备,而且再次加深学生理解模块化程序设计思想并运用到综合训练中。同时,强化训练学生绘制程序功能模块图、流程图等,为学生设计较大的应用程序提供宽基础、强技能支撑。
在综合应用训练中,学生依托基础训练、拓展训练中积累的程序设计经验和编写代码技能,基于模块化设计思想再一次构造含有基础代码和拓展代码的较大型完整程序。这是一个再设计过程,而非简单的组合。同时,要向学生特别强调加强程序的调试训练,充分掌握调试程序技能。
学生掌握了程序设计的基本方法,具有了较扎实的知识储备和实践技能基础,适时地开展延伸应用训练,一方面保持学生利用Python语言开展程序设计的不断进阶,另一方面希望促进学生的学习意识提升到自主探索境界。为此,列举示例14,将图形界面扩充到素数判断应用中,以促进学生在程序设计应用中的自主探索。
示例14:运用Python语言设计具有图2和图3界面的程序,实现对素数的判断。
图形界面是深受用户欢迎的计算机应用程序操作方式。在图形界面程序设计中,需要教师提供相应的范例、教程、参考文档等,为学生自主探索学习提供帮助。学生要将学习延伸到课外,通过自主探索训练,使自己的知识储备、编程思想、操作技能等各方面来一次大的飞跃,从而形成总体的Python程序设计与代码编写的知识体系与应用架构。
学生经过一个主题四个层次由易到难的多重递进训练后,在流畅地表述知识体系与提供问题解决方案、快速编写调试代码、自主寻找学习新知识途径等方面,较快地突破知识表述、代码编写与调试、设计思想认识等难点,实现了对难度较高项目的编程能力提升。既帮助学生整合了零碎的编程知识,形成较为完整的理论体系,又在有限的教学时间里让学生把握程序设计的全景认识,并运用于编程实践、内化所学知识,从而自主探索新的知识与实践学习。如表2所示。
表2 知识结构融合与建构过程
文章围绕一个主题(问题)的四个渐进层次训练,列举了若干示例,前一个示例是后一个示例的基础与支撑,后一个示例又是前一个示例的知识与应用的新生长。依此,设计出一系列训练示例,如搭支架式地不断进阶Python程序设计知识体系和应用平台。这些训练示例覆盖了Python程序设计基础的重要知识点,蕴含了知识之间的逻辑继承和发展关系。四个层次训练的复杂度、难度不断提高,也不断地提升了学生的程序设计知识水平和应用能力。更重要的是,在Python语言程序设计编写代码支架式训练中,蕴含了学生由编写简单程序代码、编写结构程序代码,进阶到掌握程序设计的文件操作、筑牢模块化程序设计理念,再到交互式程序设计应用、图形界面程序设计以及贯穿整个训练过程的程序调试能力养成的隐形历程。这说明基础训练、拓展训练、综合应用、自主探索的支架式实训教学,便于实训教学的顺利开展。总之,通过一系列针对性强的示例,支架式的四个层次训练,使学生能够熟练地编写正确的程序代码,领会并掌握程序设计的思想与方法,内化编程知识、强化编程技能,并汇入到学生自己的知识体系结构中。
Python语言程序设计课程内容庞杂,知识点多,教师可采用一个主题四个层次的支架式实训模式设计出针对性强、指向明确的实训项目,预设较完备的知识网络,方便学生经由学习与实训,从多维度建构自己的程序设计知识体系。当然,教师对实训的预期安排及指向明确的实践指导也是达成训练目标的重要内容,对此可以另行展开探讨。