Python是大数据时代最受欢迎的程序设计语言之一,是很多高校本、专科学生的一门必修课或选修课。特别对于高校计算机相关专业来说,很多学校已经把它作为大一学生学习的第一门计算机课程,因此它不仅仅是专业的基础课,为学习后续课程打基础,还肩负着如何激发学生的学习兴趣、培养学生的专业基本功、培养学生分析问题解决问题的能力、引导学生成为合格的专业人才(即启蒙、入门)等重任。作者在多年的教学实践和工程实践中一直在思考一个问题: 计算机专业的第一门课到底讲授什么、怎么讲授才能符合应用工程型人才的培养目标,才能体现这门课该起的作用。带着这样的问题,以福建工程学院校级精品课程建设为平台,不断地进行理论教学和实验教学改革,吸收和学习国内外先进的教学理念和方法,于2015年9月由清华大学出版社出版了比较有特色的教材《问题求解与程序设计》(C语言版)。该书自2015年出版以来,得到很多老师和同学的认可。年轻的老师通过这本教材的教学大大提高了程序设计的教学能力,大学一年级的学生通过这本教材的学习,对程序设计,对计算机科学产生了浓厚的兴趣,开启了他们程序设计和软件开发的人生之旅。由于严格的在线评测程序设计风格,问题求解为核心的软件工程思想体系,以及特别注重分析问题解决问题能力的培养,专业的程序设计基本功的训练等显著特征,《问题求解与程序设计》(C语言版)2017年被福建省教育厅评为福建省特色优秀本科教材,作者所在的教学团队,福建工程学院信息工程与计算机学院软件工程教研室荣获福建工程学院教学成果二等奖。这两年来,作者一直在给数据科学与大数据技术、软件工程等专业的学生教授“Python程序设计”课程, 一直想在《问题求解与程序设计》(C语言版)的基础上,出版一本同样风格的《问题求解与Python程序设计》,现在终于完成了,这要非常感谢清华大学出版社的支持。 教材的特点 教材每章的开始处列出了该章的学习目标,引出了该章要讨论的话题和要解决的问题。每章的最后给出了“你学到了什么?”一节,帮助读者理顺一章中的基本概念和重要知识点,提出了若干疑问请读者回答,如果读者回答有困难,就要回头查看相关的内容,再次消化理解。每章设计了比较丰富的程序练习题,对读者的程序设计能力给以强化训练,读者可以借助在线评测平台,自主练习。另外,每章还设计了比较综合的项目问题,读者可以尝试。除此之外,本书还有下面一些突出的特点。 1. 以问题求解为核心 学习程序设计的目的就是要解决实际问题,训练和提高分析问题和解决问题的能力。因此本书精心组织了41个案例问题。每个章节都围绕解决某个或某类案例问题来展开。把各种语法现象和编程技巧与规范融入解决这个问题的具体过程中。在解决问题的过程中学习程序设计的方法,训练程序设计的功夫。对于每个案例,经过分析、设计之后,给出完整的程序实现清单,教师或学生可以先运行程序,从感性上了解程序的输入输出和运行结果,然后详细展开几个相关的知识点。 2. 融入软件工程的思想 对于每个案例问题,首先按照问题描述和输入、输出格式的要求进行全面分析,明确要做什么,考虑各种可能的情况。对每一情况都给出具体的算法设计方案(伪码或流程图)、对应的代码实现(程序清单),然后对程序或算法用一组测试用例进行运行测试(这个运行测试是实时演示,教材中省略)。不管案例问题是大还是小,都严格按照这样的过程展开,进行强化训练。 问题求解与Python程序设计前言3. 遵循循序渐进的原则 传统的教材都是比较集中地介绍各种语法现象,学生比较难以接受。本书采用循序渐进的原则,螺旋式展开,在问题求解需要的时候才介绍语法规范和注意事项。具体表现在以下几个方面。 (1) 对于数据类型和运算来说,在第2章只是介绍了整型数据和浮点型数据、算术运算和赋值运算。在第3章介绍了字符型数据、布尔型数据,关系运算、逻辑运算和条件运算。在第4章介绍了自增、自减运算和复合赋值运算,第7章引出了列表、字典、元组类型,第8章利用了集合类型等。 (2) 对于变量的存储类别和作用域来说,先在5.1.3节(函数调用)初步认识,然后在5.2.3节(函数调用堆栈)介绍局部自动变量和局部静态变量以及单文件内的外部变量。之后进一步介绍应用程序范围内(多文件之间)的全局变量,还介绍了单文件范围内的静态函数——私有变量和私有函数。 (3) 对于面向对象,从常用的整数对象、浮点数对象开始,到字符对象、字符串对象、range对象、函数对象,在前5章中逐渐展开,到第6章正式讨论面向对象的思想,介绍自定义类的方法,并借助tkinter模块中各种小构件类,加深对类和对象的理解,第7章通过批量数据的处理问题,介绍了序列类型list、tuple和映射类型dict,第8章是面向对象的提高,介绍了代码重用的两种机制“组合和继承”,多态性,抽象基类等,在第9章介绍了跟文件相关的对象。在第10章介绍了NumPy、Pandas库中的对象等。 (4) 对于异常处理机制,从第3章的含有判断的程序开始,就引出了异常的概念,使用了异常处理结构。第4章讨论程序的容错能力,正式介绍了异常;在第8章面向对象程序设计之后,再仔细研究异常类的层次结构(这一部分留给读者自学)。 (5) 对于格式化输出,本书开始使用的是C语言风格的%表达式,然后介绍了format函数,以及字符串的format方法,在第4章给出了最新的fstring方法,并且建议大家尽量使用fstring格式。 本书的亮点之一是图形程序设计贯穿始终,几乎每章都有。从HelloWorld开始介绍turtle库的海龟作图,富有趣味性,通过turtle绘图可以帮助理解选择判断结构、循环结构、函数等基本概念,到了第6章转为tkinter模块进行GUI程序设计,并在面向对象的程序设计中扮演重要的角色。对于数据分析一章,引出了matplotlib扩展库,可以很方便地绘制NumPy的ndarray类型的数据。 有人说Python程序设计没有指针,这是表面现象,应该说没有像C语言那样的用说明的指针。实际上处处是指针。在Python中变量名是对象的引用,其实质就是对象的地址,因此凡是有标识符的地方实际都是指向对象的指针。Python函数的参数传递,传递的是引用,传引用充分体现了引用的指针意义。在第7章的列表是一组有序(非排序)对象的集合,每个列表元素是通过对象的引用访问的,在第8章借助对象的引用给出了对象之间的链式存储方法,等等。 4. 程序设计在线评测 在线评测(Online Judge)本来是为各种程序设计竞赛提供的平台,通过近些年来的教学实践,大家都觉得在线评测用于程序设计类课程的教学效果很好。首先,由于每道在线评测的题目都精心设计了一组测试用例,学生要完成它,必须严格按照输入、输出样例的格式要求,仔细设计问题的求解算法。在设计过程中必须考虑各种可能的情况,不然就会导致部分测试用例不能通过。因此对于学生来说,非常有利于培养学生的专业素质,提高学生程序设计的能力。其次,由于是在线评测,学生提交作业之后会立即得到评测结果,因此如果在线评测的结果是accepted,学生也会产生学习兴趣,带来一定的成就感。如果在线评测的结果是错误的,也会马上知道什么类型的错误,学生也会很快改正。对于教师来说,虽然需要比较多的准备时间,但是题目一旦设计好,基本上就不用手工评阅程序了。当然教师也应该抽查学生在线提交的作业,包括正确的和不正确的,从中发现问题。最后,在线评测与传统的作业完成方式相比更能训练学生的动手操作能力、问题求解能力。本教材从第2章起,每章都设计了10余道在线评测题目,全书总计包括100多道在线评测题目(部分题目不支持在线自动评测)。 5. 项目设计 从第2章起,每章最后都至少给出了项目设计题目。项目设计题目是一个规模相对比较大的题目,因此最好以小组为单位集体完成。组员之间彼此进行分工合作,这样可以培养学生的团队协作精神。在设计的时候,如果采用集成环境最好建立一个工程,特别是当项目规模比较大的时候更应该建立工程,这样可以方便地管理多个文件。 6. 课程平台 随着互联网的快速发展,特别是5G高速网络的到来,在线学习已经越来越普及。在线编译器、在线解释器和在线评测系统成为程序设计学习的热门平台。此外,如果想自己搭建一个含有在线评测的自主学习平台,也可以自己安装moodle系统,不过要另外安装一个onlinejudge插件。有很多高校的onlinejudge平台提供了丰富的在线评测题目,可以注册后练习。 7. 程序设计风格的培养 鼓励学生程序设计要练基本功。提倡先以命令行+编辑器(特别是Linux vim编辑器)的方式进行程序设计。然后再考虑使用集成环境。 在书中多次提到Python程序设计的规范PEP8,希望读者能仔细学习规范化程序设计,养成良好的程序设计习惯。 8. 在线学习资源 本书提供了全书41个求解问题的113个源程序清单,每个源程序均可通过手机扫码,在线查看或下载,如果在手机上事先安装了Python3IDE应用程序,可以直接运行该程序,查看运行结果,只须把查看到的源代码复制到Python3IDE的编辑窗口中,单击“运行”按钮即可。注意“查看程序”和Python3IDE是两个不同的应用程序,Python3IDE打开后默认是一个编辑环境,等待用户输入代码,这时需要切换到查看程序界面,复制代码之后,再回到Python3ID,粘贴代码。还可以在Python3IDE中对代码进行编辑修改。 本书还为每章设计了一个实验,提供了实验指导,每个实验指导同样可以通过手机扫码,在线查看或下载。 全书共有10章,各章内容概述如下。 第1章绪论——计算机与程序设计。本章介绍了计算机的工作原理和它的快速计算能力和逻辑判断能力,特别强调这些能力都要通过存储程序来实现,因此进一步讨论了如何存储程序和数据、计算机系统中软件(程序)的重要性。为了使学生对程序有一个感性认识并产生一定的兴趣,介绍了典型的Python结构化程序,包括一个命令行的猜数游戏程序、一个turtle图形绘制程序,限于篇幅GUI窗口程序、嵌入式程序和网络应用程序没有列出。最后说明了写程序、开发软件要讲究方法,介绍了结构化方法和面向对象方法。程序设计还需要一个基本的开发环境,包括编辑器、编译器/解释器和调试器。对于编辑器,鼓励学生学习使用专业的Vim或者Emacs编辑器,并先在命令行环境下使用解释器,过一阶段再使用集成开发环境。要求计算机专业的学生必须练好打字基本功,并能够熟练地使用操作系统的命令窗口。 第2章数据类型与变量——程序设计入门。本章通过6个问题的分析求解,使读者初步认识程序设计。通过“在屏幕上输出文字信息”的问题,介绍了Python结构化程序设计的基本框架以及标准输出函数,以及有趣的turtle模块中的在图形窗口写字的函数。通过“计算两个固定整数的和与积”问题,引出了常量与变量、整型数据、算术运算、赋值运算等概念。通过“计算任意两个整数的和与积”问题介绍了标准输入函数、测试用例和用流程图表示顺序程序结构的方法。通过“温度转换”问题的求解过程说明了变量初始化和运算的优先级和结合性的重要性。通过“求三个整数的平均值”问题引出了浮点型数据以及不同的数据类型之间转换等重要概念。通过“求圆的周长和面积”介绍了math模块中的符号常量pi的用法。通过海龟绘图问题,介绍了turtle库的特征,海龟按照指令爬行的轨迹就是图形。 第3章判断与决策——选择程序设计。本章通过5个问题的求解,介绍了具有判断决策能力的程序该如何设计实现。通过“让成绩合格的学生通过”问题引出了逻辑常量、布尔型数据、关系运算、判断条件的各种表达形式,以及Python中进行逻辑判断的单分支选择结构。通过 “按成绩把学生分成两组”的问题引出双分支选择结构和条件运算,同时分析了如果用顺序的两个单分支求解同样的问题会如何。通过“按成绩把学生分成多组(百分制)”问题的分析自然而然地引出选择结构的嵌套,同时给出了一种新的表达方式ifelifelse结构。通过“按成绩把学生分成多组(5级制)”引出了字符型数据的表达方法。通过“判断闰年问题”引出了逻辑运算,从而给出了复杂判断条件的表达方法。把判断用在海龟作图的问题里,即判断点是否在圆内。 第4章重复与迭代——循环程序设计。本章通过7个问题的分析求解,阐述了循环程序结构和3种控制循环的方法。通过“打印规则图形”问题分析了如何从重复的角度观察问题,使读者认识到发现问题中包含的重复因素的重要性,引出了while循环结构及计数控制循环的方法。通过“自然数求和与阶乘计算”问题引出了与while等价的for循环结构。通过“简单的学生成绩统计”问题的分析引出了标记控制(输入CtrlZ或CtrlD或特殊的值)循环的方法,因为这时不知道重复的次数。通过“计算2的算术平方根”问题的分析求解,介绍了误差精度控制循环的方法。通过“打印九九乘法表”问题介绍了循环嵌套和穷举法。通过“素数判断”和“处理有效成绩”问题的分析求解引入了break、continue的用法。通过“随机游戏模拟”问题介绍了random模块和自顶向下、逐步求精的分析方法,很多实际问题是随机现象,在这一节举例说明了随机现象如何模拟,如掷硬币实验,随机行走图形模拟。最后对结构化程序进行了总结,指出任何问题都可以使用顺序结构、选择结构和循环结构通过堆叠和嵌套的方法表示出来。 第5章分而治之——函数程序设计。本章循序渐进地介绍了函数程序设计的思想和方法。通过“再次讨论猜数游戏模拟”问题,采用自顶向下、逐步求精的分析过程把问题划分为子问题,介绍了Python语言如何用函数表达子问题,包括函数的定义、调用和函数测试,函数模块化的基本方法。通过“判断问题”的分析求解进一步加深了函数的概念和函数的分而治之功能,并且进一步探讨了函数调用的内部机制以及变量的存储类别和作用域在函数调用过程中是如何体现的。接下来通过“问题的递归描述”介绍了递归函数的定义和递归调用的过程。通过进一步讨论海龟绘图问题,使读者进入了更高的层次,如何把一组函数做成一个库接口,即如何设计接口,如何实现接口,如何使用接口以及如何建立一个自己的函数库和package。在这个过程中,介绍了多文件之间的全局变量和文件内部的私有函数的声明方法。然后介绍了典型的Python项目的目录层次结构。 第6章客观对象描述——面向对象程序设计基础。本章通过3个问题介绍了面向对象程序设计的基本思想。首先通过“学生成绩统计”问题,讨论了Python如何抽象学生对象,建立学生类,封装学生成绩的相关信息和方法,特别重要的是实例初始化方法__init__,它是构造器创建实例时自动调用的方法。然后通过“有理数的四则运算问题”,引出了面向对象程序设计中的运算符重载。特别强调了__str__重载的意义,在这里还介绍了@property属性的用法,私有成员、静态成员和类方法等重要的概念。最后通过“身体健康指数问题”引出了如何设计GUI程序,介绍了Python内置的tkinter模块,在这个模块中的每个小构件都是类,它们封装了该构件拥有的属性和方法,学习GUI设计是理解面向对象程序设计的不错的方法。 第7章批量数据处理——序列程序设计。本章通过典型的批量数据中的排序和查找问题引出了序列程序设计的概念和用法。通过“一门课程的成绩排序”问题的分析,引出了用一维列表存储数据的方法。详细介绍了列表创建的方法,序列数据类型访问元素的方法等。这个成绩排序问题还实现了用字典存储的方法。无论是列表实现还是字典实现,在排序过程中使用了zip函数,而zip转换为列表是一个元组列表,因此在这一节系统地介绍了元组的基本操作。通过“三门课程成绩按总分排序”问题引出了二维列表的概念,分析了二维列表与一维列表的关系。由于序列类型的列表list的可变性,导致它作为函数参数时的特别的效果。通过两个排序问题的求解,介绍了交换排序、选择排序的算法,还有冒泡排序和插入排序。通过“在成绩单中查找某人的成绩”问题的分析,进一步讨论字符串类型str,比较深入地介绍了字符串类的基本方法。同时还介绍了典型的查找算法,线性查找和折半查找。通过在画布上绘制图形问题,介绍了tkinter的Canvas类以及鼠标事件。 第8章代码重用——面向对象程序设计进阶。代码重用是面向对象程序设计的重要特征之一。面向对象的对象类之间具有两种主要关系。一是hasa关系,另一个是isa关系。前者是利用已有对象类组合新的对象类,而后者可以通过扩展,派生出新的类型,这是两种不同形式的代码重用机制。通过“课程管理”问题中涉及的对象,介绍了hasa关系组合新类的方法,通过层次几何图形的描述,介绍了如何从一个比较抽象的基类派生出内容更加丰富的、新类的方法。在这里特别强调了如何派生,继承什么,怎么继承,以及覆盖方法和多态性等重要概念。其中,课程管理问题还介绍了对象的链表存储方法。通过“简单的编辑器问题”讨论了tkinter模块中的Text构件和对话框。 第9章数据持久存储——文件程序设计。本章首先回顾了数据的变量存储、列表存储甚至是链表存储,它们都具有易失性,引出了数据要持久存储可以采用文件机制,进一步可以使用数据库机制。本章通过3个问题讨论了这个话题。首先通过“文件复制”问题的求解,介绍了文件操作的一般步骤、缓冲文件系统的概念以及文本文件的读写方法。通过“把学生成绩数据保存到文件中”的问题求解介绍了文件的格式化读写方法,包括文本读写和二进制读写,还介绍了JSON格式,CSV格式文件的读写方法,pickle序列化和struct序列化方法。 第10章数据分析与可视化——数组程序设计。本章通过4个问题,对NumPy模块、Pandas模块、Matplotlib模块、Jieba和Wordcloud模块做了比较精简的介绍,突出模块的主要特征,使读者利用较少的篇幅、经典的问题求解就能体会到数据分析与可视化的基本内容,给继续学习数据分析可视化引了一条路,特别指出,NumPy中的数据类型ndarray是数组,是与序列不同的、计算效率比较高的类型。介绍了Python中一个特别的数据对象与函数绑定的方法——闭包,以及可以修饰函数的修饰器。 建议教学安排续表章节理论学时实验学时第1章绪论——计算机与程序设计22第2章数据类型与变量——程序设计入门42第3章判断与决策——选择程序设计42第4章重复与迭代——循环程序设计42第5章分而治之——函数程序设计62第6章客观对象描述——面向对象程序设计基础62第7章批量数据处理——序列程序设计62第8章代码重用——面向对象程序设计进阶42第9章数据持久存储——文件程序设计42第10章数据分析与可视化—数组程序设计42合计4420本书的写作计划虽然酝酿已久,但是真正成稿却是在一个令人终生难忘的特别时期——2020年2月开始至2020年6月,突如其来的新冠病毒把人们封闭在一个小圈子里。整天除了学习就是学习。通过网络查阅大量资料,包括官方文档和优秀的博文论坛,从中学到了很多之前没有深入研究过的东西。但是,由于本书作者水平有限,书中还是难免存在不足,恳请广大读者批评指正。 此外,本书的出版不仅得到了福建工程学院信息学院软件工程教研室教学团队的支持,还得到了四川工业科技学院电信学院计算机教研室教学团队的认可,在此表示衷心的感谢! 鲍春波于福建福州/四川德阳2020年12月