来自中国大学MOOC的《Python语言程序设计》
以下内容为在学习中国大学MOOC的《Python语言程序设计》中整理的学习过程,由于本文目的是尽量保证覆盖关键内容和条理清晰,所以阅读上会有些枯燥:)推荐作为在中国大学MOOC上学习这门课程的辅助文章
个人能力有限,如有问题请您指出啦
以下为分章节链接:
1.Python基本语法元素
1.1 程序设计基本方法
计算机与程序设计
-
计算机的概念
满足以下两点
-
功能性(对数据的操作,表现为数据计算、输入输出处理和结果存储等)
-
可编程性(根据一系列指令自动地、可预测地、准确地完成操作者的意图)
-
计算机的发展
摩尔定律
计算机的发展参照摩尔定律
它名为定律,实为预测法则:单位面积集成电路上可容纳晶体管的数量约每两年翻一番(指数级别)(CPU\GPU等由晶体管组成,也满足)
-
程序设计(即编程)
程序设计语言是一种用于交互(交流)的人造语言
它比自然语言(如中文)简单、严谨、精确
用于人与计算机的交互
编译和解释
-
编程语言的执行方式
-
源代码:人类可读的,按某种编程语言编写的程序(如:ans=a+b;)
-
目标代码:计算机可直接执行,一般人不可读(如:11010010 00111011)
-
-
编译:将源代码一次性转换为目标代码的过程
源代码->编译器->目标代码->程序执行(输入->输出)
-
解释:将源代码逐条转换成目标代码同时逐条运行的过程
源代码、程序输入依次进行->解释器->输出
(因此编译后不需源代码,解释需要)
-
静态语言和脚本语言(根据执行方式不同划分)
-
静态语言:使用编译执行的编程语言(如C++/Java)
一次生成目标代码,优化充分,程序快
-
脚本语言:解释执行(如Python/JavaScript/PHP)
维护灵活、跨多平台运行
-
其实语言本身没有编译和解释的区分,就像C语言主要是编译后执行,有人写了它的解释器,Python主要是解释执行,有人写了它的编译器,解释和编译只是某种语言偏好的执行方式
程序的基本编写方法:IPO
-
理解IPO
Input Process Output
-
计算机只(辅助)解决问题的计算部分
-
编程解决问题的步骤
-
分析问题:分析计算部分
-
划分边界:规划IPO
-
设计算法
-
编写程序
-
调试测试
-
升级维护
-
计算机编程
-
计算思维
是区别于逻辑思维(数学为代表)和实证思维(物理为代表)的体现抽象交互关系、自动化执行的思维模式
-
编程能**带来乐趣**、提高效率、带来就业
1.2 Python开发环境配置
Python语言概述
- 是一个由编程牛人领导设计并开发的编程语言
- 是一个有开发、开源精神的编程语言
- 应用于火星探测、搜索引擎、应力波分析等众多领域
Python语言Windows系统开发环境
在安装时勾选add python3.x to path(即把python命令添加到环境变量)
Python程序编写与运行
-
两种编写方式
-
交互式
对每个输入语句即时运行结果,适合语法练习
即直接用IDLE编写
-
文件式
批量执行一组语句并一次性得出结果,编程主要方式
即在IDLE里面新建文件并保存为x.py后运行
-
-
实例1:圆面积的计算
r=25 area=3.1415*r*r print(area) print("{:.2f}".format(area))
-
实例2:同切圆绘制
import turtle turtle.pensize(2) turtle.circle(10) turtle.circle(40) turtle.circle(80) turtle.circle(160)
-
实例3:五角星绘制
from turtle import * color('red','red') begin_fill() for i in range(5): fd(200) rt(144) end_fill() done()
1.3 实例1:温度转换
问题分析
转换摄氏度和华氏度
-
计算部分的理解和确定
- 理解1:直接将温度值进行转换
- 理解2:将温度信息发布的声音或图像形式进行理解和转换
-
理解3:监控或爬取温度信息发布渠道,实时获取并转换温度值
- 入门采取理解1
-
划分边界
- 输入为带摄氏或华氏标志的温度值
- 处理为根据标志选择温度转换算法
- 输入输出格式设置:F和C
-
设计算法
- C=(F-32)/1.8
- F=C*1.8+32
实例编写
#TempConvert.py
TempStr=input("请输入带有符号的温度值:")
if TempStr[-1] in ['F','f']:
C=(eval(TempStr[0:-1])-32)/1.8
print("转换后的温度是{:.2f}C".format(C))
elif TempStr[-1] in['C','c']:
F=1.8*eval(TempStr[0:-1])+32
print("转换后的温度是{:.2f}F".format(F))
else:
print("输入格式错误")
举一反三
- Python语法元素理解
- 输入输出的改变
- 计算问题的扩展(做类似问题)
1.4 Python程序语法元素分析
程序的格式框架
-
代码高亮
-
缩进
-
表达程序的格式框架,是语法的一部分
- 严格明确
- 所属关系
- 长度一致
-
-
注释
- 单行注释 #开头
- 多行注释 ‘'’开头’'’结尾
命名与保留字
-
变量:用于保存和表示数据的占位符号
-
变量命名:关联标识符的过程
- 规则:大小写字母、数字、下划线和汉字等字符及组合
- 注意:大小写敏感、首字符不能是数字、不与保留字相同
-
保留字(关键字):被编程语言内部定义并保留使用的标识符
and elif import raise global as else in return nonlocal assert except is try True break finally lambda while False class for not with None continue from or yield def if pass del
数据类型
-
整数、字符串、浮点数、列表
-
10,011,101
- 整数:10011101
- 字符串:”10,011,101”
- 列表:[10,011,101]
-
字符串:由0个或多个字符组成的有序字符序列
-
在两侧由一对单引号或一对双引号(没有区别)
-
字符串中的编号从0开始,即一般认为的第一个字符即为第0个字符
-
正向递增序号和反向递减序号,举例
"请输入带有符号的温度值:" 正向递增序号从第一个字符开始由0递增 反向递减序号从最后一个字符开始由-1递减 其中"符"是正向递增序号中的第5个字符 也是反向递减序号中的第-7个字符
-
字符串的索引
返回字符串中单个字符
如:
"请输入带有符号的温度值:"[0] TempStr[-1]
-
字符串的切片
如:
"请输入带有符号的温度值:"[1:3]包括第1、2个字符 TempStr[0:-1]不包括最后一个字符
-
-
数字类型
- 整数:数学中的整数
- 浮点数:数学中的实数,带有小数部分
-
列表
-
使用[]表示,采用,分隔各元素
如:
['F','f']表示两个元素'F'和'f'
-
使用 in 判断一个元素是否在列表中
如:
TempStr[-1] in ['C','c'] 中如果TempStr的最后一个字符为C或者c则其返回值为True 否则为False
-
语句与函数
-
赋值语句:由赋值符号(单一等号)构成的一行代码
-
分支语句
如果条件成立则执行:后部分语句
如:
if ...: ... ... elif ...: ... ... else: ...
-
函数:根据输入参数产生不同输出的功能过程
如input(“…”),print(“…”)
采用<函数名>(<参数>)的方式使用参数>函数名>
Python程序的输入输出
-
input():从控制台获得信息输入的函数
- <变量>=input("提示信息字符串") 变量>
-
print():以字符形式向控制台输出结果的函数
-
print(<拟输出字符串或字符串变量>)拟输出字符串或字符串变量>
-
格式化:如
print("转换后的温度是{:.2f}C".format(C)) {}表示槽,后续变量填充到槽中 {:.2f}表示将变量C填充到这个位置时取小数点后两位
-
-
eval():简单称为评估函数,去掉参数最外侧引号并执行余下语句的函数
-
eval(<字符串或字符串变量>)字符串或字符串变量>
-
如
>>>eval(“1”)
1
>>>eval(“1+2”)
3
>>>eval(‘ “1+2” ‘)
‘1+2’
>>>eval(‘print(“Hello”)’)
Hello
-
“温度转换”代码分析
#TempConvert.py
TempStr=input("请输入带有符号的温度值:")
if TempStr[-1] in ['F','f']:
C=(eval(TempStr[0:-1])-32)/1.8
print("转换后的温度是{:.2f}C".format(C))
elif TempStr[-1] in['C','c']:
F=1.8*eval(TempStr[0:-1])+32
print("转换后的温度是{:.2f}F".format(F))
else:
print("输入格式错误")
练习
-
实例1: 温度转换
描述
这是”实例”题,与课上讲解实例相同,请作答检验学习效果。
温度的刻画有两个不同体系:摄氏度(Celsius)和华氏度(Fahrenheit)。
请编写程序将用户输入华氏度转换为摄氏度,或将输入的摄氏度转换为华氏度。
转换算法如下:(C表示摄氏度、F表示华氏度)
C = ( F - 32 ) / 1.8
F = C * 1.8 + 32
要求如下:
(1) 输入输出的摄氏度可采用大小写字母C结尾,温度可以是整数或小数,如:12.34C指摄氏度12.34度;
(2) 输入输出的华氏度可采用大小写字母F结尾,温度可以是整数或小数,如:87.65F指华氏度87.65度;
(3) 输出保留小数点后两位,输入格式错误时,输出提示:输入格式错误;
(4) 使用input()获得测试用例输入时,不要增加提示字符串。
## 输入
示例1:12.34C
示例2:87.65F
## 输出
示例1:54.21F
示例2:30.92C
s=input()
if s[-1] in ['F','f']:
c=(eval(s[0:-1])-32)/1.8
print("{:.2f}C".format(c))
elif s[-1] in ['C','c']:
f=eval(s[0:-1])*1.8+32
print("{:.2f}F".format(f))
else:
print("输入格式错误")
-
Hello World I
描述
这是学习每种程序设计语言的第一个实例。
输出Hello World,注意大小写。
## 输入
无
## 输出
Hello World
print("Hello World")
-
数字形式转换 I
描述
获得用户输入的一个正整数输入,输出该数字对应的中文字符表示。
0到9对应的中文字符分别是:零一二三四五六七八九
输入输出示例
输入 输出 示例 1 123 9876543210
一二三 九八七六五四三二一零
s=input() for c in s: if c=='0':print('零',end="") if c=='1':print('一', end="") if c=='2':print('二', end="") if c=='3':print('三', end="") if c=='4':print('四', end="") if c=='5':print('五', end="") if c=='6':print('六', end="") if c=='7':print('七', end="") if c=='8':print('八', end="") if c=='9':print('九', end="") 或者 template = "零一二三四五六七八九" s = input() for c in s: print(template[eval(c)], end="") print()中增加end=""参数表示输出后不增加换行,多个print()可以连续输出。
-
温度转换 II
描述
温度的刻画有两个不同体系:摄氏度(Celsius)和华氏度(Fahrenheit)。
请编写程序将用户输入华氏度转换为摄氏度,或将输入的摄氏度转换为华氏度。
转换算法如下:(C表示摄氏度、F表示华氏度)
C = ( F - 32 ) / 1.8
F = C * 1.8 + 32
要求如下:
(1) 输入输出的摄氏度采用大写字母C开头,温度可以是整数或小数,如:C12.34指摄氏度12.34度;
(2) 输入输出的华氏度采用大写字母F开头,温度可以是整数或小数,如:F87.65指华氏度87.65度;
(3) 不考虑异常输入的问题,输出保留小数点后两位;
(4) 使用input()获得测试用例输入时,不要增加提示字符串。
## 输入
示例1:C12.34
示例2:F87.65
## 输出
示例1:F54.21
示例2:C30.92
s=input()
if s[0] in ['F','f']:
c=(eval(s[1:])-32)/1.8
print("C{:.2f}".format(c))
elif s[0] in ['C','c']:
f=eval(s[1:])*1.8+32
print("F{:.2f}".format(f))
else:
print("输入格式错误")
或者
#TempConvert.py
TempStr = input()
if TempStr[0] in ['F']:
C = (eval(TempStr[1:]) - 32)/1.8
print("C{:.2f}".format(C))
elif TempStr[0] in ['C']:
F = 1.8*eval(TempStr[1:]) + 32
print("F{:.2f}".format(F))
else:
print() #不输入任何错误提示
这个实例扩展自实例1,请注意以下三点:
(1) 将输入字符串转换为数字时使用eval()函数,不要用int()函数,因为输入的数字可能不是整数;
(2) 采用{:.2f}将输出数字变成两位小数点表示时,即使数学上该输出值是整数,也会按照小数方式输出,例如,转换后温度为10度,输出为10.00;
(3) TempStr[1:]表示字符串除首字符外的所有字符。
-
货币转换 I
描述
人民币和美元是世界上通用的两种货币之一,写一个程序进行货币间币值转换,其中:
人民币和美元间汇率固定为:1美元 = 6.78人民币。
程序可以接受人民币或美元输入,转换为美元或人民币输出。人民币采用RMB表示,美元USD表示,符号和数值之间没有空格。
注意:
(1) 这是一个OJ题目,获得输入请使用input() ;
(2) 不提示输出格式错误,结果小数点后保留两位。
## 输入
示例1:RMB123
示例2:USD20
## 输出
示例1:USD18.14
示例2:RMB135.60
s=input()
if s[0:3]=="RMB":print("USD{:.2f}".format(eval(s[3:])/6.78))
elif s[0:3]=="USD":print("RMB{:.2f}".format(eval(s[3:])*6.78))
else:print("")
或者
CurStr = input()
if CurStr[:3] == "RMB":
print("USD{:.2f}".format(eval(CurStr[3:])/6.78))
elif CurStr[:3] in ['USD']:
print("RMB{:.2f}".format(eval(CurStr[3:])*6.78))
这个代码是实例1的一个扩展,注意以下3点:
(1) eval()函数将字符串转换成数字,不能省略;
(2) == 表示 "等于",in 表示成员包含,对于这个题目,由于只允许输入采用全大写方式,两种方法均可;
(3) :.2f输出小数点后两位。
测验
单项选择题
-
Guido van Rossum正式对外发布Python版本的年份是:
A. 1998 B.2002 C.1991 D.2008
C
Python成功了,所以早年的开发历史也受到关注,以下是Guido自述的启动阶段时间表:
”
December, 1989 Implementation started
1990 Internal releases at CWI
February 20, 1991 0.9.0 (released to alt.sources)
February, 1991 0.9.1
”
鉴于Internal release不算对外发布,普遍认为Python语言诞生于1991年。
-
以下关于Python语言中“缩进”说法正确的是:
A. 缩进可以用在任何语句之后,表示语句间的包含关系
B. 缩进在程序中长度统一且强制使用
C. 缩进统一为4个空格
D. 缩进是非强制的,仅为了提高代码可读性
D
Python语言的缩进只要统一即可,不一定是4个空格(尽管这是惯例)。
-
以下不属于IPO模型的是:
A. Process
B. Output
C. Input
D. Program
D
IPO:Input Process Output
-
字符串是一个字符序列,给字符串s,以下表示s从右侧向左第三个字符的是:
A. s[-3]
B. s[3]
C. s[0:-3]
D. s[:-3]
A
字符串有正向递增和反向递减两套序号体系
-
以下不是Python语言合法命名的是:
A. MyGod
B. 5MyGod
C. MyGod5
D. _MyGod_
B
合法命名的首字符不能是数字。
-
在Python中,用于获取用户输入的函数是:
A. eval()
B. print()
C. input()
D. get()
C
get()不是Python内置函数,获得用户输入只有一种方式:input()。
-
下面不属于Python保留字的是:
A. import
B. type
C. def
D. elif
B
type不是Python保留字,而是内置函数 type()。
-
以下不是Python数据类型的是:
A. 字符串
B. 整数
C. 实数
D. 列表
C
实数是数学中的概念,在Python中对应浮点数。
-
哪个选项给出的保留字不直接用于表示分支结构?
A. elif
B. else
C. in
D. if
C
if-elif-else是分支表达,in用来进行成员判断。
-
利用print()格式化输出,哪个选项用于控制浮点数的小数点后两位输出?
A. {:.2f}
B. {.2f}
C. {.2}
D. {:.2}
A
:.2f 哪一个都不能少
程序设计题
-
Hello World的条件输出
描述
获得用户输入的一个整数,参考该整数值,打印输出”Hello World”,要求:
如果输入值是0,直接输出”Hello World”
如果输入值大于0,以两个字符一行方式输出”Hello World”(空格也是字符)
如果输入值小于0,以垂直方式输出”Hello World”
输入输出示例
输入 输出 示例 1 0
Hello World
a=input() if eval(a)==0 : print("Hello World") elif eval(a)>0 : print("He\nll\no \nWo\nrl\nd") elif eval(a)<0 : print("H\ne\nl\nl\no\n \nW\no\nr\nl\nd") 或者 参考代码如下: n = eval(input()) if n == 0: print("Hello World") elif n > 0: print("He\nll\no \nWo\nrl\nd") else: for c in "Hello World": print(c) 答案可以有很多种写法。
-
数值运算
描述
获得用户输入的一个字符串,格式如下:
M OP N
其中,M和N是任何数字,OP代表一种操作,表示为如下四种:+, -, *, /(加减乘除)
根据OP,输出M OP N的运算结果,统一保存小数点后2位。
注意:M和OP、OP和N之间可以存在多个空格,不考虑输入错误情况。
输入输出示例
输入 输出 示例 1 10 + 100 1 / 20
110.00 0.05
s=input() print("{:.2f}".format(eval(s))) 或者 参考答案如下: s = input() print("{:.2f}".format(eval(s))) 体会eval()函数的作用,在编程中用处很大。
2.Python基本图形绘制
2.1 深入理解Python语言
计算机技术的演进
- 计算机技术的演进过程
- 1946-1981 计算机系统结构时代(35年)- 计算能力问题
- 1981-2008 网络和视窗时代(27年)- 交互问题
- 2008-2016 复杂信息系统时代(8年)- 数据问题
- 2017- 人工智能时代 - 人类的问题
- 我们现在的时代:新计算时代
编程语言的多样初心
-
C(计算机系统结构时代)
- 学习内容 指针、内存、数据类型
- 语言本质 理解计算机系统结构
- 解决问题 性能
- 适用对象 计算机类专业
-
Java(网络和视窗时代;面向对象语言)
- 学习内容 对象、跨平台、运行时
- 语言本质 理解主客体关系
- 解决问题 跨平台
- 适用对象 软件类专业
-
C++
- 学习内容 对象、多态、继承
- 语言本质 理解主客体关系
- 解决问题 大规模程序(如操作系统)
- 适用对象 计算机类专业
-
VB(网络和视窗时代)
- 学习内容 对象、按钮、文本框
- 语言本质 理解交互逻辑
- 解决问题 桌面应用
- 适用对象 不确定(很少)
-
Python(复杂信息系统时代)
- 学习内容 编程逻辑、第三方库
- 语言本质 理解问题求解
- 解决问题 各类问题的计算部分
- 适用对象 所有专业
-
2018年以后的计算环境
大数据、云计算、物联网、信息安全、人工智能等需求爆发
解决日益增长的计算需求,用什么语言?
Python语言的特点
-
Python语言是通用(普世)、脚本、开源、跨平台、多模型语言
-
特点与优势
-
语法简洁
-
C代码量的10%
-
强制可读性(缩进)
-
较少的底层语法元素
-
多种编程方式
-
支持中文字符
-
-
生态高产
- 快速增长的计算生态(13万第三方库)
- 避免重复造轮子
- 开发共享
- 跨操作系统平台
-
-
如何看待Python
-
人生苦短,我学Python
-
C/C++
Python语言不能解决计算机底层/内存/接口方面的工作,需要C
对效率,执行速度无多少要求的,完全可以用Python实现
- Java:针对特定开发和岗位需求
- HTML/CSS/JS:不可替代的前端技术,全栈能力
- 其他:R/Go/Matlab,特定领域
-
-
最高产的程序设计语言
- 掌握抽象并求解计算问题综合能力的语言
- 了解产业界解决复杂计算问题方法的语言
- 享受利用编程将创新变成现实乐趣的语言
-
工具决定思维:Python高效产出
-
“超级语言”的诞生
- 编程语言的种类
- 机器语言
- 二进制语言,直接执行
- 和CPU型号有关
- 汇编语言
- 将二进制代码直接对应助记符,和CPU有关,需要汇编器转换
- 如add 2,3 ,result是2+3功能的汇编语言
- 高级语言
- 接近自然语言,容易描述计算问题
- 与CPU型号无关,编译运行
- 如result = 2 + 3
- 机器语言
- 编程语言种类和发展
- 机器语言-汇编语言-高级语言
- 超级语言
- 粘性整合已有程序,具有庞大的计算生态
- 编程思维:刀耕火种->集成开发
- 如result=sum(2,3)
- Python是以计算生态位标志的“超级语言”
2.2 实例2:Python蟒蛇绘制
“Python蟒蛇绘制”问题分析
-
Python蟒蛇绘制
-
设计形状
-
问题1 计算机绘图原理是?
一段程序为什么能产生窗体?为什么能在窗体上绘制图形?
-
问题2 绘制从哪开始?
如何绘制一条线?如何绘制一个弧形?如何绘制一个蟒蛇?
-
“Python蟒蛇绘制”实例编写
#PythonDraw.py
import turtle
turtle.setup(650,350,200,200)
turtle.penup()
turtle.fd(-250)
turtle.pendown()
turtle.pensize(25)
turtle.pencolor("purple")
turtle.seth(-40)
for i in range(4):
turtle.circle(40,80)
turtle.circle(-40,80)
turtle.circle(40,80/2)
turtle.fd(40)
turtle.circle(16,180)
turtle.fd(40*2/3)
turtle.done()
import是保留字,它引入了一个绘图库,名字叫turtle
import turtle就是这段程序可绘图的原因
“Python蟒蛇绘制”举一反三
- 语法理解 共17行,多行相似
- 参考框架结构,逐行理解
- 程序参数改变
- 颜色
- 长度
- 方向
- 计算问题拓展-是各类图形绘制问题代表
2.3 模块1:turtle库的使用
turtle库基本介绍
- turtle库概述
- 海龟库,是turtle绘图体系的Python实现
- 是Python标准库之一
- 入门级图形绘制函数库
- 标准库
- Python计算生态=标准库(随解释器安装)+第三方库(需经过安装才能使用)
- 库Library、包Package、模块Module,统称模块
- turtle的原理(玩法)
- 有一只海龟在窗体中心,在布上游走
- 走过的轨迹成了图形
- 海龟可变颜色、宽度等
turtle绘图窗体布局
-
turtle的绘图窗体
-
在操作系统上表现为窗口,是turtle的画布空间,最小单位是像素
-
屏幕坐标系
-
左上角是(0,0)
-
turtle.setup(width,height,startx,starty)
设置窗体的宽度(横向),高度,x(横向),y
xy坐标即窗体左上角位置相对于屏幕左上角的坐标
setup函数非必须,其中最后两个参数也非必须
-
-
turtle空间坐标体系
-
绝对坐标
-
绝对坐标(0,0)在画布正中心,海龟初始朝向为右
-
右为x,上为y
-
turtle.goto(x,y)
指让海龟到达(x,y)
-
-
海龟坐标
- 根据海龟朝向,有前进方向,后退方向,左侧方向,右侧方向
- turtle.fd(d)向正前方运行,turtle.bk(d)向反方向运行
- turtle.circle(r,angle)是以海龟当前位置左侧一点为圆心曲线运行
turtle角度坐标体系
-
绝对角度
-
x轴正方向为0/360度,y轴正方向为90/-270度
-
turtle.seth(angle)
改变海龟行进角度(以度为单位)
-
-
海龟角度
- turtle.left(angle)/turtle.right(angle)
- 令海龟向左/右转angle度
RGB色彩体系
- RGB色彩模式
- 由三种颜色构成万物色(指红蓝绿的三个通道颜色组合)
- 覆盖视力所能感知的所有颜色
- 每色取值为0-255整数或0-1小数
-
常用RGB色彩
- white;255,255,255;1,1,1;白色
- yellow;255,255,0;1,1,0;黄色
- magenta;255,0,255;1,0,1;洋红
- cyan;0,255,255;0,1,1;青色
- blue;0,0,255;0,0,1;蓝色
- black;0,0,0;0,0,0;黑色
- seashell;255,245,238;1,0.96,0.93;海贝色
- gold;255,215,0;1,0.84,0;金色
- pink;255,192,203;1,0.75,0.80;粉红色
- brown;165,42,42;0.65,0.16,0.16;棕色
- purple;160,32,240;0.63,0.13,0.94;紫色
- tomato;255,99,71;1,0.39,0.28;番茄色
-
色彩模式切换
-
默认采用小数值,可切换为整数值
turtle.colormode(1.0)/turtle.colormode(255)
-
2.4 turtle程序语法元素分析
库引用与import
-
“turtle.”是<a>.<b>()的编码风格
-
库应用
-
扩充Python程序功能的方式
-
使用import保留字完成,<a>.<b>()的编码风格
-
使用时
import <库名>库名>
<库名>.<函数名>(<函数参数>) 函数参数>函数名>库名>
-
-
-
import更多用法
-
使用from和import保留字共同完成
from <库名> import <函数名>函数名>库名>
from <库名> import *库名>
<函数名>(<函数参数>) 函数参数>函数名> -
比较
- 以import库名的方式使用时的**<库名>.<函数名>**整个是新程序的函数名函数名>库名>
- 以from库名import*则库中函数的函数名就是独立的函数名
- 第一种方法不会出现函数重名的问题(因此在import很多库时用第一种)
-
使用import和as保留字共同完成
import <库名> as <库别名>库别名>库名>
<库别名>.<函数名>(<函数参数>) 即**给外部库关联一个更短、更适合的名字** 函数参数>函数名>库别名>
-
turtle画笔控制函数
-
画笔控制函数
-
画笔操作后一直有效,一般成对出现
-
turtle.penup()/turtle.pu()/turtle.up()(turtle库为编写者设计的冗余性函数)
抬起画笔,海龟飞行
-
turtle.pendown()/turtle.pd()
放下画笔
-
-
画笔设置后一直有效,直至下次重新设置
-
turtle.pensize(width)/turtle.width(width)
画笔宽度,海龟腰围
-
turtle.pencolor(color)color为颜色字符串或r,g,b值
画笔颜色,海龟涂装
其中color参数有三种形式
- 颜色字符串:turtle.pencolor(“purple”)
- RGB的小数值:turtle.pencolor(0.63,0.13,0.94)
- RGB的元组值:turtle.pencolor((0.63,0.13,0.94))
-
-
turtle运动控制函数
-
运动控制函数
-
控制海龟行进:直线/曲线
-
turtle.forward(d)/turtle.fd(d)
其中d可为负数(倒退)
-
turtle.circle(r,extent)
根据半径r(圆心在左侧r位置处)绘制一个extent角度的弧形
第二个参数无时默认360度整圆
-
-
turtle方向控制函数
-
方向控制函数
-
控制海龟面对方向:绝对角度/海龟角度
-
turtle.setheading(angle)/turtle.seth(angle)
将海龟转为绝对坐标下的angle角度方向
-
turtle.left(angle)
-
turtle.right(angle)
-
-
循环语句与range()函数
-
循环语句:按照一定次数循环执行一组语句
-
for <变量> in range (<参数>):参数>变量>
<被执行循环的语句>被执行循环的语句>
- <变量>表示每次循环次数(循环到了第几次),0到<次数>-1 次数>变量>
-
-
range()函数:产生循环计数序列
- range(n):产生0到n-1的整数序列,共n个数
- range(m,n):产生m到n-1的整数序列,共n-m个
for i in range(5):
print(i)
result:
0
1
2
3
4
#若
#for i in range(5):
# print("Hello:",i)
#result:
# Hello: 0
# Hello: 1
# Hello: 2
# Hello: 3
# Hello: 4
#可以发现print中的“,”起到了空格的作用
“Python蟒蛇绘制”代码分析
import turtle
turtle.setup(650,350,200,200)
turtle.penup()
turtle.fd(-250)
turtle.pendown()
turtle.pensize(25)
turtle.pencolor("purple")
turtle.seth(-40)
for i in range(4):
turtle.circle(40,80)
turtle.circle(-40,80)
turtle.circle(40,80/2)
turtle.fd(40)
turtle.circle(16,180)
turtle.fd(40*2/3)
turtle.done()
其中turtle.done()函数在使用文件式(而非交互式)编写时停止画笔绘制,程序运行之后,程序不会退出,需手工关闭窗体退出
练习
-
实例2: Python蟒蛇绘制
描述
这是”实例”题,与课上讲解实例相同,请作答检验学习效果。
使用turtle库,绘制一个蟒蛇形状的图形。
注意:这不是自动评阅题目,仅用于练习,没有评阅。
输出示例
输出效果如下:
import turtle as t
t.setup(650,350,200,200)
t.pu()
t.fd(-250)
t.pd()
t.pensize(25)
t.pencolor("purple")
t.seth(-40)
for i in range(4):
t.circle(40,80)
t.circle(-40,80)
t.circle(40,40)
t.fd(40)
t.circle(16,180)
t.fd(80/3)
t.done()
#PythonDraw.py
import turtle
turtle.setup(650, 350, 200, 200)
turtle.penup()
turtle.fd(-250)
turtle.pendown()
turtle.pensize(25)
turtle.pencolor("purple")
turtle.seth(-40)
for i in range(4):
turtle.circle(40, 80)
turtle.circle(-40, 80)
turtle.circle(40, 80/2)
turtle.fd(40)
turtle.circle(16, 180)
turtle.fd(40 * 2/3)
turtle.done()
-
turtle正方形绘制
描述
使用turtle库,绘制一个正方形。
注意:这不是自动评阅题目,仅用于练习,没有评阅。
##
输出示例
正方形效果如下:
import turtle as t t.pensize(6) t.goto(200,0) t.goto(200,200) t.goto(0,200) t.goto(0,0) t.done() #RectDraw.py import turtle as t t.pensize(2) for i in range(4): t.fd(150) t.left(90)
-
turtle六边形绘制
描述
使用turtle库,绘制一个六边形。
注意:这不是自动评阅题目,仅用于练习,没有评阅。
##
输出示例
六边形效果如下:
import turtle as t t.pensize(5) for i in range(6): t.fd(150) t.left(60) t.done() #HexagonDraw.py import turtle as t t.pensize(2) for i in range(6): t.fd(150) t.left(60)
-
turtle叠边形绘制
描述
使用turtle库,绘制一个叠边形,其中,叠边形内角为100度。
注意:这不是自动评阅题目,仅用于练习,没有评阅。
##
输出示例
叠边形效果如下:
import turtle as t t.pensize(3) for i in range(9): t.fd(150) t.left(80) t.done() #TwoRoundDraw.py import turtle as t t.pensize(2) for i in range(9): t.fd(150) t.left(80) #720/9
-
turtle风轮绘制
描述
使用turtle库,绘制一个风轮效果,其中,每个风轮内角为45度,风轮边长150像素。
注意:这不是自动评阅题目,仅用于练习,没有评阅。
提示:turtle.goto(x,y)函数,能够将turtle画笔移动到坐标(x,y)
输出示例
叠边形效果如下:
import turtle as t t.pensize(3) for i in range(4): t.fd(150) t.right(90) t.circle(-150,45) t.right(90) t.fd(150) t.left(135) t.done() #WindWheel.py import turtle as t t.pensize(2) for i in range(4): t.seth(90*i) t.fd(150) t.right(90) t.circle(-150, 45) t.goto(0,0)
测验
单项选择题
-
哪个选项不能正确引用turtle库进而使用setup()函数?
A. from turtle import*
B. import turtle as t
C. import turtle
D. import setup from turtle
D
import只有三种使用方法,以turtle库为例:
import turtle
from turtle import setup 或 from turtle import *
import turtle as t (其中t是别名,可以更换其他名称)
-
关于turtle库,哪个选项的描述是错误的?
A. turtle坐标系的原点默认在屏幕左上角
B. turtle库是一个直观有趣的图形绘制函数库
C. turtle绘图体系以水平右侧为绝对方位的0度
D. turtle库最早成功应用于LOGO编程语言
A
turtle坐标系的原点默认在窗体正中间
-
哪个选项是turtle绘图中角度坐标系的绝对0度方向?
A. 画布正左方
B. 画布正下方
C. 画布正上方
D. 画布正右方
D
坐标系类似这样,角度坐标系的绝对0度方向是右侧
-
哪个选项是下面代码的执行结果?
turtle.circle(-90,90)
A. 绘制一个半径为90像素的弧形,圆心在小海龟当前行进的右侧
B. 绘制一个半径为90像素的弧形,圆心在画布正中心
C. 绘制一个半径为90像素的整圆形
D. 绘制一个半径为90像素的弧形,圆心在小海龟当前行进的左侧
A
circle(x, y) 表示 以x长度为半径,y为角度,当前方向左侧x出为圆心,画圆。其中x和y都可以是负数,相应取反。
-
关于turtle库绘图函数,哪个选项的描述是错误的?
A. turtle.seth(to_angle)函数的作用是设置小海龟当前行进方向为to_angle,to_angle是角度的整数值
B. turtle.fd(distance)函数的作用是向小海龟当前行进方向前进distance距离
C. turtle.pensize(size)函数的作用是改变画笔的宽度为size像素
D. turtle.circle(radius, extent=None)函数的作用是绘制一个椭圆形,extent参数可选
D
circle()函数不能绘制椭圆形。
-
关于turtle库的画笔控制函数,哪个选项的描述是错误的?
A. turtle.width()和turtle.pensize()都可以用来设置画笔尺寸
B. turtle.penup()的别名有turtle.pu(),turtle.up()
C. turtle.pendown()作用是落下画笔,并移动画笔绘制一个点
D. turtle.colormode()的作用是设置画笔RGB颜色的表示模式
C
turtle.pendown()只是放下画笔,并不绘制任何内容。
-
哪个选项不能改变turtle画笔的运行方向?
A. right()
B. left()
C. bk()
D. seth()
C
bk()只能后退,但不改变方向,”后退”不是”转向”。
-
哪个选项所列保留字能够实现对一组语句的循环执行?
A. while和def
B. for和in
C. range()
D. if和else
B
循环相关保留字是:for..in和while,但def用于定义函数,不相关。
-
哪个选项能够使用turtle库绘制一个半圆形?
A. turtle.circle(100, -180)
B. turtle.circle(100, 90)
C. turtle.fd(100)
D. turtle.circle(100)
A
circle(x,y)函数的用法,绘制半圆,第二个参数y是180的奇数倍。
-
哪个选项对turtle.done()的描述是正确的?
A. turtle.done()用来隐藏turtle绘制画笔,一般放在代码最后
B. turtle.done()用来停止画笔绘制,但绘图窗体不关闭
C. turtle.done()用来暂停画笔绘制,用户响应后还可以继续绘制
D. turtle.done()放在代码最后,是turtle绘图的必要要求,表示绘制完成
B
建议在每个turtle绘图最后增加turtle.done()。
程序设计题
-
turtle八边形绘制
描述
使用turtle库,绘制一个八边形。
注意:这是一个自动评阅题目,请补充”编程模板”中横线内容,横线不保留。
输出示例
八边形效果如下:
#请在横线中填写Python表达式或语句,实现所需要的功能
#注意:补充代码将以匹配方式评阅,代码中不要出现空格
import turtle as t
t.pensize(2)
for i in range(_):
t.fd(100)
t.left(_)
import turtle as t
t.pensize(2)
for i in range(8):
t.fd(100)
t.left(45)
-
turtle八角图形绘制
描述
使用turtle库,绘制一个八角图形。
注意:这是一个自动评阅题目,请补充”编程模板”中横线内容,横线不保留。
输出示例
八角图形效果如下:
#请在横线中填写Python表达式或语句,实现所需要的功能 #注意:补充代码将以匹配方式评阅,代码中不要出现空格 import turtle as t t.pensize(2) for i in range(_): t.fd(150) t.left(_) import turtle as t t.pensize(2) for i in range(8): t.fd(150) t.left(135)
3.基本数据类型
3.1 数字类型及操作
整数类型
- 整数类型:与数学中整数概念一致
- 可正可负,没取值限制
- pow(x,y),计算$x^y$
- 四种进制表示形式
- 十进制
- 二进制,以0b/0B开头:0b010,-0B101
- 八进制,以0o/0O开头
- 十六进制,以0x/0X开头
浮点数类型
-
浮点类型:与数学实数概念一致
-
带有小数点及小数的数字
-
浮点数取值范围和小数精度都存在限制,常规计算下可忽略
-
取值范围约为$-10^{308}$到$10^{308}$,精度数量级$10^{-16}$
-
浮点数运算存在不确定尾数,不是bug
-
>>>0.1+0.3
0.4
>>>0.1+0.2
0.30000000000000004
-
这涉及到计算机的内部原理
计算机中所有数字都是用二进制表示
Python中用53位二进制表示小数部分
0.1的二进制是0.00011001100110011001100110011…
而计算机只能截取53位,无限接近0.1
因此二进制表示小数可无限接近,但不相同
所以0.1+0.2结果接近0.3而存在尾数
-
>>>0.1+0.2==0.3
False
>>>round(0.1+0.2,1)==0.3
True
round(x,d):对x四舍五入,d是小数截取位数#可用int(x)取整
-
浮点数运算及比较用round()函数辅助
-
不确定尾数一般发生在$10^{-16}$左右,round()十分有效
-
-
浮点数可用科学计数法表示
- 使用e/E为幂的符号,以10为基数
- <a>e<b>表示$a*10^b$
- 用这种方式表达比较大或非常小的浮点数
-
复数类型
-
复数类型:与数学中复数概念一致
-
$j=\sqrt{(-1)}$,a+bj被称为复数,a是实部,b是虚部
-
实例:z=1.23e-4+5.6e+89j
z.real获得实部
z.imag获得虚部
-
应用:复变函数
-
数值运算操作符
-
操作符是完成运算的一种符号体系
- x+y,x-y,x*y
- x/y,在其他一些语言中整数用/是整数除,而Python中仅是数学意义上的除
- x//y,整数除,10//3=3
- +x,x本身
- -y,y的负值
- x%y,求余/模运算,10%3=1
- x**y
- 幂运算,x的y次幂
- y为小数时开方运算,4**0.5=2
-
二元操作符有对应的增强赋值操作符:x op=y
- x+=y,x=x+y
- x-=y,x=x-y
- x*=y,x=x*y
- x/=y,x=x/y
- x//=y,x=x//y
- x%=y,x=x%y
- x**=y,x=x**y
-
类型间可以进行混合运算,生成结果为“最宽”类型
整数->浮点数->复数
如:123+4.0=127.0
数值运算函数
-
一些以函数形式提供的数值运算功能
-
abs(x),求x绝对值
-
divmod(x,y),商余,同时输出商和余数,divmod(10,3)结果是(3,1)(二元素)
-
pow(x,y[,z]),幂余,(x**y)%z,[…]表示z可省略
-
pow(3,pow(3,99),10000)得到了3的(3的99次方)次方的后四位
直接算pow(3,pow(3,99))无法在普通计算机中得到结果,会超出内存
通过余数z是运算始终保持在余数范围内
-
round(x[,d]),四舍五入,d是保留小数位数,默认为0(取整)
-
max(x1,x2,…,xn)返回其中最大值,n不限
-
min(x1,x2,…,xn)返回其中最小值,n不限
-
数值类型转换函数
-
int(x),将x变成整数,舍弃小数部分
int(123.45)=123;int(“123”)=123
-
float(x),将x变为浮点数,增加小数部分
float(12)=12.0;float(“1.23”)=1.23
-
complex(x),将x变为复数,增加虚数部分
complex(4)=4+0j
-
-
3.2 实例3:天天向上的力量
“天天向上的力量”问题分析
-
基本问题:持续的价值
-
一年365天,每天进步1%,累计进步多少呢
$1.01^{365}$
-
一年365天,每天进步1%,累计剩下多少呢
$0.99^{365}$
-
可以用数学公式求解,但用程序快
-
如果是“三天打鱼两天晒网”呢
-
如果是“双休日不退步”呢
-
“天天向上的力量”第一问
-
问题1:千分之一的力量
-
一年365天,每天进步1%。,累计进步多少呢
$1.001^{365}$
-
一年365天,每天退步1%。,累计退步多少呢
$0.999^{365}$
-
#DayDayUpQ1.py
dayup=pow(1.001,365)
daydown=pow(0.999,365)
print("向上:{:.2f},向下:{:.2f}".format(dayup,daydown))
向上:1.44,向下:0.69
“天天向上的力量”第二问
- 问题2:千分之五和百分之一的力量
- 一年365天,每天进步5%。或1%,累计进步多少呢
- 一年365天,每天退步5%。或1%。,累计退步多少呢
#DayDayUpQ2.py
dayfactor=0.005#引入变量的好处:只需一处修改即可
dayup=pow(1+dayfactor,365)
daydown=pow(1-dayfactor,365)
print("向上:{:.2f},向下:{:.2f}".format(dayup,daydown))
0.005时 向上:6.17,向下:0.16
0.01时 向上:37.78,向下:0.03
“天天向上的力量”第三问
-
问题3:工作日的力量
-
一年365天,一周5个工作日,每天进步1%
-
一年365天,一周2个休息日,每天退步1%
$1.01^{365}$(数学思维)=>for…in…(计算思维)
-
#DayDayUpQ3.py
dayup=1.0
dayfactor=0.01
for i in range(365):
if i%7 in [6,0]:
dayup=dayup*(1-dayfactor)
else:
dayup=dayup*(1+dayfactor)
print("工作日的力量:{:.2f}".format(dayup))
工作日的力量:4.63
介于千分之五和千分之一之间
“天天向上的力量”第四问
-
问题4:工作日的努力
-
工作日模式要努力到什么水平,才能与每天努力1%一样
-
A:一年365,每天进步1%
-
B:一年365,每周工作5,休息2,休息日下降1%,要多努力
for…in…(计算思维)=>def…while…(“笨方法”试错)
-
#DayDayUpQ4.py
def dayUP(df):
dayup=1
for i in range(365):
if i%7 in [6,0]:
dayup=dayup*(1-0.01)
else:
dayup=dayup*(1+df)
return dayup
#def保留字用于定义函数
#根据df参数计算工作日力量的函数
#参数不同,这段代码可以共用
dayfactor=0.01
while dayUP(dayfactor)<37.78:
dayfactor+=0.001
print("工作日的努力参数是:{:.3f}".format(dayfactor))
#while保留字判断条件是否成立
#条件成立时循环进行
工作日的努力参数是:0.019
GRIT:perseverance and passion for long-term goals
$1.01^{365}=37.78$ $1.019^{365}=962.89$
GRIT,坚毅,对长期目标的持续激情及持久耐力
GRIT是获得成功最重要的因素之一,牢记天天向上的力量
“天天向上的力量”举一反三
在Q3中
#DayDayUpQ3.py
dayup=1.0
dayfactor=0.01
for i in range(365):
if i%7 in [6,0]:
dayup=dayup*(1-dayfactor)
else:
dayup=dayup*(1+dayfactor)
print("工作日的力量:{:.2f}".format(dayup))
我们抛弃了数学思维,引入了计算思维for…in…,这种计算思维是抽象和自动化相结合的结果,计算机的算力使得抽象和自动化带来了问题的快速求解
在Q4中
#DayDayUpQ4.py
def dayUP(df):
dayup=1
for i in range(365):
if i%7 in [6,0]:
dayup=dayup*(1-0.01)
else:
dayup=dayup*(1+df)
return dayup
#def保留字用于定义函数
#根据df参数计算工作日力量的函数
#参数不同,这段代码可以共用
dayfactor=0.01
while dayUP(dayfactor)<37.78:
dayfactor+=0.001
print("工作日的努力参数是:{:.3f}".format(dayfactor))
#while保留字判断条件是否成立
#条件成立时循环进行
我们使用了def…while…试错,这也是计算机算力通过程序的体现
“天天向上的力量”中包含了:判断条件循环,次数循环,分支,函数,计算思维
- 问题的变化和拓展
- 工作日模式中,休息日不下降?
- 每天提高百分之一,休息下降千分之一?
- 工作3天休息一天?
- “三天打鱼两天晒网”?
- 努力>下降?下降>努力?
3.3 字符串类型及操作
字符串类型的表示
-
字符串:由0个或多个字符组成的有序字符序列
-
字符串由一对单引号/双引号表示
-
是字符的有序序列,可以对其中的字符进行索引(从0编号)
-
有2类4种表示方法
-
由一对单引号/双引号表示,仅表示单行字符串
-
一对三单引号/三双引号表示,可表示多行字符串(也可以起到多行注释的作用)
-
如果希望在字符串种包含双引号或单引号?
如果在字符串中希望出现双引号则两侧可用单引号
如果在字符串中希望出现单引号则两侧可用双引号
-
如果希望在字符串种包含双引号和单引号?
可以用三个单引号表示
-
-
-
字符串的序号
-
正向递增序号和反向递减序号
正向递增序号:0,1,2,…
反向递减序号:-1,-2,-3,…
-
-
字符串的使用:使用[]获取字符串中一个或多个字符串
- 索引:返回字符串中单个字符 <字符串>[M]字符串>
- 切片:返回字符串中一段字符子串 <字符串>[M:N]字符串>
-
字符串切片高级用法:使用[M:N:K]根据步长对字符串切片
- <字符串>[M:N],M缺失表示至开头,N缺失表示至结尾 字符串>
- <字符串>[M:N:K],根据步长K对字符串切片 "〇一二三四五六七八九十"[1:8:2]结果是"一三五七" 特别的,"〇一二三四五六七八九十"**[::-1]**结果是"十九八七六五四三二一〇"(从后向前逐一取出) 字符串>
-
字符串的特殊字符
-
转义符\
-
转义符表达特定字符的本意:即\后的字符将被当作字符本意理解
如:”这里有个双引号(")”结果为 这里有个双引号(“)
-
转义符形成一些组合,表达一些不可打印的含义
\b回退(使光标回退) \n换行(使光标移动到下行行首) \r回车(使光标移动到本行首)
-
-
字符串操作符
- 字符串操作符
- x+y连接两字符串x,y
- n*x或x*n复制n次字符串x
- x in s,如果x是s的子串,返回True,否则返回False
- 例子:获取星期字符串
- 输入:1-7的整数,表示星期几
- 输出:输入整数对应星期字符串
- 如:输入3,输出星期三
#WeekNamePrintV1.py
weekStr="星期一星期二星期三星期四星期五星期六星期日"
weekId=eval(input("请输入星期数字(1-7):"))
pos=(weekId-1)*3
print(weekStr[pos:pos+3])
#也可用ifelse逐一判断,但毫无疑问这种方式简单简洁
#WeekNamePrintV2.py
weekStr="一二三四五六日"
weekId=eval(input("请输入星期数字(1-7):"))
print("星期"+weekStr[weekId-1])
字符串处理函数
-
字符串处理函数:一些以函数形式提供的字符串处理功能
-
len(x),返回字符串x的长度
-
str(x),将任何类型的x转换为字符串形式(与eval()函数是一对对应的函数)
-
hex(x)/oct(x),将整数x转换为其十六进制/八进制小写形式的字符串
计算机内部运算用二进制完成=>二进制大量01对人类读取不友好=>人们喜欢十六/八进制来表示计算机内部运算形式
通过这两个函数可以将计算机的一些运算操作通过字符串的形式打印出来,尤其是程序员关心的系统级程序的使用
-
chr(u),u为Unicode编码,返回其对应字符
-
ord(x),x为字符,返回其对应的Unicode编码
-
-
Unicode编码:也是Python字符串的编码方式
-
统一字符编码,希望覆盖实际上所有字符
-
从0到1114111(0x10FFFF)空间,每个编码对应一个字符
-
Python字符串中每个字符都是Unicode编码字符
使得Python通用处理不同国家语言
-
有趣的例子
-
>>>“1+1=2”+chr(10004)
‘1+1=2✔’
-
>>>“这个字符♉的Unicode值是:”+str(ord(“♉”))
‘这个字符♉的Unicode值是:9801’
(可以输出chr(9800)~chr(9811),即十二个星座玩一下)
-
-
字符串处理方法
-
字符串处理方法
-
“方法”在编程中是一个专有名词
-
“方法”特指<a>.<b>()风格中的函数<b>()
-
“方法”本身也是函数但与<a>有关,<a>.<b>()风格使用
-
字符串及变量也是<a>,存在一些“方法”
-
本课程仅讲解基本语法体系,而不讲解面向对象编程
事实上,<a>.<b>()风格恰恰是面向对象的使用风格,其中<a>是对象,<b>是某对象能提供的功能,叫方法
“方法”是面向对象编程里的专有名词,这里是借用
注意,方法必须要用“.”的形式执行
-
-
一些以方法形式提供的字符串处理功能
-
str.lower()或str.upper(),返回字符串副本,使得字符串中的字符全小写/大写
-
str.split(sep=None),返回一个列表,由str根据sep被分隔部分组成;如:”A,B,C”.split(“,”)结果为[‘A’,’B’,’C’]
默认根据空格分隔
-
str.count(sub),返回子串sub在str中出现的次数
-
str.replace(old,new),返回字符串str的副本,所有old子串被替换为new
注意使用时str=str.replace(old,new)
-
str.center(width[,fillchar]),字符串str在宽度width中居中,fillchar可选,用于填充空白;如:”python”.center(20,”=”)结果为’=======python=======’
-
str.strip(chars),从str中去掉在其左侧和右侧chars中列出的字符;如:”= python= “.strip(“ =np”)结果为’ytho’
-
str.join(iter),在iter变量除最后一个元素外每个元素后增加一个str;如:”,”.join(“12345”)结果为”1,2,3,4,5”#主要用于字符串分隔等
-
-
字符串类型的格式化
-
字符串类型的格式化:格式化是对字符串进行格式表达的方式
-
字符串格式化使用.format()方法,用法如下:
<模板字符串>.format(<逗号分隔的参数>) 逗号分隔的参数>模板字符串> -
槽:一对占位信息符,用”{}”表示,只在字符串中有用
如:”{}:计算机{}的CPU占用率为{}%”.format(“2018-10-10”,”C”,10)
其中默认状态下槽与format中参数一一对应,从0开始编号
当然也可以将参数按需要的顺序填入槽中
如:”{1}:计算机{0}的CPU占用率为{2}%”.format(“2018-10-10”,”C”,10)
-
-
format()方法的格式控制
-
槽内部对格式化的配置方式
{<参数序号>:<格式控制标记>}格式控制标记>参数序号>
- <填充>、<对齐>、<宽度> - 填充:用于填充的单个字符 - 对齐:<左对齐、>右对齐、^居中对齐 - 宽度:槽设定的输出宽度 - \>\>\>"{0:=^20}".format("PYTHON") '\=\=\=\=\=\=\=PYTHON\=\=\=\=\=\=\=' - \>\>\>"{0:*>20}".format("BIT") '\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*BIT' - \>\>\>"{:10}".format("BIT") 'BIT ' 宽度>对齐>填充>
-
<,>、<.精度>、<类型>类型>
-
,:数字的千位分隔符(输出的数字字符串便于阅读)
-
.精度:浮点数小数精度或字符串最大输出长度
-
类型:整数类型b,c,d,o,x,X浮点数类型e,E,f,%
-
>>>“{0:,.2f}”.format(12345.6789)
‘12,345.68’
-
>>>“{0:b},{0:c},{0:d},{0:o},{0:x},{0:X}”.format(425)
‘110101001,Ʃ,425,651,1a9,1A9’
- b:二进制形式
- c:Unicode编码形式
- d:十进制形式
- o:八进制形式
- x:十六进制形式
- X:大写的十六进制形式
-
>>>“{0:e},{0:E},{0:f},{0:%}”.format(3.14)
‘3.140000e+00,3.140000E+00,3.140000,314.000000%’
- e:科学计数法e形式
- E:科学计数法E形式
- f:通常的,非科学计数法形式
- %:百分数形式
-
-
3.4 模块2:time库的使用
time库基本介绍
-
time库是Python中处理时间的标准库
-
计算机时间的表达
-
提供获取系统时间并格式化输出的功能
-
提供系统级精确计时功能,用于程序性能分析
-
使用:
import time
time.<b>()
-
-
time库包括三类函数
- 时间获取:time(),ctime(),gmtime()
- 时间格式化:strftime(),strptime()
- 程序计时:sleep(),perf_counter()
时间获取
-
time():获取当前时间戳,即计算机内部时间值,浮点数,表示从1970.1.1,0:00开始到当前,以秒为单位的数值
>>>time.time()
1596614684.456416
-
ctime():获取当前时间并以易读方式表示,返回字符串
>>>time.ctime()
‘Wed Aug 5 16:06:32 2020’
-
gmtime():获取当前时间,表示为计算机可处理的时间格式
>>>time.gmtime()
time.struct_time(tm_year=2020, tm_mon=8, tm_mday=5, tm_hour=8, tm_min=8, tm_sec=4, tm_wday=2, tm_yday=218, tm_isdst=0)
时间格式化
-
将时间以合理方式展示出来
-
格式化:类似字符串格式化,需要展示模板
-
展示模板由特定格式化控制符组成
-
strftime()方法
-
strftime(tpl,ts)
-
tpl是格式化模板字符串,用来定义输出效果
-
ts是计算机内部时间类型变量
-
>>>time.strftime(“%Y-%m-%d %H:%M:%S”,time.gmtime())
‘2020-08-05 08:13:11’
-
tpl中
- %Y:年份,数字
- %m:月份,数字
- %B:月份英文名
- %b:月份英文名缩写
- %d:日期,数字
- %A:英文的星期
- %a:英文星期缩写
- %H:小时(24h),数字
- %I(大写i):小时(12h),数字
- %p:AM/PM
- %M:分钟,数字
- %S:秒,数字
-
-
strptime()方法
-
与strftime()操作相反,相当于反格式化
-
>>>time.strptime(‘2020-08-05 08:13:11’,”%Y-%m-%d %H:%M:%S”)
time.struct_time(tm_year=2020, tm_mon=8, tm_mday=5, tm_hour=8, tm_min=13, tm_sec=11, tm_wday=2, tm_yday=218, tm_isdst=-1)
-
-
程序计时应用
-
程序计时
-
程序计时应用广泛
- 程序计时指测量起止动作所经历时间的过程
- 即一段程序开始到结束用时
- 测量时间:perf_counter()
- 产生时间:sleep()
-
perf_counter()
-
返回CPU级别(纳秒)精确的时间计数值,单位为秒
-
由于计数值起点不确定,连续调用取差值才有意义
-
-
sleep(s)
- s为让程序休眠的时间,单位是秒,可以是浮点数
-
3.5 实例4:文本进度条
“文本进度条”实例分析
- 需求分析
- 文本进度条
- 采用字符串方式打印可以动态变化的文本进度条
- 需要能在一行中逐渐变化
- 文本进度条
- 问题分析
- 如何获得文本进度条的变化时间?
- 采用sleep()模拟一个持续的进度
- 用字符串模拟,不难
- 如何获得文本进度条的变化时间?
“文本进度条”简单的开始
#TextProBarV1.py
import time
scale=10
print("------执行开始------")
for i in range(scale+1):
a='*'*i
b='.'*(scale-i)
c=(i/scale)*100
print("{:^3.0f}%[{}->{}]".format(c,a,b))
time.sleep(0.1)
print("------执行结束------")
”文本进度条“单行动态刷新
- 单行动态刷新
- 刷新的本质是:用后打印的字符覆盖之前的字符
- 不能换行:print()需要被控制
- 要能回退:打印后光标退回到之前的位置(当前行的行首)\r
#TextProBarV2.py
import time
for i in range(101):
print("\r{:3}%".format(i),end="")
time.sleep(0.1)
可是这段程序在IDLE里的输出却并不能看到单行刷新的效果
因为IDLE本身是一个编写程序的开发环境,不是程序运行的主要环境,正常运行程序通过双击/控制台,IDLE为保证其中参数的运行效果,就把\r功能屏蔽了
windows下看到运行效果的方法:
- 按住shift同时右键py文件所在文件夹
- 选择在此处打开powershell窗口
- 在窗口中输入python TextProBarV2.py(即用这样的命令执行程序)
”文本进度条“实例完整效果
#TextProBarV3.py
import time
scale=50
print("执行开始".center(scale//2,"-"))
start=time.perf_counter()
for i in range(scale+1):
a='*'*i
b='.'*(scale-i)
c=(i/scale)*100
dur=time.perf_counter()-start
print("\r{:^3.0f}%[{}->{}]{:.2f}s".format(c,a,b,dur),end='')
time.sleep(0.1)
print("\n"+"执行结束".center(scale//2,'-'))
”文本进度条“举一反三
-
计算问题拓展
- 文本进度条程序使用了perf_counter()计时
- 计时方法适合各类需要统计时间的计算问题
- 例如:比较不同算法时间、统计部分程序运行时间
-
进度条拓展
-
在任何运行时间需要较长的程序中增加进度条
-
在任何希望提高用户体验的应用中增加进度条
-
进度条是人机交互的纽带之一
-
我们有很多种让计算机展示进度的方式
-
如在计算机下载了90%时展示为10%或下载了10%时展示为90%
-
科学家在某次实验中用了9种算法并观察用户体验
为Linear,Early Pause,Late Pause,Slow Wavy,Fast Wavy,Power,Inverse Power,Fast Power,Inverse Fast Power,有兴趣可查
结论是:速度上显得先慢后快的更符合人类心理需求
-
-
练习
-
实例3:天天向上的力量
描述
这是”实例”题,与课上讲解实例相同,请作答检验学习效果。
工作日模式要努力到什么水平,才能与每天努力1%一样?
-A君: 一年365天,每天进步1%,不停歇
-B君: 一年365天,每周工作5天休息2天,休息日下降1% ,要多努力呢?
每周工作5天休息2天,计算工作日的努力参数是多少才能与每天努力1%一样。
要求如下:
(1) 一年365天,以第0天的能力值为基数,记为1.0;
(2) 当好好学习时,能力值相比前一天提高1%;当没有学习时,由于遗忘等原因能力值相比前一天下降1%;
## 输出
输出结果格式如下:(其中结果保留小数点后三位,冒号后有一个空格)
工作日的努力参数是: 0.019
a=1
for i in range(365):
a=a*1.01
def gao(improve):
b=1
for i in range(365):
if i%7 in [0,6]:
b=b*0.99
else:
b=b*(1+improve)
return b<a
b=0.01
while(gao(b)):
b+=0.001
print("工作日的努力参数是: {:.3f}".format(b))
-
实例4:文本进度条
描述
这是”实例”题,与课上讲解实例相同,请作答检验学习效果。
采用字符串方式打印可以动态变化的文本进度条,进度条需要能在一行中逐渐变化
要求如下:
(1) 采用sleep()模拟一个持续的进度,获得文本进度条的变化时间;
(2) 通过print()函数实现单行动态刷新,在print()函数中更换参数end的默认值为’‘,每次使用print()函数输出时不能换行;
(3) 要能回退:打印后光标到之前的位置 \r。
请在Windows的命令行(cmd或PowerShell)或其他操作系统的命令行下执行Python程序,获得进度条效果。
## 输出
import time
a=50
print("执行开始".center(a//2,'-'))
g=time.perf_counter()
for i in range(a+1):
b=i*'*'
c=(a-i)*'.'
d=(i/a)*100
e=time.perf_counter()-g
print("\r{:3.0f}%[{}->{}]{:.2f}s".format(d,b,c,e),end='')
time.sleep(0.1)
print("\n"+"执行结束".center(a//2,'-'))
-
三次方格式化
描述
获得用户输入的一个数字,可能是整数或浮点数,a,计算a的三次方值,并打印输出。
输出结果采用宽度20个字符、居中输出、多余字符采用减号(-)填充。
如果结果超过20个字符,则以结果宽度为准。
输入输出示例
输入 输出 示例 1 10
--------1000--------
a=input() print("{:-^20}".format(pow(eval(a),3)))
-
星号三角形
描述
读入一个整数N,N是奇数,输出由星号字符组成的等边三角形,要求:
第1行1个星号,第2行3个星号,第3行5个星号,依次类推,最后一行共N的星号。
输入输出示例
输入 输出 示例 1 3
` * ***` a=eval(input()) b=1 while(a!=b): print("{0:^{1}}".format('*'*b,a))#这行用了控制输出宽度为输入的a的操作 b+=2 print("{}".format(a*'*')) n = eval(input()) for i in range(1,n+1,2): print("{0:^{1}}".format('*'*i, n)) 关键是对.format()中槽机制的理解,槽中可以嵌套槽,用来表示宽度、填充等含义。
-
恺撒密码
描述
恺撒密码是古罗马恺撒大帝用来对军事情报进行加解密的算法,它采用了替换方法对信息中的每一个英文字符循环替换为字母表序列中该字符后面的第三个字符,即,字母表的对应关系如下:
原文:A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
密文:D E F G H I J K L M N O P Q R S T U V W X Y Z A B C
对于原文字符P,其密文字符C满足如下条件:C=(P+3) mod 26
上述是凯撒密码的加密方法,解密方法反之,即:P=(C-3) mod 26
假设用户可能使用的输入包含大小写字母a~zA~Z、空格和特殊符号,请编写一个程序,对输入字符串进行恺撒密码加密,直接输出结果,其中空格不用进行加密处理。使用input()获得输入。
## 输入
示例1: python is good
## 输出
示例1: sbwkrq lv jrrg
#s=input()
#for i in range(len(s)):
# if ('a'<=s[i] and s[i]<='z') or ('A'<=s[i] and s[i]<='Z'):
# if('a'<=s[i] and s[i]<='z'):
# s[i]=chr((((ord(s[i])-ord('a'))+3)%26)+ord('a'))
# else:
# s[i]=chr((((ord(s[i])-ord('A'))+3)%26)+ord('A'))
#print(s)
#wrong
#s=input()
#for i in range(26):
# s=s.replace(chr(ord('a')+i),chr(((i+3)%26)+ord('a')))
# s=s.replace(chr(ord('A')+i),chr(((i+3)%26)+ord('A')))
#print(s)
#wrong
s=input()
t=""
for i in range(len(s)):
if ('a'<=s[i] and s[i]<='z') or ('A'<=s[i] and s[i]<='Z'):
if('a'<=s[i] and s[i]<='z'):
t+=chr((((ord(s[i])-ord('a'))+3)%26)+ord('a'))
else:
t+=chr((((ord(s[i])-ord('A'))+3)%26)+ord('A'))
else:
t+=s[i]
print(t)
s = input()
t = ""
for c in s:
if 'a' <= c <= 'z':
t += chr( ord('a') + ((ord(c)-ord('a')) + 3 )%26 )
elif 'A' <= c <= 'Z':
t += chr( ord('A') + ((ord(c)-ord('A')) + 3 )%26 )
else:
t += c
print(t)
#恺撒密码加密算法由很多种编写方法,这是一种很直接的方法。
测验
单项选择题
-
pow(x, 0.5)能够计算x的平方根,计算负数的平方根将产生:
A. 程序崩溃
B. 无输出
C. ValueError错误
D. 复数
D
>>> pow(-1, 0.5) (6.123233995736766e-17+1j)
-
以下关于字符串.strip()方法功能说明正确的是:
A. 去掉字符串两侧指定字符
B. 连接两个字符串序列
C. 按照指定字符分割字符串为数组
D. 替换字符串中特定字符
A
“去掉字符串两侧指定字符”对应功能是.strip()
“按照指定字符分割字符串为数组”对应功能是.split()
“替换字符串中特定字符”对应功能是.replace()
“连接两个字符串序列”对应功能是+操作符
-
字符串是一个连续的字符序列,哪个选项可以实现打印字符信息的换行?
A. 使用空格
B. 使用“\换行”
C. 使用转义符\\
D. 使用\n
D
换行符\n,与C语言中一致。
-
val=pow(2,1000),请用一行代码返回val结果的长度值。
A. 其他答案均不正确
B. len(val)
C. len(str(val))
D. len(pow(2,1000))
C
len(str(val))首先通过str(val)将数字类型val变成字符串,再通过len()获得字符串长度,即val的数字个数。
-
下面关于time库引用不正确的是?
A. from time import *
B. from time import strftime
C. from * import time
D. import time
C
from * import time 应该是: from time import *
-
哪个选项不是Python语言的整数类型?
A. 0B1010
B. 0E99
C. 0x9a
D. 88
B
十进制:一般表示
二进制:0b 或 0B 开头
八进制:0o 或 0O 开头
十六进制:0x 或 0X 开头
没有0E开头
-
关于整数类型的4种进制表示,哪个选项的描述是正确的?
A. 二进制、四进制、八进制、十进制
B. 二进制、四进制、十进制、十六进制
C. 二进制、八进制、十进制、十六进制
D. 二进制、四进制、八进制、十六进制
C
Python不支持四进制整数
-
哪个选项是Python语言%运算符的含义?
A. x与y的整数商
B. x与y之商
C. x的y次幂
D. x与y之商的余数
D
%是取余数,与C语言相同。
-
哪个选项是下面代码的执行结果?
name="Python语言程序设计课程" print(name[0],name[2:-2],name[-1])
A. P thon语言程序设计 程
B. P thon语言程序设计课 课
C. P thon语言程序设计课 程
D. P thon语言程序设计 课
A
s[N:M]表示对字符串s的切片操作,从N到M,但不包含M
-
哪个选项是下面代码的执行结果?
s='PYTHON' print("{0:3}".format(s))
A. PYTHON
B. PYTHON
C. PYTH
D. PYT
B
{0:3}表示输出的宽度是3,但如果字符串超过长度3,则以字符串长度显示。
程序设计题
-
平方根格式化
描述
获得用户输入的一个整数a,计算a的平方根,保留小数点后3位,并打印输出。
输出结果采用宽度30个字符、右对齐输出、多余字符采用加号(+)填充。
如果结果超过30个字符,则以结果宽度为准。
输入输出示例
输入 输出 示例 1 10
+++++++++++++++++++++++++3.162
a=eval(input()) a=pow(a,0.5) print("{:+>30.3f}".format(a)) 【参考代码】 a = eval(input()) print("{:+>30.3f}".format(pow(a, 0.5))) 这是一个简单题,重点在于理解格式化输出的方法。 注意:如果平凡根后产生一个复数,由于复数的实部和虚部都是浮点数,.3f可以将实部和虚部分别取三位小数。
-
字符串分段组合
描述
获得输入的一个字符串s,以字符减号(-)分割s,将其中首尾两段用加号(+)组合后输出。
输入输出示例
输入 输出 示例 1 Alice-Bob-Charis-David-Eric-Flurry
Alice+Flurry
s=input() a=0 while(s[a]!='-'):a+=1 b=len(s)-1 while(s[b]!='-'):b-=1 print("{}+{}".format(s[:a],s[b+1:])) 参考代码如下: s = input() ls = s.split("-") print("{}+{}".format(ls[0], ls[-1])) s.split(k)以k为标记分割s,产生一个列表。通过该题目,掌握split()方法的使用,注意:k可以是单字符,也可以是字符串。
4.程序的控制结构
4.1 程序的分支结构
单分支结构
-
单分支结构:根据判断条件结果而选择不同向前路径的运行方式
if<条件>:<语句块>语句块>条件>
二分支结构
-
二分支结构:根据判断条件结果而选择不同的向前路径的运行方式
if<条件>:<语句块1>语句块1>条件>
else:<语句块2>语句块2>
-
紧凑形式:适用于简单表达式的二分支结构
<表达式1> if <条件> else <表达式2> 表达式2>条件>表达式1>
guess=eval(input())
if guess==99:
print("猜对了")
else:
print("猜错了")
guess=eval(input())
print("猜{}了".format("对" if guess=99 else "错"))
#注意这种紧凑形式是有返回值的表达式而不是一段语句
#也有类似这样的紧凑形式:n_ = n_+1 if n_ < n else n_
#但是请注意把n_+1 if n_ < n else n_当作整体理解
多分支结构
-
多分支结构:根据多个条件来选择不同语句块运行的一种分支机构
if<条件>:<语句块>语句块>条件>
elif<条件>:<语句块>语句块>条件>
elif<条件>:<语句块>语句块>条件>
…
else:<语句块>语句块>
条件判断及组合
- 条件判断
- 操作符
- < 小于
- <= 小于等于
- >= 大于等于
- > 大于
- == 等于
- != 不等于
- 用于条件组合的保留字
- x and y:xy两个条件的逻辑与
- x or y:xy两个条件的逻辑或
- not x:x的逻辑非
- 操作符
程序的异常处理
举例
num=eval(input("请输入一个整数:"))
print(num**2)
如果用户输入的是字符串abc,程序会异常退出,并给出异常信息
Traceback(most recent call last):
File "t.py", line 1,in <module>
num=eval(input("请输入一个整数:"))
File "<string>", line 1,in <module>
NameError: name 'abc' is not defined
其中“line 1”表示异常发生的代码行数
“NameError”是异常类型#重要
“name 'abc' is not defined”是异常内容提示,输入的'abc'经过eval处理,去掉引号变成了变量abc,而变量abc没有被定义
-
异常处理的基本使用
try:<语句块1>语句块1>
except:<语句块2>语句块2>
要执行的程序放语句块1,如果出现异常则执行语句块2,不出现异常则跳过语句块2
也有
try:<语句块1>语句块1>
except<异常类型>:<语句块2>语句块2>异常类型>
仅当出现的异常类型为except后指示的异常时执行语句块2
try:
num=eval(input("请输入一个整数:"))
print(num**2)
except:
print("输入不是整数")
或者
try:
num=eval(input("请输入一个整数:"))
print(num**2)
except NameError:
print("输入不是整数")
-
异常处理的高级使用方法
try:<语句块1>语句块1>
except:<语句块2>语句块2>
else:<语句块3>语句块3>
finally:<语句块4> 当执行语句块1不发生异常,执行语句块3,如果发生异常,执行语句块2,但最后无论发不发生异常都执行语句块4语句块4>
4.2 实例5:身体质量指数BMI
问题分析
-
BMI:对身体质量的刻画(Body Mass Index)
-
BMI=体重(kg)/身高(m)的平方
-
国际:世界卫生组织;国内:国家卫生健康委员会
分类:
国际BMI 国内BMI
偏瘦 <18.5 <18.5
正常 18.5~25 18.5~24
偏胖 25~30 24~28
肥胖 >=30 >=28
-
问题需求
- 输入:给定体重和升高值
- 输出:BMI指标分类信息(国际和国内)
实例讲解
- 思路方法
- 难点在于同时输出国际和国内对应的分类
- 思路1:分别计算并给出国际和国内BMI分类
- 思路2:混合计算并给出国际和国内BMI分类
#CalBMIv1.py
height,weight=eval(input("请输入身高(米)和体重\(公斤)[逗号隔开]:"))
bmi=weight/pow(height,2)
print("BMI 数值为:{:.2f}".format(bmi))
who=""
if bmi<18.5:
who="偏瘦"
elif 18.5<=bmi<25:
who="正常"
elif 25<=bmi<30:
who="偏胖"
else:
who="肥胖"
print("BMI 指标为:国际'{0}'".format(who))
#CalBMIv2.py
height,weight=eval(input("请输入身高(米)和体重\(公斤)[逗号隔开]:"))
bmi=weight/pow(height,2)
print("BMI 数值为:{:.2f}".format(bmi))
nat=""
if bmi<18.5:
nat="偏瘦"
elif 18.5<=bmi<24:
nat="正常"
elif 24<=bmi<28:
nat="偏胖"
else:
nat="肥胖"
print("BMI 指标为:国内'{0}'".format(nat))
#CalBMIv3.py
height,weight=eval(input("请输入身高(米)和体重\(公斤)[逗号隔开]:"))
bmi=weight/pow(height,2)
print("BMI 数值为:{:.2f}".format(bmi))
who,nat="",""
if bmi<18.5:
who,nat="偏瘦","偏瘦"
elif 18.5<=bmi<24:
who,nat="正常","正常"
elif 24<=bmi<25:
who,nat="正常","偏胖"
elif 25<=bmi<28:
who,nat="偏胖","偏胖"
elif 28<=bmi<30:
who,nat="偏胖","肥胖"
else:
who,nat="肥胖","肥胖"
print("BMI 指标为:国内'{0}',国内'{1}'".format(who,nat))
举一反三
- 关注多分支条件的组合
- 多分支条件之间的覆盖是重要问题
- 避免程序可运行,但不正确的情况,注意多分支
- 分支结构是程序的重要框架,读程序优先看分支,再看细节
4.3 程序的循环结构
遍历循环
-
遍历循环:遍历某个结构形成的循环运行方式
-
for <循环变量> in <遍历结构>:遍历结构>循环变量>
<语句块>语句块>
-
从遍历结构中逐一提取元素,放在循环变量中
-
由保留字for和in组成,完整遍历所有元素后结束
-
每次循环,所获得元素放入循环变量,并执行一次语句块(在语句块中可以使用循环变量)
-
-
遍历循环的运用
-
计数循环(N次)
for i in range(N):
<语句块>语句块>
遍历由range()函数产生的数字序列,产生循环
-
计数循环(特定次)
for i in range(M,N,K):
<语句块>语句块>
如
>>>for i in range(1,6):
print(i)
1
2
3
4
5
>>>for i in range(1,6,2)
print(“Hello:”,i)
Hello:1
Hello:3
Hello:5
-
字符串遍历循环
for c in s:
<语句块>语句块>
s是字符串,遍历字符串中每个字符c,产生循环
如
>>>for c in “Python123”
print(c,end=”,”)
P,y,t,h,o,n,1,2,3,
-
列表遍历循环
for item in ls:
<语句块>语句块>
ls是一个列表,遍历其中每个元素,产生循环
如
>>>for item in [123,”PY”,456]:
print(item,end=”,”)
123,PY,456,
-
文件遍历循环
for line in fi:
<语句块>语句块>
fi是一个文件标识符,遍历其每行,产生循环
- 文件标识符:对外部一个文件用Python的函数打开,如果该文件是以字符形式打开,那么它就会表现为文件的标识的名字。即用一个变量标识系统中的一个文件,这个变量就是文件标识符。
-
元组,字典类型遍历循环。。。
-
掌握概念:遍历结构是一个由多个元素构成的数据类型,就可以用for in的方式遍历它,遍历次数即该遍历结构的元素个数
-
无限循环
-
无限循环:由条件控制的循环运行方式
while <条件>:条件>
<语句块>语句块>
反复执行语句块,直到条件不满足时退出
如
>>>a=3
>>>while a>0:
a=a-1
print(a)
2
1
0
>>>a=3
>>>while a>0:
a=a+1
print(a)
4
5
…(一直输出,可按CTRL+C退出执行)
循环控制保留字
- break:跳出并结束当前整个循环,执行循环后的语句
- continue:结束当次循环,继续执行后续次数循环
- 两者都可与for/while搭配
如
>>>for c in “PYTHON”:
if c==”T”:
continue
print(c,end=””)
PYHON
>>>for c in “PYTHON”:
if c==”T”:
break
print(c,end=””)
PY
break退出当前整个循环啥意思啊?如下
>>>s=”PYTHON”
>>>while s!=””
for c in s:
print(c,end=””)
s=s[:-1]
PYTHONPYTHOPYTHPYTPYP
>>>s=”PYTHON”
>>>while s!=””
for c in s:
if c == “T”:
break
print(c,end=””)
s=s[:-1]
PYPYPYPYPYP
即break退出的是当前整个即for循环,而不会退出while循环,一个break跳出一层循环(最内层)
循环的高级用法
-
循环与else
for <循环变量> in <遍历结构>:遍历结构>循环变量>
<语句块1>语句块1>
else:
<语句块2>语句块2>
while <条件>:条件>
<语句块1>语句块1>
else:
<语句块2>语句块2>
-
当循环没有被break语句退出时,执行else语句块
- else语句块可看作”正常“完成循环的奖励
- 这里的else用法与异常处理中else用法相似
如
>>>for c in “PYTHON”:
if c==”T”:
continue
print(c,end=””)
else:
print(“正常退出”)
PYHON正常退出
>>>for c in “PYTHON”:
if c==”T”:
break
print(c,end=””)
else:
print(“正常退出”)
PY
-
4.4 模块3:random库的使用
random库基本介绍
-
random库概述:random库是使用随机数的Python标准库(随Python解释器安装)
小tip:计算机无法真正产生随机数,它所谓的随机数是用一种特定方法计算出来的看似随机的特定数
- 伪随机数:采用梅森旋转算法生成的(伪)随机序列中元素
- random库主要用于生成随机数
- 使用:import random
-
random库的函数
- random库包括两类函数,常用的有8个
- 基本随机数函数:seed(),random()
- 扩展随机数函数:randint(),getrandbits(),uniform(),randrange(),choice(),shuffle()
基本随机数函数
-
随机数种子
如给定随机数种子10,根据梅森旋转算法,整出随机序列,其中的每个数就“叫”随机数
-
seed(a=None)
初始化给定的随机种子,默认为当前系统时间
>>>random.seed(10)#产生种子10对应的序列
当然,在使用随机数的时候可不用这个函数,直接用random()函数,这时它将使用当前操作系统的默认系统时间为种子
-
random()
生成一个[0.0,1.0)之间的随机小数
>>>random.random()
0.5714025946899135
产生的随机小数与种子有关,如用了种子10,那么产生的第一个随机小数一定是上面的0.57
如
>>>import random
>>>random.seed(10)
>>>random.random()
0.5714025946899135
>>>random.random()
0.4288890546751146
…
给定随机数种子可以复现程序的运算过程,而不会让程序因为采用系统时间为种子造成每次程序的运算结果不同
如
>>>import random
>>>random.seed(10)
>>>random.random()
0.5714025946899135
>>>random.seed(10)
>>>random.random()
0.5714025946899135
扩展随机数函数
-
randint(a,b)
生成一个[a,b]之间的整数
>>>random.randint(10,100)
64
-
randrange(m,n[,k])
生成一个[m,n)之间以k为步长的随机整数
>>>random.randrange(10,100,10)
80
-
getrandbits(k)
生成一个k比特长的随机整数
>>>random.getrandbits(16)
37885
-
uniform(a,b)
生成一个[a,b]之间的随机小数
>>>random.uniform(10,100)
13.096321648808136
-
choice(seq)
从序列seq中随机选择一个元素
>>>random.choice([1,2,3,4,5,6,7,8,9])
8
-
shuffle(seq)
将序列seq中元素随机排列,返回打乱后的序列
>>>s=[1,2,3,4,5,6,7,8,9];random.shuffle(s);print(s)
[3,5,8,9,6,1,2,7,4]
-
随机数函数的使用
- 需要掌握的能力
- 能够利用随机数种子产生“确定”伪随机数
- 能够产生随机整数
- 能够对序列类型进行随机操作
- 需要掌握的能力
4.5 实例6:圆周率的计算
“圆周率的计算”问题分析
-
圆周率的近似计算公式
$\pi=\sum_{k=0}^{\infty}[\frac{1}{16^{k}}(\frac{4}{8k+1}-\frac{2}{8k+4}-\frac{1}{8k+5}-\frac{1}{8k+6})]$
-
工程上:蒙特卡罗方法
圆周率相当于单位圆的面积去除以边长为2的正方形的面积
那么对于“边长为2的正方形框住单位圆”的图形,对它进行“撒点”,每个点随机出现在图形中,如果给出点的数量足够庞大,就可以通过正方形的面积、撒在圆和正方形中点的数量的比值计算出圆的面积
“圆周率的计算”实例讲解
- 圆周率的近似计算公式
#CalPiV1.py
pi=0
N=100
for k in range(N):
pi+=1/pow(16,k)*( \
4/(8*k+1)-2/(8*k+4)- \
1/(8*k+5)-1/(8*k+6))
print("圆周率值是:{}".format(pi))
用\换行后的代码和写在一行是一致的,可增加可读性
- 蒙特卡罗方法
#CalPiV2.py
from random import random
from time import perf_counter
DARTS=1000*1000
hits=0.0
start=perf_counter()
for i in range(1,DARTS+1):
x,y=random(),random()
dist=pow(x**2+y**2,0.5)
if dist<=1.0:
hits=hits+1
pi=4*(hits/DARTS)
print("圆周率值是:{}".format(pi))
print("运行时间是:{:.5f}s".format(perf_counter()-start))
“圆周率的计算”举一反三
-
理解方法思维
-
数学思维:找到公式,利用公式求解
-
计算思维:抽象一种过程,用计算机自动化求解
-
谁更准确?
-
存在精确公式时数学思维当然准确,但不是每个问题都有精确公式
- 当对精度要求不大时可以用数学思维(近似公式),要求大时可采用计算思维(更多次随机,结果更精确)
- 四色定理:并不能用数学公式解决,最终是由计算机用计算思维解决的
-
-
- 程序运行时间分析
- 使用time库的计时方法获得程序运行时间
- 改变撒点数量,理解程序运行时间的分布
- 一般来说,一个程序的主要运行时间应该都花在循环上
- 初步掌握简单的程序性能分析方法
- 计算问题的扩展
- 不求解圆周率,而是某个特定图形面积
- 在工程计算中寻找蒙特卡罗方法的应用场景
练习
-
实例5:身体质量指数BMI
描述
这是”实例”题,与课上讲解实例相同,请作答检验学习效果。
BMI :Body Mass Index 国际上常用的衡量人体肥胖和健康程度重要标准,主要用于统计分析
定义:BMI = 体重 (kg) /身高2(m2)
获取用户输入的体重和身高值,计算并给出国际和国内的 BMI 分类
要求如下:
(1) 混合计算并给出国际和国内的 BMI 分类;
(2) 使用input()获得测试用例输入时,不要增加提示字符串。
## 输入输出示例
输入 | 输出 | |
---|---|---|
示例1 | 1.68,41 |
BMI数值为:14.53 BMI指标为:国际'偏瘦',国内'偏瘦' |
示例2 | 1.72,80 |
BMI数值为:27.04 BMI指标为:国际'偏胖',国内'偏胖' |
height,weight=eval(input())
bmi=weight/pow(height,2)
print("BMI数值为:{:.2f}".format(bmi))
if bmi<18.5:
print("BMI指标为:国际'偏瘦',国内'偏瘦'")
elif 18.5<=bmi<24:
print("BMI指标为:国际'正常',国内'正常'")
elif 24<=bmi<25:
print("BMI指标为:国际'正常',国内'偏胖'")
elif 25<=bmi<28:
print("BMI指标为:国际'偏胖',国内'偏胖'")
elif 28<=bmi<30:
print("BMI指标为:国际'偏胖',国内'肥胖'")
else:
print("BMI指标为:国际'肥胖',国内'肥胖'")
-
实例6:圆周率的计算
描述
这是”实例”题,与课上讲解实例相同,请作答检验学习效果。
求解圆周率可以采用蒙特卡罗方法,在一个正方形中撒点,根据在1/4圆内点的数量占总撒点数的比例计算圆周率值。
请以123作为随机数种子,获得用户输入的撒点数量,编写程序输出圆周率的值,保留小数点后6位。
输入输出示例
输入 输出 示例 1 1024
3.218750
import random
random.seed(123)
n=eval(input())
hits=0
for i in range(1,n+1):
x,y=random.random(),random.random()
dist=(x**2+y**2)**0.5
if dist<=1.0:
hits=hits+1
pi=4*(hits/n)
print("{:.6f}".format(pi))
---
from random import random, seed
DARTS = eval(input())
seed(123)
hits = 0.0
for i in range(DARTS):
x, y = random(), random()
dist = pow(x ** 2 + y ** 2, 0.5)
if dist <= 1.0:
hits = hits + 1
pi = 4 * (hits/DARTS)
print("{:.6f}".format(pi))
-
整数的加减和
描述
编写程序计算如下数列的值:
1-2+3-4…966
其中,所有数字为整数,从1开始递增,奇数为正,偶数为负
输入格式
该题目没有输入。
输入输出示例
输入 输出 示例 1 无
111(仅表示输出样式,不是输出结果)
ans=0
for i in range(1,967):
if i%2==1:
ans=ans+i
else:
ans=ans-i
print(ans)
-
三位水仙花数
描述
“水仙花数”是指一个三位整数,其各位数字的3次方和等于该数本身。
例如:ABC是一个”3位水仙花数”,则:A的3次方+B的3次方+C的3次方 = ABC。
请按照从小到大的顺序输出所有的3位水仙花数,请用”逗号”分隔输出结果。
输入输出示例
输出仅表示格式,不表示对错。
输入 输出 示例 1 无输入
111,222
b=0
for i in range(100,1000):
if (((i//100)**3)+(((i%100)//10)**3)+((i%10)**3))==i:
if b==0:
print(i,end="")
b=1
else:
print(",{}".format(i),end="")
---
s = ""
for i in range(100, 1000):
t = str(i)
if pow(eval(t[0]),3) + pow(eval(t[1]),3) + pow(eval(t[2]),3) == i :
s += "{},".format(i)
print(s[:-1])
#这里采用了s[:-1]方式不输出最后一个逗号。也可以把所有结果放到一个列表中,采用字符串的.join()方法输出结果。
-
用户登录的三次机会
描述
给用户三次输入用户名和密码的机会,要求如下:
1)如输入第一行输入用户名为‘Kate’,第二行输入密码为‘666666’,输出‘登录成功!’,退出程序;
2)当一共有3次输入用户名或密码不正确输出“3次用户名或者密码均有误!退出程序。”。
输入输出示例
输入 输出 示例 1 Kate 666666
登录成功!
kate 123 alice 456 john 111111
3次用户名或者密码均有误!退出程序。
standard_name='Kate'
standard_code='666666'
for i in range(3):
s1=input()
s2=input()
#读字符串不可以s1,s2=input()
if (s1==standard_name) and (s2==standard_code):
print("登录成功!")
break
elif i==2:
print("3次用户名或者密码均有误!退出程序。")
---
count = 0
while count < 3:
name = input()
password = input()
if name == 'Kate'and password == '666666':
print("登录成功!")
break
else:
count += 1
if count == 3:
print("3次用户名或者密码均有误!退出程序。")
测验
单项选择题
-
for var in ___: print(var)
哪个选项不符合上述程序空白处的语法要求?
A. (1,2,3)
B. “Hello”
C. {1;2;3;4;5}
D. range(0,10)
C
for .. in .. 中 in 的后面需要是一个迭代类型(组合类型),{1;2;3;4;5}不是Python的有效数据类型。
-
for i in range(0,2): print(i)
哪个选项是以上程序的输出结果?
A. 0 1
B. 1
C. 1 2
D. 0 1 2
A
range(0, 2)输出两个值:0和1。
-
k=10000 while k>1: print(k) k=k/2
哪个选项给出了上述程序的输出次数?
A. 1000
B. 15
C. 13
D. 14
D
请跟随程序计算或在IDLE中运行程序获得结果。
-
哪个选项是程序的三种基本结构?
A. 顺序结构,循环结构,分支结构
B. 顺序结构,跳转结构,循环结构
C. 过程结构,循环结构,分支结构
D. 过程结构,对象结构,函数结构
A
无对象结构、跳转结构、过程结构等说法。
-
哪个选项关于循环结构的描述是错误的?
A. 死循环无法退出,没有任何作用
B. 条件循环和遍历循环结构都是基本的循环结构
C. 循环是一种程序的基本控制结构
D. 循环是程序根据条件判断结果向后反复执行的一种运行方式
A
死循环能够用于测试性能,形式上的死循环可以用break来退出,例如:
x = 10 while True: x = x - 1 if x == 1: break
死循环是有其作用的。
-
关于Python语句P=-P,哪个选项的描述是正确的?
A. P的绝对值
B. P等于它的负数
C. 给P赋值为它的负数
D. P=0
C
Python中的=是赋值符号,==是判断相等性的等于符号。
-
哪个选项是用来判断当前Python语句在分支结构中?
A. 缩进
B. 冒号
C. 引号
D. 大括号
A
缩进表达层次关系。
-
哪个选项是下面代码的执行结果?
for s in "PYTHON": if s=="T": continue print(s,end="")
A. PYHON
B. PYTHON
C. PY
D. TT
A
continue结束当次循环,但不跳出当前循环。
-
哪个选项是random库中用于生成随机小数的函数?
A. randint()
B. random()
C. randrange()
D. getrandbits()
B
randint()、getrandbits()、randrange()都产生随机整数,random()产生0到1之间的随机小数。
-
关于try-except,哪个选项的描述是错误的?
A. NameError是一种异常类型
B. 使用了异常处理,程序将不会再出错
C. 表达了一种分支结构的特点
D. 用于对程序的异常进行捕捉和处理
B
使用了异常处理,程序可能运行不会出错,但逻辑上可能出错。程序错误是一个大概念,不仅指代码运行错误,更代表功能逻辑错误。
程序设计题
-
四位玫瑰数
描述
四位玫瑰数是4位数的自幂数。自幂数是指一个 n 位数,它的每个位上的数字的 n 次幂之和等于它本身。
例如:当n为3时,有1^3 + 5^3 + 3^3 = 153,153即是n为3时的一个自幂数,3位数的自幂数被称为水仙花数。
请输出所有4位数的四位玫瑰数,按照从小到大顺序,每个数字一行。
输入输出示例
输出仅表示格式,不表示对错。
输入 输出 示例 1 无
1111 2222 3333
for i in range(1000,10000):
s=str(i)
if (eval(s[0])**4+eval(s[1])**4+eval(s[2])**4+eval(s[3])**4)==i:
print(i)
---
s = ""
for i in range(1000, 10000):
t = str(i)
if pow(eval(t[0]),4) + pow(eval(t[1]),4) + pow(eval(t[2]),4) + pow(eval(t[3]),4) == i :
print(i)
-
100以内素数之和
描述
求100以内所有素数之和并输出。
素数指从大于1,且仅能被1和自己整除的整数。
提示:可以逐一判断100以内每个数是否为素数,然后求和。
输入格式
该题目没有输入
输入输出示例
输入 输出 示例 1 1234(这是示例,不是真实输出)
def judge(n):
for i in range(2,n):
if n%i==0:
return 0
return 1
ans=0
for i in range(2,101):
if judge(i):
ans+=i
print(ans)
---
#Prime
def is_prime(n):
for i in range(2,n):
if n%i == 0:
return False
return True
sum = 0
for i in range(2,100):
if is_prime(i):
sum += i
print(sum)
简单的函数使用在"天天向上的力量"实例中已经介绍过了。
5.函数和代码复用
5.1 函数的定义与使用
函数的理解和定义
-
函数的定义
-
函数是一段代码的表示
- 函数是一段具有特定功能的、可重用的语句组
- 函数是一种功能的抽象,一般函数表达特定功能
- 两个作用:降低编程难度和代码复用
- 通过函数将一部分需要实现的内容/功能割离出去
def <函数名>(<参数(0个或多个)>):函数名>
<函数体>函数体>
return <返回值>返回值>
-
案例:计算n!
def fact(n): s=1 for i in range(1,n+1): s*=i return s
-
y=f(x)
- 函数定义时,所指定的参数是一种占位符
- 函数定义后,如果不经过调用,不会被执行
- 函数定义时,参数是输入、函数体是处理、结果是输出(IPO)
-
函数的使用及调用过程
-
函数的调用
-
调用是运行函数代码的方式
-
调用时要给出实际参数
-
实际参数替换定义中的参数
-
函数调用后得到返回值
-
例子:用fact(10)计算10!
def fact(n): s=1 for i in range(1,n+1): s*=i return s a=fact(10) print(a)
-
-
函数的参数传递
-
参数个数
-
函数可以有参数,也可以没有,但必须保留括号
def <函数名>():函数名>
<函数体>函数体>
return <返回值>返回值>
例子:
def fact(): print("我也是函数")
-
函数定义时可以为某些参数指定默认值,构成可选参数
def <函数名>(<非可选参数>,<可选参数>):#注意两者先后可选参数>非可选参数>函数名>
<函数体>函数体>
return <返回值>返回值>
-
计算n!//m
def fact(n,m=1):#这里的m是可选参数,在使用时不给定m,则默认为1 s=1 for i in range(1,n+1): s*=i return s//m #10!==fact(10) #10!//5==fact(10,5)
-
-
可变参数传递
-
函数定义时可以设计可变数量参数,即不确定参数总数量
def <函数名>(<参数>,\*b):#\*b中的b是一个可自定义的变量名参数>函数名>
<函数体>函数体>
return <返回值>返回值>
-
计算n!乘一些数
def fact(n,*b): s=1 for i in range(1,n+1): s*=i for item in b: s*=item return s #10!*3==fact(10,3) #10!*3*5*8==fact(10,3,5,8)
像max(),min()两个函数就用了可变参数传递的方式进行定义
-
-
参数传递的两种方式
-
函数调用时,参数可以按照位置或名称方式传递
def fact(n,m=1): s=1 for i in range(1,n+1): s*=i return s//m #>>>fact(10,5)进行位置传递 #>>>fact(m=5,n=10)进行名称传递
-
函数的返回值
-
函数的返回值
-
函数可以返回0个或多个结果
-
return保留字用来传递返回值
-
函数可以有返回值,也可以没有,可以有return,也可以没有
-
return可以传递0个返回值,也可以传递任意多个返回值
def fact(n,m=1): s=1 for i in range(1,n+1): s*=i return s//m,n,m #>>>fact(10,5) #(725760,10,5) #以上用小括号,中间用逗号分隔的形式为**元组类型** #用方括号,逗号分隔的是列表类型 #两者很相似 #>>>a,b,c=fact(10,5) #>>>print(a,b,c) 725760 10 5
-
-
局部变量和全局变量
-
局部变量和全局变量
<语句块1> def <函数名>(<参数>): <函数体> return <返回值> <语句块2> 整段程序中定义的是全局变量,在函数体中定义的是局部变量 ```python n,s=10,100#n和s是全局变量 def fact(n):#fact()中的n和s是局部变量 s=1 for i in range(1,n+1): s*=i return s print(fact(n),s)#n和s是全局变量 ``` - 规则1:局部变量和全局变量是不同变量 - 局部变量是函数内部的占位符,**与全局变量可能重名但不同** - 函数运算结束后,局部变量被释放 - 可以使用global保留字在函数内部使用全局变量 ```python n,s=10,100 def fact(n):#fact()中s是局部变量与全局变量s不同 s=1 for i in range(1,n+1): s*=i return s#此处局部变量s是3628800 print(fact(n),s)#此处全局变量s是100 #运行结果 #3628800 100 --- n,s=10,100 def fact(n): global s#fact()中使用global保留字声明此处s是全局变量s for i in range(1,n+1): s*=i return s#此处s指全局变量s print(fact(n),s)#此处全局变量s被函数修改 #运行结果 #362880000 362880000 ``` - 规则2:局部变量为**组合数据类型且并未创建**,等同于局部变量 ```python ls=["F","f"]#通过使用[]真实创建了一个全局变量列表ls def func(a): ls.append(a)#此处ls是列表类型,未真实创建 则等同于全局变量 return func("C")#全局变量ls被修改 print(ls) #运行结果 #['F','f','C'] --- ls=["F","f"]#通过使用[]真实创建了一个全局变量列表ls def func(a): ls=[] ls.append(a)#此处ls是列表类型,真实创建 是局部变量 return func("C")#局部变量ls被修改 print(ls) #运行结果 #['F','f'] ``` 具体解释:组合数据类型在python中由指针来体现,函数中如果没真实创建组合数据类型,它使用的变量是指针,而指针指向外部的全局变量,所以修改这个指针对应的内容则修改的是全局变量 - 使用规则 - 基本数据类型,无论是否重名,局部变量与全局变量不同 - 可以通过global保留字在函数内部声明全局变量 - 组合数据类型,如果局部变量**未真实创建**,则是全局变量 语句块2>返回值>函数体>参数>函数名>语句块1>
lambda函数
-
lambda函数
- lambda函数返回函数名作为结果
- lambda函数是一种匿名函数,即没有名字的函数
- 使用lambda保留字定义,函数名是返回结果
- lambda函数用于定义简单的、能够在一行内表示的函数
- lambda函数返回函数名作为结果
-
lambda函数的应用
- 谨慎使用lambda函数
- lambda函数主要用作一些特定函数或方法的参数
- lambda函数有一些固定使用方式,建议逐步掌握
- 一般情况,建议使用def定义的普通函数(除非知道lambda函数的固定搭配和固定使用)
- 谨慎使用lambda函数
5.2 实例7:七段数码管绘制
“七段数码管绘制”问题分析
- 七段数码管
- 选择不同数码管的亮灭可以构成不同的数字和字母组合
- 需求:用程序绘制七段数码管
- turtle绘图体系
“七段数码管绘制”实例讲解
-
基本思路
- 步骤1:绘制单个数字对应的数码管
- 步骤2:获得一串数字,绘制对应的数码管
- 步骤3:获得当前系统时间,绘制对应的数码管
-
步骤1:绘制单个数字对应的数码管
- 七段数码管由7个基本线条组成
- 七段数码管可以有固定顺序
- 不同数字显示不同线条
import turtle def drawLine(draw):#绘制单段数码管 turtle.pendown() if draw else turtle.penup() turtle.fd(40) turtle.right(90) def drawDigit(digit):#根据数字绘制七段数码管 drawLine(True) if digit in [2,3,4,5,6,8,9] else drawLine(False) drawLine(True) if digit in [0,1,3,4,5,6,7,8,9] else drawLine(False) drawLine(True) if digit in [0,2,3,5,6,8,9] else drawLine(False) drawLine(True) if digit in [0,2,6,8] else drawLine(False) turtle.left(90) drawLine(True) if digit in [0,4,5,6,8,9] else drawLine(False) drawLine(True) if digit in [0,2,3,5,6,7,8,9] else drawLine(False) drawLine(True) if digit in [0,1,2,3,4,7,8,9] else drawLine(False) turtle.left(180) turtle.penup()#为绘制后续数字确定位置 turtle.fd(20)#为绘制后续数字确定位置
-
步骤2:获取一段数字,绘制多个数码管
import turtle def drawLine(draw):#绘制单段数码管 turtle.pendown() if draw else turtle.penup() turtle.fd(40) turtle.right(90) def drawDigit(digit):#根据数字绘制七段数码管 drawLine(True) if digit in [2,3,4,5,6,8,9] else drawLine(False) drawLine(True) if digit in [0,1,3,4,5,6,7,8,9] else drawLine(False) drawLine(True) if digit in [0,2,3,5,6,8,9] else drawLine(False) drawLine(True) if digit in [0,2,6,8] else drawLine(False) turtle.left(90) drawLine(True) if digit in [0,4,5,6,8,9] else drawLine(False) drawLine(True) if digit in [0,2,3,5,6,7,8,9] else drawLine(False) drawLine(True) if digit in [0,1,2,3,4,7,8,9] else drawLine(False) turtle.left(180) turtle.penup()#为绘制后续数字确定位置 turtle.fd(20)#为绘制后续数字确定位置 def drawDate(date):#获得要输出的数字 for i in date: drawDigit(eval(i))#通过eval()函数将数字变为整数 def main(): turtle.setup(800,350,200,200) turtle.penup() turtle.fd(-300) turtle.pensize(5) drawDate('20181010') turtle.hideturtle()#藏起海龟 turtle.done() main()
推荐先复制粘贴上面的代码,运行后再尝试理解每段代码的作用
-
步骤3:获得当前系统时间,绘制对应的数码管
在此之前,让我们尝试绘制漂亮的七段数码管(增加drawGap函数)
import turtle def drawGap():#绘制数码间隔 turtle.penup() turtle.fd(5) def drawLine(draw):#绘制单段数码管 drawGap() turtle.pendown() if draw else turtle.penup() turtle.fd(40) drawGap() turtle.right(90) def drawDigit(digit):#根据数字绘制七段数码管 xxx xxx
- 使用time库获取当前系统时间
- 增加年月日标记
- 年月日颜色不同
现在对drawDate函数的输入参数date做一个修改,date为日期,date格式规定为’%Y-%m=%d+’,将-、=、+分别对应汉字年、月、日
import turtle,time xxx def drawDate(date):#date格式为'%Y-%m=%d+' turtle.pencolor("red") for i in date: if i=='-': turtle.write('年',font=("Arial",18,"normal")) turtle.pencolor("green") turtle.fd(40) elif i=='=': turtle.write('月',font=("Arial",18,"normal")) turtle.pencolor("blue") turtle.fd(40) elif i=='+': turtle.write('日',font=("Arial",18,"normal")) else: drawDigit(eval(i)) xxx
为了获得当前系统时间并将其格式化为上面需要的date形式,使用time库中的gmtime,strftime
import turtle,time xxx def main(): turtle.setup(800,350,200,200) turtle.penup() turtle.fd(-300) turtle.pensize(5) drawDate(time.strftime('%Y-%m=%d+',time.gmtime())) turtle.hideturtle() turtle.done() main()
下面是整个程序的代码
import turtle,time def drawGap():#绘制数码间隔 turtle.penup() turtle.fd(5) def drawLine(draw):#绘制单段数码管 drawGap() turtle.pendown() if draw else turtle.penup() turtle.fd(40) drawGap() turtle.right(90) def drawDigit(digit):#根据数字绘制七段数码管 drawLine(True) if digit in [2,3,4,5,6,8,9] else drawLine(False) drawLine(True) if digit in [0,1,3,4,5,6,7,8,9] else drawLine(False) drawLine(True) if digit in [0,2,3,5,6,8,9] else drawLine(False) drawLine(True) if digit in [0,2,6,8] else drawLine(False) turtle.left(90) drawLine(True) if digit in [0,4,5,6,8,9] else drawLine(False) drawLine(True) if digit in [0,2,3,5,6,7,8,9] else drawLine(False) drawLine(True) if digit in [0,1,2,3,4,7,8,9] else drawLine(False) turtle.left(180) turtle.penup()#为绘制后续数字确定位置 turtle.fd(20)#为绘制后续数字确定位置 def drawDate(date):#date格式为'%Y-%m=%d+' turtle.pencolor("red") for i in date: if i=='-': turtle.write('年',font=("Arial",18,"normal")) turtle.pencolor("green") turtle.fd(40) elif i=='=': turtle.write('月',font=("Arial",18,"normal")) turtle.pencolor("blue") turtle.fd(40) elif i=='+': turtle.write('日',font=("Arial",18,"normal")) else: drawDigit(eval(i)) def main(): turtle.setup(800,350,200,200) turtle.penup() turtle.fd(-300) turtle.pensize(5) drawDate(time.strftime('%Y-%m=%d+',time.gmtime())) turtle.hideturtle() turtle.done() main()
“七段数码管绘制”举一反三
- 理解方法思维
- 模块化思维:确定模块接口,封装功能
- 规则化思维:抽象过程为规则,计算机自动执行
- 化繁为简:将大功能变为小功能组合,分而治之(函数降低编码难度的主要方式)
- 应用问题的扩展
- 绘制带小数点的七段数码管
- 带刷新的时间倒计时效果
- 绘制高级的数码管,不局限于七段
5.3 代码复用与函数递归
代码复用与模块化设计
-
代码复用
-
把代码当成资源进行抽象
- 代码资源化:程序代码是一种用来表达计算的“资源”
- 代码抽象化:使用函数等方法对代码赋予更高级别的定义
- 代码复用:同一份代码在需要时可以被重复使用
-
函数和对象是代码复用的两种主要形式
-
函数:将代码命名,在代码层面建立了初步抽象
(这种抽象级别比较低,只是将代码变成了一个功能组)
-
对象:通过属性和方法,即<a>.<b>和<a>.<b>()在函数之上再次组织进行抽象
(这里不再深入介绍“对象”“面向对象编程”,只需理解函数是对代码的抽象;“再次组织的抽象”实际上是一种“面向对象的程序设计方法”)
-
-
-
模块化设计
-
分而治之
- 通过函数或对象封装将程序划分为模块及模块间的表达
- 具体包括:主程序、子程序和子程序间关系
- 分而治之:一种分而治之,分层抽象,体系化的设计思想
-
紧耦合 松耦合
-
紧耦合:两个部分之间交流很多,无法独立存在
-
松耦合:两个部分之间交流很少,可以独立存在
-
模块(函数)内部紧耦合(通过局部变量进行数据传输),模块(函数)之间松耦合(在函数之间减少传递参数和返回值)
(原因:函数的输入参数和返回值,就是这段函数与其他代码之间的交流通道,这样的交流通道越少越清晰,这段函数的复用可能性就越高)
-
-
函数递归的理解
-
递归的定义
-
函数定义中调用函数自身的方式
例子:
$n!=\begin{cases}1 \quad n=0 \ n(n-1)! \quad otherwise \end{cases}$
-
两个关键特征
-
链条:计算过程存在递归链条
n!与(n-1)!构成递归链条
-
基例:存在一个或多个不需要再次递归的基例(基础的实例)
n=0时n!=1
-
-
类似数学归纳法
- 数学归纳法
- 证明当$n$取第一个值$n_0$时命题成立
- 假设当$n_k$时命题成立,证明当$n=n_{k+1}$时命题也成立
- 递归是数学归纳法思维的编程体现
-
函数递归的调用过程
-
递归的实现
$n!=\begin{cases}1 \quad n=0 \ n(n-1)! \quad otherwise \end{cases}$
def fact(n): if n==0: return 1 else: return n*fact(n-1)
- 函数+分支语句
- 递归本身是一个函数,需要函数定义方式描述
- 函数内部,采用分支语句对输入参数进行判断
- 基例和链条,分别编写对应代码
分析:上例中求fact(5)时,fact(5)->5*fact(4)->5*4*fact(3)->5*4*3*fact(2)->5*4*3*2*fact(1)->5*4*3*2*1*fact(0)->5*4*3*2*1*1->5*4*3*2*1->5*4*3*2->5*4*6->5*24->120
函数定义时调用的是自身,而执行时调用的是自身代码的不同复制版本
- 函数+分支语句
函数递归实例分析
-
字符串反转
- 将字符串s反转后输出
- 简单:s[::-1](-1的步长即反转)
- 函数+分支结构
- 确定递归链条(首字符放最后,其余字符再反转)
- 确定递归基例(空字符)
def rvs(s): if s=="": return s else: return rvs(s[1:])+s[0]
-
斐波那契数列
- 一个经典数列
- $F(n)=\begin{cases}1 \quad n=1 \ 1 \quad n=2 \ F(n-1)+F(n-2) \quad otherwise \end{cases}$
- 函数+分支结构
- 递归链条(F(n)=F(n-1)+F(n-2))
- 递归基例(n=1/2)
def f(n): if n==1 or n==2: return 1 else: return f(n-1)+f(n-2)
-
汉诺塔
- 汉诺塔(又称河内塔)问题源于印度一个古老传说。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。
- 对于给定数量的圆盘,从最左侧搬运到最右侧需要多少步骤
- 该怎么搬运:既然是n个圆盘从A到C,就相当于n-1个圆盘先从A到B,再将第n个从A到C,再将n-1个从B到C(想一下,为符合规则只能这样)
- 递归过程只关心递归链条,我只要知道n到n-1怎么搬,不需要关心n-1具体怎么搬
count=0 def hanoi(n,src,dst,mid): global count if n==1: print("{}:{}->{}".format(1,src,dst)) count+=1 else: hanoi(n-1,src,mid,dst) print("{}:{}->{}".format(n,src,dst)) count+=1 hanoi(n-1,mid,dst,src) #例:hanoi(3,"A","C","B") # print(count)
5.4 模块4:PyInstaller库的使用
PyInstaller库基本介绍
- 前言
- 存在需求:将编写的.py源代码转换成无需源代码的可执行文件(如Windows下.exe)即将编好的程序发给电脑没有python环境的朋友玩
- 原因:在Windows,Linux,OS操作系统上可能有时没有安装python的解释器,此时就需要将源程序先编译、打包成一个可执行文件
- PyInstaller库概述
- 将.py源代码转换成无需源代码的可执行文件
- .py->PyInstaller->可执行文件
- PyInstaller库是第三方库
- 官方网站
- 第三方库:使用前需要额外安装
- 安装第三方库python提供了好用的pip工具
- 安装需要Windows下command命令行或者Linux或OS系统下相应命令行去执行pip指令
- PyInstaller库的安装(Windows下安装)
- Win+R打开“运行”
- 运行cmd
- (cmd命令行)pip install pyinstaller
- 需要联网安装
- 安装完后出现successfully installed则安装好
PyInstaller库使用说明
-
注意:用Windows下的命令行使用PyInstaller,因为它是命令行的执行程序,而不是python下的执行命令
-
简单的使用
- (cmd命令行)pyinstaller -F <文件名.py>文件名.py>
- 目录中出现额外的三个目录_pycache_,build,dist
- 其中_pycache_,build可以安全删除,dist文件夹中有打包之后生成的exe文件,可以鼠标双击执行
-
PyInstaller库常用参数
-
-h 查看帮助
-
–clean 清理打包过程中的临时文件
-
-D,–onedir 默认值,生成dist文件夹
-
-F,–onefile 在dist文件夹中只生成独立的打包文件
-
-i <图标文件名.ico> 指定打包程序使用的图标(icon)文件图标文件名.ico>
如:pyinstaller -i x.ico -F y.py
-
5.5 实例8:科赫雪花小包裹
“科赫雪花小包裹”问题分析
- 科赫雪花
- 高大上的分形几何
- 分形几何是一种具有迭代关系的几何图形,广泛存在于自然界中
- 科赫曲线,也叫雪花曲线
- 高大上的分形几何
- 科赫雪花绘制
- 用Python绘制科赫曲线
- 对一段线段,取其中间1/3长度,去掉后增加两条1/3长度的线段,这样就形成一个60°的突起
- 这样一条直线到这样一种曲线的变换叫一次科赫曲线的转换
- 0阶科赫曲线是一段线段,每“对其中的每条线段做一次变化”就升一阶
- 用Python绘制科赫曲线
“科赫雪花小包裹”实例讲解
-
科赫曲线的绘制(绘制n阶科赫曲线)
- 递归思想:函数+分支
- 递归链条:线段的组合
- 递归基例:初始线段
#KochDrawV1.py import turtle def koch(size,n): if n==0: turtle.fd(size) else: for angle in [0,60,-120,60]: turtle.left(angle) koch(size/3,n-1) def main(): turtle.setup(800,400) turtle.penup() turtle.goto(-300,-50) turtle.pendown() turtle.pensize(2) koch(600,3) turtle.hideturtle() main()
-
科赫曲线->科赫雪花
#KochDrawV1.py import turtle def koch(size,n): xxx def main(): turtle.setup(600,600) turtle.penup() turtle.goto(-200,100) turtle.pendown() turtle.pensize(2) level=3 koch(400,level) turtle.right(120) koch(400,level) turtle.right(120) koch(400,level) turtle.right(120) turtle.hideturtle() main()
-
pyinstaller -i curve.ico -F KochDrawV1.py
“科赫雪花小包裹”举一反三
- 绘制条件的扩展
- 修改分形几何绘制阶数
- 修改科赫曲线的基本定义及旋转角度
- 修改绘制科赫雪花的基本框架图形
- 分形几何千千万
- 康托尔集、谢尔宾斯基三角形、门格海绵…
- 龙形曲线、空间填充曲线、科赫曲线…
- 深入理解函数递归思想
练习
-
实例7:七段数码管绘制
描述
这是”实例”题,与课上讲解实例相同,请作答检验学习效果。
七段数码管是一种展示数字的有效方式。
请用程序绘制当前系统时间对应的七段数码管,效果如下:
要求如下:
(1) 使用 time 库获得系统当前时间,格式如下:20190411
(2) 绘制对应的七段数码管
(3) 数码管风格不限
请在本机编写代码完成实例,建议有趣的风格请在Python123的绘图专区上传展示。
import time,turtle def drawLine(draw): turtle.penup() turtle.fd(5) turtle.pendown() if draw else turtle.penup() turtle.fd(40) turtle.penup() turtle.fd(5) turtle.right(90) def drawDigit(d): drawLine(True) if d in [2,3,4,5,6,8,9] else drawLine(False) drawLine(True) if d in [0,1,3,4,5,6,7,8,9] else drawLine(False) drawLine(True) if d in [0,2,3,5,6,8,9] else drawLine(False) drawLine(True) if d in [0,2,6,8] else drawLine(False) turtle.left(90) drawLine(True) if d in [0,4,5,6,8,9] else drawLine(False) drawLine(True) if d in [0,2,3,5,6,7,8,9] else drawLine(False) drawLine(True) if d in [0,1,2,3,4,7,8,9] else drawLine(False) turtle.left(180) turtle.penup() turtle.fd(20) def drawDate(date): turtle.pencolor("red") for i in date: drawDigit(eval(i)) def main(): turtle.setup(800,350,200,200) turtle.penup() turtle.fd(-300) turtle.pensize(5) drawDate(time.strftime('%Y%m%d',time.gmtime())) turtle.done() main()
-
实例8:科赫雪花小包裹
描述
这是”实例”题,与课上讲解实例相同,请作答检验学习效果。
科赫曲线,也叫雪花曲线。绘制科赫曲线。
请补充编程模板中代码,完成功能:获得用户输入的整数N,作为阶,绘制N阶科赫曲线。
import turtle def koch(size, n): if n == 0: turtle.fd(size) else: for angle in [0, 60, -120, 60]: turtle.left(angle) koch(size/3, n-1) def main(level): turtle.setup(600,600) turtle.penup() turtle.goto(-200, 100) turtle.pendown() turtle.pensize(2) koch(400,level) turtle.right(120) koch(400,level) turtle.right(120) koch(400,level) turtle.hideturtle() try: level = eval(input("请输入科赫曲线的阶: ")) main(level) except: print("输入错误")
-
625673
任意累积
描述
请根据编程模板补充代码,计算任意个输入数字的乘积。
注意,仅需要在标注…的地方补充一行或多行代码。
输入输出示例
输入 输出 示例 1 1,2,3,4
24
def cmul(*num): sum=1 for i in num: sum*=i return sum print(eval("cmul({})".format(input()))) --- def cmul(a, *b): m = a for i in b: m *= i return m print(eval("cmul({})".format(input())))
-
斐波那契数列计算
描述
根据编程模板补充代码,计算斐波那契数列的值,具体功能如下:
\1. 获取用户输入整数N,其中,N为正整数
\2. 计算斐波那契数列的值
如果将斐波那契数列表示为fbi(N),对于整数N,值如下:
fbi(1)和fbi(2)的值是1,当N>2时,fbi(N) = fbi(N-1) + fbi(N-2)
请采用递归方式编写。
输入输出示例
输入 输出 示例 1 4
3
def fbi(n): if n==1 or n==2: return 1 else: return fbi(n-1)+fbi(n-2) n=eval(input()) print(fbi(n))
-
汉诺塔实践
描述
汉诺塔问题大家都清楚,这里不再赘述。
请补充编程模板中代码,完成如下功能:
有三个圆柱A、B、C,初始时A上有N个圆盘,N由用户输入给出,最终移动到圆柱C上。
每次移动步骤的表达方式示例如下:[STEP 10] A->C。其中,STEP是步骤序号,宽度为4个字符,右对齐。
请编写代码,获得输入N后,输出汉诺塔移动的步骤。
输入格式
一个整数
输出格式
每个步骤一行,每行参考格式如下:[STEP 10] A->C
输入输出示例
输入 输出 示例 1 3
[STEP 1] A->C [STEP 2] A->B [STEP 3] C->B [STEP 4] A->C [STEP 5] B->A [STEP 6] B->C [STEP 7] A->C
step=1 def hanoi(n,a,c,b): global step if n==1: print("[STEP{:>4}] {}->{}".format(step,a,c)) step+=1 else: hanoi(n-1,a,b,c) #print("[STEP{:>4}] {}->{}".format(step,a,b)) print("[STEP{:>4}] {}->{}".format(step,a,c)) step+=1 hanoi(n-1,b,c,a) #print("[STEP{:>4}] {}->{}".format(step,b,c)) n=eval(input()) hanoi(n,'A','C','B')
测验
单项选择题
-
以下选项不是函数作用的是:
A. 提高代码执行速度
B. 降低编程复杂度
C. 增强代码可读性
D. 复用代码
A
函数不能直接提高代码执行速度。
-
下列程序的输出结果为:
def f(a,b): a=4 return a+b def main(): a=5 b=6 print(f(a,b),a+b) main()
A. 11 10
B. 10 11
C. 10 10
D. 11 11
B
这里没有全局变量,都是函数局部变量的运算。
-
以下关于Python函数说法错误的是:
def func(a,b): c=a**2+b b=a return c a=10 b=100 c=func(a,b)+a
A. 执行该函数后,变量a的值为10
B. 该函数名称为func
C. 执行该函数后,变量b的值为100
D. 执行该函数后,变量c的值为200
D
a, b为全局变量,请在IDLE中执行代码观察结果。
-
以下关于函数调用描述正确的是:
A. 自定义函数调用前必须定义
B. Python内置函数调用前需要引用相应的库
C. 函数在调用前不需要定义,拿来即用就好
D. 函数和调用只能发生在同一个文件中
A
函数调用前必须已经存在函数定义,否则无法执行。
Python内置函数直接使用,不需要引用任何模块。
-
以下关于模块化设计描述错误的是:
A. 应尽可能合理划分功能块,功能块内部耦合度高
B. 应尽可能合理划分功能块,功能块内部耦合度低
C. 高耦合度的特点是复用较为困难
D. 模块间关系尽可能简单,模块之间耦合度低
B
模块内高耦合、模块间低耦合。
-
以下对递归描述错误的是:
A. 一定要有基例
B. 书写简单
C. 执行效率高
D. 递归程序都可以有非递归编写方法
C
递归不提高程序执行效率。
任何递归程序都可以通过堆栈或队列变成非递归程序(这是程序的高级应用)。
-
以下关于函数说法错误的是:
A. 对函数的使用必须了解其内部实现原理
B. 函数通过函数名来调用
C. 函数是一段具有特定功能的、可重用的语句组
D. 函数可以看做是一段具有名字的子程序
A
调用函数不需要知道函数内部实现原理,只需要知道调用方法(即接口)即可。
-
哪个选项对于函数的定义是错误的?
A. def vfunc(*a,b):
B. def vfunc(a,*b):
C. def vfunc(a,b):
D. def vfunc(a,b=2):
A
def vfunc(*a, b) 是错误的定义:*a表示可变参数,可变参数只能放在函数参数的最后。
-
关于return语句,以下选项描述正确的是:
A. 函数中最多只有一个return语句
B. return只能返回一个值
C. 函数必须有一个return语句
D. 函数可以没有return语句
D
函数可以包含0个或多个return语句
-
以下关于递归函数基例的说法错误的是:
A. 每个递归函数都只能有一个基例
B. 递归函数必须有基例
C. 递归函数的基例不再进行递归
D. 递归函数的基例决定递归的深度
A
每个递归函数至少存在一个基例,但可能存在多个基例。
程序设计题
-
随机密码生成
描述
补充编程模板中代码,完成如下功能:
以整数17为随机数种子,获取用户输入整数N为长度,产生3个长度为N位的密码,密码的每位是一个数字。每个密码单独一行输出。
产生密码采用random.randint()函数。
输入输出示例
输入 输出 示例 1 3
634 524 926
#请在...补充代码 import random def genpwd(length): if length==1: return random.randint(0,9) else: return random.randint(10**(length-1),10**length-1) length = eval(input()) random.seed(17) for i in range(3): print(genpwd(length)) --- import random def genpwd(length): if length==1: return random.randint(0,9) else: return random.randint(10**(length-1),10**length-1) length = eval(input()) random.seed(17) for i in range(3): print(genpwd(length)) --- import random def genpwd(length): a = 10**(length-1) b = 10**length - 1 return "{}".format(random.randint(a, b)) length = eval(input()) random.seed(17) for i in range(3): print(genpwd(length))
-
连续质数计算
描述
补充编程模板中代码,完成如下功能:
获得用户输入数字N,计算并输出从N开始的5个质数,单行输出,质数间用逗号,分割。
注意:需要考虑用户输入的数字N可能是浮点数,应对输入取整数;最后一个输出后不用逗号。
输入输出示例
输入 输出 示例 1 12
13,17,19,23,29
# 请在...补充一行或多行代码 def prime(m): ... n = eval(input()) ... --- def prime(m): if m==2: return True else: for i in range(2,m): if m%i==0: return False return True n = eval(input()) #if round(n)<n: # n=round(n)+1#wrong->round()是四舍五入 if int(n)<n: n=int(n)+1 cnt=0 while True: if prime(n): if cnt==4: print(n,end="") break; else: print("{},".format(n),end="") cnt+=1 n+=1 --- def prime(m): for i in range(2,m): if m % i == 0: return False return True n = eval(input()) n_ = int(n) n_ = n_+1 if n_ < n else n_ count = 5 while count > 0: if prime(n_): if count > 1: print(n_, end=",") else: print(n_, end="") count -= 1 n_ += 1 这个代码注意: (1) 需要对输入小数情况进行判断,获取超过该输入的最小整数(这里没用floor()函数);#floor()似乎是math库里的 (2) 对输出格式进行判断,最后一个输出后不增加逗号(这里没用.join()方法)。
6.组合数据类型
6.1 集合类型及操作
集合类型的定义
-
集合类型的定义
- 集合是多个元素的无序组合
- 集合类型与数学中的集合概念一致
- 集合元素之间无序,每个元素唯一,不存在相同元素
- python中集合元素不可更改,是不可变数据类型(这样不会出现更改后集合间突然出现相同元素的错误)
- 非可变数据类型有:整数、浮点数、复数、字符串类型、元组类型……
- 集合用大括号{}表示,元素间用逗号分隔
- 建立集合类型用{}或set(),其中{}为空时建立的是字典类型
- 建立空集合必须用set()
>>>A={“python”,123,(“python”,123)} #使用非空{}建立集合
{123,’python’,(‘python’,123)}
>>>B=set(“pypy123”) #使用set()建立集合注意区别它与{}对待字符串的不同;或者说set里面只能放一个数据,不能用逗号隔开
{‘1’,’p’,’2’,’3’,’y’}
>>>C={“python”,123,”python”,123}
{‘python’,123}
- 集合是多个元素的无序组合
-
重点
- 集合用大括号{}表示,元素间用逗号分隔
- 集合中每个元素唯一,不存在相同元素
- 集合元素之间无序
集合操作符
-
集合间操作
S T 并 S-T 差
S&T 交
S^T 补(S^T==(S T)-(S&T)) -
集合操作符
-
6个操作符
-
S T 返回一个新集合,包括在集合S和T中的所有元素
-
S-T
返回一个新集合,包括在集合S但不在T中的元素
-
S&T
返回一个新集合,包括同时在集合S和T中的元素
-
S^T
返回一个新集合,包括集合S和T中的非相同元素
-
S<=T或S<T
返回True/False,判断S和T的子集关系
-
S>=T或S>T
返回True/False,判断S和T的包含关系
-
-
4个增强操作符
-
S =T 更新集合S,包括在集合S和T中的所有元素
-
S-=T
更新集合S,包括在集合S但不在T中的元素
-
S&=T
更新集合S,包括同时在集合S和T中的元素
-
S^=T
更新集合S,包括集合S和T中的非相同元素
-
>>>A={“p”,”y”,123}
>>>B=set{“pypy123”}
>>>A-B
{123}
>>>B-A
{‘3’,’1’,’2’}
>>>A&B
{‘p’,’y’}
>>>A B {‘1’,’p’,’2’,’y’,’3’,123}
>>>A^B
{‘2’,123,’3’,’1’}
-
集合处理方法
-
集合处理方法
-
S.add(x)
如果x不在集合S中,将x增加到S
-
S.discard(x)
移除S中元素x,如果x不在集合S中,不报错
-
S.remove(x)
移除S中元素x,如果x不在集合S中,产生KeyError异常
-
S.clear()
移除S中所有元素
-
S.pop()
随机返回S的一个元素,并在S中移除它,若S为空产生KeyError异常
-
S.copy()
返回S的一个副本
-
len(S)
返回S的元素个数
-
x in S
判断S中是否有元素x,依此返回True/False
-
x not in S
判断S中是否有元素x,依此返回False/True
-
set(x)
将其他类型变量x转换为集合类型
>>>A={“p”,”y”,123}
>>> for item in A:
print(item,end=””)
p123y
用for in的方式遍历的顺序也许和你定义的顺序不同,但这个顺序在集合定义后就是固定的,只不过无法利用这个顺序
也可以用while循环遍历
>>>try:
while True:
print(A.pop(),end=””)
except:
pass
p123y
当然一般还是用for in方式遍历组合数据类型
-
集合类型应用场景
-
集合类型应用场景
-
包含关系比较
>>>“p” in {“p”,”y”,123}
True
>>>{“p”,”y”}>={“p”,”y”,123}
False
-
数据去重:集合类型所有元素无重复
>>>ls=[“p”,”p”,”y”,”y”,123]
>>>s=set(ls)#利用了集合无重复元素的特点
{‘p’,’y’,123}
>>>lt=list(s)#将集合转换为列表
[‘p’,’y’,123]
-
6.2 序列类型及操作
序列类型定义
- 序列是具有先后关系的一组元素
- 序列是一维元素向量,元素类型可以不同
- 类似数学元素序列:$s_0,s_1,…,s_{n-1}$
- 元素间由序号引导,通过下标访问序列的特定元素
- 序列是一个基类类型
- 序列类型的衍生有:字符串类型、元组类型、列表类型
- 序号的定义
- 正向递增序号
- 反向递减序号
序列处理函数及方法
-
序列类型通用操作符
-
6个操作符
-
x in s
如果x是序列s的元素,返回True,否则返回False
-
x not in s
与上面的相反
-
s+t
连接两个序列s和t
-
s*n或n*s
将序列s复制n次
-
s[i]
索引,返回s中的第i个元素,i是序列的序号
-
s[i:j]或s[i:j:k]
切片,返回序列s中第i到第j以k为步长的元素子序列
-
-
-
序列类型操作实例
>>>ls=[“python”,123,”.io”]
>>>ls[::-1]#列表取反
[‘.io’,123,’python’]
>>>s=”python123.io”
>>>s[::-1]#字符串取反(毕竟字符串类型也是序列类型的扩展形式)
‘oi.321nohtyp’
-
序列类型通用函数和方法
-
5个函数和方法
-
len(s)
返回序列s的长度
-
min(s)
返回序列s的最小元素,s中元素需要可比较(不可比较则报错)
-
max(s)
返回序列s的最大元素,s中元素需要可比较(不可比较则报错)
-
s.index(x)或s.index(x,i,j)
返回序列s从i开始到j位置中第一次出现元素x的位置(下标)
-
s.count(x)
返回序列s中出现x的总次数
-
-
-
序列类型操作实例
>>>ls=[“python”,123,”.io”]
>>>len(ls)
3
>>>s=”python123.io”
>>>max(s)#字符之间的比较按字母序比较
‘y’
元组类型及操作
-
元组类型定义
-
元组是序列类型的一种扩展
- 元组是一种序列类型,一旦创建就不能被修改
- 使用小括号()或tuple()创建,元素间用逗号分隔
- 可以使用或不使用小括号
如:
def func():
return 1,2
这里的1,2将默认处理为元组类型(1,2)
>>>creature=”cat”,”dog”,”tiger”,”human”
>>>creature
(‘cat’,’dog’,’tiger’,’human’)
>>>color=(0x001100,”blue”,creature)
(4352,’blue’,(‘cat’,’dog’,’tiger’,’human’))
-
-
元组类型操作
- 元组继承序列类型的全部通用操作
- 元组继承了序列类型的全部通用操作(操作符,处理函数,处理方法)
- 元组因为创建后不能修改,因此没有特殊操作
- 使用或不使用小括号
>>>creature=”cat”,”dog”,”tiger”,”human”
>>>creature[::-1]
(‘human’,’tiger’,’dog’,’cat’)
>>>color=(0x001100,”blue”,creature)
>>>color[-1][2]
‘tiger’
- 元组继承序列类型的全部通用操作
列表类型及操作
-
列表类型定义
- 列表是序列类型的一种扩展,十分常用
- 列表是一种序列类型,创建后可以随意被修改
- 使用方括号[]或list()创建,元素间用逗号分隔
- 列表中各元素类型可以不同,无长度限制
>>>ls=[“cat”,”dog”,”tiger”,1024]
>>>ls
[‘cat’,’dog’,’tiger’,1024]
>>>lt=ls
>>>lt
[‘cat’,’dog’,’tiger’,1024]
注意:方括号[]或list()真正创建一个列表,赋值仅传递引用(即lt,ls此时指向同一个列表,相当于重新命名)
- 列表是序列类型的一种扩展,十分常用
-
列表类型操作函数和方法
-
ls[i]=x
替换列表ls第i元素为x
-
ls[i:j:k]=lt
用列表lt替换ls切片后所对应元素子列表
-
del ls[i]
删除列表ls中第i元素
-
del ls[i:j:k]
删除列表ls中第i到第j以k为步长的元素
-
ls+=lt
更新列表ls,将列表lt中的元素加到列表ls后
-
ls*=n
更新列表ls,其元素重复n次
-
例子:
>>>ls=[“cat”,”dog”,”tiger”,1024]
>>>ls[1:2]=[1,2,3,4]
[‘cat’,1,2,3,4,’tiger’,1024]
>>>del ls[::3]
[1,2,4,’tiger’]
>>>ls*2
[1,2,4,’tiger’,1,2,4,’tiger’]
-
ls.append(x)
在列表ls最后增加元素x
-
ls.clear()
清空列表ls
-
ls.copy()
生成一个新列表,赋值ls中所有元素
-
ls.insert(i,x)
在列表ls的第i位置增加元素x
-
ls.pop(i)
将列表ls中第i位置元素取出并删除
-
ls.remove(x)
将列表ls中出现的第一个元素x删除
-
ls.reverse()
将列表ls中元素反转
-
例子:
>>>ls=[“cat”,”dog”,”tiger”,1024]
>>>ls.append(1234)
[‘cat’,’dog’,’tiger’,1024,1234]
>>>ls.insert(3,”human”)
[‘cat’,’dog’,’tiger’,’human’,1024,1234]
>>>ls.reverse()
[1234, 1024, ‘human’, ‘tiger’, ‘dog’, ‘cat’]
-
-
列表功能小测试
-
定义空列表lt
-
向lt新增5个元素
-
修改lt中第2个元素
-
向lt中第2个位置增加一个元素
-
从lt中第1个位置删除一个元素
-
删除lt中第1-3位置元素
-
判断lt中是否包含数字0
-
向lt新增数字0
-
返回数字0所在lt中的索引
-
lt的长度
-
lt中最大元素
-
清空lt
-
答案:
-
定义空列表lt
lt=[]
-
向lt新增5个元素
lt+=[1,2,3,4,5]
-
修改lt中第2个元素
lt[2]=6
-
向lt中第2个位置增加一个元素
lt.insert(2,7)
-
从lt中第1个位置删除一个元素
del lt[1]
-
删除lt中第1-3位置元素
del lt[1:4]
-
判断lt中是否包含数字0
0 in lt
-
向lt新增数字0
lt.append(0)
-
返回数字0所在lt中的索引
lt.index(0)
-
lt的长度
len(lt)
-
lt中最大元素
max(lt)
-
清空lt
lt.clear()
-
-
序列类型应用场景
-
序列类型应用场景
- 元组用于元素不改变的应用场景,更多用于固定搭配场景(如函数return)
- 列表更加灵活,它是最常用的序列类型
- 最主要作用:表示一组有序数据,进而操作它们
-
元素遍历
for item in ls:
<语句块>语句块>
for item in tp:#tp是元组类型变量
<语句块>语句块>
-
数据保护
-
如果不希望数据被程序改变,转换成元组类型
>>>ls=[“cat”,”dog”,”tiger”,1024]
>>>lt=tuple(ls)
>>>lt
(‘cat’,’dog’,’tiger’,1024)
-
主要是考虑到当一段程序是由多人完成时,存在不希望被修改的数据,可以要求程序之间的接口采用元组类型来传递
-
6.3 实例9:基本统计值计算
“基本统计值计算”问题分析
- 基本统计值
- 需求:给出一组数,对它们有个概要理解
- 该怎么做?
- 总个数、求和、平均值、方差、中位数…
- 总个数:len()
- 求和:for … in
- 平均值:求和/总个数
- 方差:各数据与平均数差的平方的和的平均数
- 中位数:排序,然后奇数找中间1个,偶数找中间2个取平均
“基本统计值计算”实例讲解
#CalStatisticsV1.py
def getNum():#获取用户不定长度的输入
nums=[]
iNumStr=input("请输入数字(回车退出):")
while iNumStr !="":
nums.append(eval(iNumStr))
iNumStr=input("请输入数字(回车退出):")
return nums
def mean(numbers):#计算平均值
s=0.0
for num in numbers:
s=s+num
return s/len(numbers)
def dev(numbers,mean):#计算方差
sdev=0.0
for num in numbers:
sdev+=(num-mean)**2
return pow(sdev/(len(numbers)-1),0.5)
def median(numbers):#计算中位数
sorted(numbers)#对列表进行排序#经个人查证,课程中这里应该讲错了,正确使用方法应为numbers=sorted(numbers)或numbers.sort()
size=len(numbers)
if size%2==0:
med=(numbers[size//2-1]+numbers[size//2])/2
else:
med=numbers[size//2]
return med
n=getNum()
m=mean(n)
print("平均值:{},方差:{:.2},中位数:{}".format(m,dev(n,m),median(n)))
“基本统计值计算”举一反三
- 技术能力扩展
- 获取多个数据:从控制台获取多个不确定数量数据的方法
- 分隔多个函数:模块化设计方法
- 充分利用函数:充分利用Python提供的内置函数
6.4 字典类型及操作
字典类型定义
-
理解“映射”
-
映射是一种键(索引)和值(数据)的对应
-
如:
内部颜色:蓝色
外部颜色:红色
“streetAddr”:”中关村南大街5号”
“city”:”北京市”
“zipcode”:”100081”
[“python”,123,”.io”]
的 0 1 2
即序列类型由0..N整数作为数据的默认索引
而映射类型则由用户为数据定义索引
-
-
字典类型是“映射”的体现
- 键值对:键是数据索引的扩展
- 字典是键值对的集合,键值对之间无序
- python采用大括号{}和dict()创建,键值对用冒号表示
- {<键1>:<值1>,<键2>:<值2>,...,<键n>:<值n>}值n>键n>值2>键2>值1>键1>
-
字典类型的用法
- 在字典变量中,通过键获得值
- <字典变量>={<键1>:<值1>,<键2>:<值2>,...,<键n>:<值n>} 值n>键n>值2>键2>值1>键1>字典变量>
- <值>=<字典变量>[<键>] 键>字典变量>值>
- <字典变量>[<键>]=<值> 值>键>字典变量>
- []用来向字典变量中索引或增加元素
>>>d={“中国”:”北京”,”美国”:”华盛顿”,”法国”:”巴黎”}
>>>d
{‘中国’: ‘北京’, ‘美国’: ‘华盛顿’, ‘法国’: ‘巴黎’}
>>>d[“中国”]
‘北京’
#如果要生成一个空的字典?
>>>de={};type(de)#type(x)用于检测变量x的类型
<class ‘dict’>
字典类型处理函数及方法
-
字典类型操作函数和方法
-
del d[k]
删除字典d中键k对应的数据值
-
k in d
判断键k是否在字典d中
-
d.keys()
返回字典d中所有的键信息
-
d.values()
返回字典d中所有的值信息
-
d.items()
返回字典d中所有的键值对信息
-
例子:
>>>d={“中国”:”北京”,”美国”:”华盛顿”,”法国”:”巴黎”}
>>>“中国” in d
True
>>>d.keys()
dict_keys([‘中国’, ‘美国’, ‘法国’])
>>>d.values()
dict_values([‘北京’, ‘华盛顿’, ‘巴黎’])
dict_keys,dict_values类型可以用for..in遍历,但不能当列表类型操作
-
d.get(k,<default>)
键k存在则返回相应值,不在则返回<default>值
-
d.pop(k,<default>)
键k存在则取出相应值,不在则返回<default>值
-
d.popitem()
随机从字典d中取出一个键值对,以元组形式返回
-
d.clear()
删除d所有键值对
-
len(d)
返回字典d中元素个数
-
例子:
>>>d={“中国”:”北京”,”美国”:”华盛顿”,”法国”:”巴黎”}
>>>d.get(“中国”,”伊斯兰堡”)
‘北京’
>>>d.get(“巴基斯坦”,”伊斯兰堡”)
‘伊斯兰堡’
>>>d.popitem()
(‘美国’, ‘华盛顿’)
-
-
字典功能小测试
-
定义空字典d
-
向d新增2个键值对元素
-
修改第2个元素
-
判断字符”c”是否是d的键
-
计算d的长度
-
清空d
-
答案:
-
定义空字典d
d={}
-
向d新增2个键值对元素
d[“a”]=1;d[“b”]=2
-
修改第2个元素
注意字典中的元素并没有顺序关系
d[“b”]=3
-
判断字符”c”是否是d的键
“c” in d
-
计算d的长度
len(d)
-
清空d
d.clear()
-
-
字典类型应用场景
-
映射的表达
- 映射无处不在,键值对无处不在
- 例如:统计数据出现的次数,数据是键,次数是值
- 最主要作用:表达键值对数据,进而操作它们
-
元素遍历
for k in d:#遍历字典d中的键
<语句块>语句块>
6.5 模块5:jieba库的使用
jieba库基本介绍
-
jieba库概述
- jieba库是优秀的中文分词第三方库
- 中文文本需要通过分词获得单个的词语
- jieba是优秀的中文分词第三方库,需要额外安装
- jieba库提供三种分词模式,而简单->只需掌握一个函数
-
jieba库的安装
cmd命令行:pip install jieba
-
jieba分词的原理
- jieba分词依靠中文词库
- 利用一个中文词库,确定汉字之间的关联概率
- 汉字间概率大的组成词组,形成分词结果
- 除了jieba自带的中文词库,用户还可以添加自定义词组(从而使其更适应某些具体领域的使用)
- jieba分词依靠中文词库
jieba库使用说明
-
jieba分词的三种模式
- 精确模式、全模式、搜索引擎模式
- 精确模式:把文本精确地切分开,不存在冗余单词
- 全模式:把文本中所有可能的词语都扫描出来,有冗余
- 搜索引擎模式:在精确模式基础上,对长词再次切分
- 精确模式、全模式、搜索引擎模式
-
jieba库常用函数
-
jieba.lcut(s)
精确模式,返回一个列表类型的分词结果
>>>jieba.lcut(“中国是一个伟大的国家”)
[‘中国’, ‘是’, ‘一个’, ‘伟大’, ‘的’, ‘国家’]
-
jieba.lcut(s,cut_all=True)
全模式,返回一个列表类型的分词结果,存在冗余
>>>jieba.lcut(“中国是一个伟大的国家”,cut_all=True)
[‘中国’, ‘国是’, ‘一个’, ‘伟大’, ‘的’, ‘国家’]
-
jieba.lcut_for_search(s)
搜索引擎模式,返回一个列表类型的分词结果,存在冗余
>>>jieba.lcut_for_search(“中华人民共和国是伟大的”)
[‘中华’, ‘华人’, ‘人民’, ‘共和’, ‘共和国’, ‘中华人民共和国’, ‘是’, ‘伟大’, ‘的’]
-
jieba.add_word(w)
向分词词典增加新词w
>>>jieba.add_word(“蟒蛇语言”)
-
6.6 实例10:文本词频统计
“文本词频统计”问题分析
“Hamlet英文词频统计”实例讲解
-
哈姆雷特(HAMLET)
初步思路:
- 获得一个HAMLET的英文文章,并将其中出现最多的单词输出
- 但是对于英文,我们会有一些单词表达方面的不同
- 单词大小写,逗号、冒号、叹号等
- 需要将文本进行噪音处理、归一化,才能在此基础上统计词频
#CalHamletV1.py
def getText():
txt=open("hamlet.txt","r").read()#打开hamlet.txt
txt=txt.lower()#将英文字母全转换为小写
for ch in '!"#$%&()*+,-./:;<=>?@[\\]^_‘’{|}·~':
txt=txt.replace(ch," ")#将特殊字符替换为空格
return txt
hamletTxt=getText()
words=hamletTxt.split()
counts={}
for word in words:
counts[word]=counts.get(word,0)+1
items=list(counts.items())
items.sort(key=lambda x:x[1],reverse=True)
#列表类型的一种sort方法,其中的参数lambda用来指定在列表中使用哪一个多元选项的列作为排序列
#默认从小到大,reverse设为True就是从大到小
#它完成的工作就是对一个列表按照键值对的两个元素的第二个元素进行排序,排序方式是由大到小
for i in range(10):
word,count=items[i]
print("{0:<10}{1:>5}".format(word,count))
“《三国演义》人物出场统计”实例讲解
- 初步分析:
- 使用jieba库分词
- 不存在大小写
- 标点符号在分词后不用处理
#CalThreeKingdomsV1.py
import jieba
txt=open("threekingdoms.txt","r",encoding="utf-8").read()
words=jieba.lcut(txt)
counts={}
for word in words:
if len(word)==1:
continue
else:
counts[word]=counts.get(word,0)+1
items=list(counts.items())
items.sort(key=lambda x:x[1],reverse=True)
for i in range(15):
word,count=items[i]
print("{0:<10}{1:>5}".format(word,count))
曹操 953
孔明 836
将军 772
却说 656
玄德 585
关公 510
丞相 491
二人 469
不可 440
荆州 425
玄德曰 390
孔明曰 390
不能 384
如此 378
张飞 358
- 但是这段代码仅能将中文进行分词并且进行词频统计,而离《三国演义》人物出场统计还有距离
- 将词频与人物相关联,面向问题:人物统计
- 修改:
- 排除词库
- 人物关联
#CalThreeKingdomsV2.py
import jieba
txt=open("threekingdoms.txt","r",encoding="utf-8").read()
excludes={"将军","却说","荆州","二人","不可","不能","如此"}
words=jieba.lcut(txt)
counts={}
for word in words:
if len(word)==1:
continue
elif word=="诸葛亮" or word=="孔明曰":
rword="孔明"
elif word=="关公" or word=="云长":
rword="关羽"
elif word=="玄德" or word=="玄德曰":
rword="刘备"
elif word=="孟德" or word=="丞相":
rword="曹操"
else:
rword=word
counts[rword]=counts.get(rword,0)+1
for word in excludes:
del counts[word]
items=list(counts.items())
items.sort(key=lambda x:x[1],reverse=True)
for i in range(10):
word,count=items[i]
print("{0:<10}{1:>5}".format(word,count))
曹操 1451
孔明 1383
刘备 1252
关羽 784
张飞 358
商议 344
如何 338
主公 331
军士 317
吕布 300
可以继续将出现的其他非人物词汇加入排除词汇中,进行优化
-
《三国演义》人物出场TOP20
曹操、孔明、刘备、关羽、张飞、吕布、赵云、孙权、司马懿、周瑜、袁绍、马超、魏延、黄忠、姜维、马岱、庞德、孟获、刘表、夏侯惇
“文本词频统计”举一反三
- 举一反三
- 应用问题的扩展
- 《红楼梦》、《西游记》、《水浒传》…
- 政府工作报告、科研论文、新闻报道…
- 进一步呢?未来还有词云
- 应用问题的扩展
练习
-
实例9:基本统计值计算
描述
这是”实例”题,与课上讲解实例相同,请作答检验学习效果。
获取以逗号分隔的多个数据输入(输入为一行),计算基本统计值(平均值、标准差、中位数)
除中位数外,其他输出保留小数点后两位。
请补充编程模板中代码完成
输入输出示例
输入 输出 示例 1 1,3,6,9,2,5,1
平均值:3.86,标准差:2.97,中位数:3
#请在...补充一行或多行代码 #CalStatisticsV1.py def getNum(): #获取用户不定长度的输入 ... def mean(numbers): #计算平均值 ... def dev(numbers, mean): #计算标准差 sdev = 0.0 for num in numbers: sdev = sdev + (num - mean)**2 return pow(sdev / (len(numbers)-1), 0.5) def median(numbers): #计算中位数 ... n = getNum() #主体函数 m = mean(n) print("平均值:{:.2f},标准差:{:.2f},中位数:{}".format(...)) --- #请在...补充一行或多行代码 #CalStatisticsV1.py def getNum(): #获取用户不定长度的输入 s=input() ls=list(eval(s)) return ls def mean(numbers): #计算平均值 tot=0.0 for num in numbers: tot+=num return tot/len(numbers) def dev(numbers, mean): #计算标准差 sdev = 0.0 for num in numbers: sdev = sdev + (num - mean)**2 return pow(sdev / (len(numbers)-1), 0.5) def median(numbers): #计算中位数 numbers.sort()#sorted(numbers) #print(numbers) if len(numbers)%2==0: return (numbers[len(numbers)//2-1]+numbers[len(numbers)//2])/2 else: return numbers[len(numbers)//2] n = getNum() #主体函数 m = mean(n) print("平均值:{:.2f},标准差:{:.2f},中位数:{}".format(m,dev(n,m),median(n))) --- #CalStatisticsV1.py def getNum(): #获取用户不定长度的输入 s = input() ls = list(eval(s)) return ls def mean(numbers): #计算平均值 s = 0.0 for num in numbers: s = s + num return s / len(numbers) def dev(numbers, mean): #计算标准差 sdev = 0.0 for num in numbers: sdev = sdev + (num - mean)**2 return pow(sdev / (len(numbers)-1), 0.5) def median(numbers): #计算中位数 numbers.sort() size = len(numbers) if size % 2 == 0: med = (numbers[size//2-1] + numbers[size//2])/2 else: med = numbers[size//2] return med n = getNum() #主体函数 m = mean(n) print("平均值:{:.2f},标准差:{:.2f},中位数:{}".format(m, dev(n,m),median(n))) 这是本课程的实例9: (1) 获取多个数据:从控制台获取逗号分隔的多个数据 (2) 多函数编写方法:模块化设计方法,每部分功能比较清晰 (3) 排序:列表ls的默认排序方法是ls.sort(),如果从大到小排序,用ls.sort(reverse=True)
-
实例10:文本词频统计 – Hamlet
描述
这是”实例”题,与课上讲解实例相同,请作答检验学习效果。
文本词频统计::一篇文章,出现了哪些词?哪些词出现的最多?
英文文本:hamlet.txt,参考附件(使用鼠标右键另存为下载)
请统计hamlet.txt文件中出现的英文单词情况,统计并输出出现最多的10个单词,注意:
(1) 单词不区分大小写,即单词的大小写或组合形式一样;
(2) 请在文本中剔除如下特殊符号:!”#$%&()*+,-./:;<=>?@[\]^_‘{ }~ (3) 输出10个单词,每个单词一行;
(4) 输出单词为小写形式。
输出样例
以下仅是输出样例(仅列出3个,需要列出10个),不是最终结果:
the
hamlet
be
#请在...处补充代码 def getText(): txt = open("hamlet.txt", "r").read() ... ... --- #请在...处补充代码 def getText(): txt = open("hamlet.txt", "r").read() txt=txt.lower() for item in '!"#$%&()*+,-./:;<=>?@[\\]^_‘{|}~': txt=txt.replace(item," ")#txt.replace(item," ") return txt txt=getText() words=txt.split() m={} for item in words: m[item]=m.get(item,0)+1 items=list(m.items()) items.sort(key=lambda x:x[1],reverse=True) for i in range(10): word,item=items[i] print(word) --- def getText(): txt = open("hamlet.txt", "r").read() txt = txt.lower() for ch in '!"#$%&()*+,-./:;<=>?@[\\]^_‘{|}~': txt = txt.replace(ch, " ") #将文本中特殊字符替换为空格 return txt hamletTxt = getText() words = hamletTxt.split() counts = {} for word in words: counts[word] = counts.get(word,0) + 1 items = list(counts.items()) items.sort(key=lambda x:x[1], reverse=True) for i in range(10): word, count = items[i] # print ("{0:<10}{1:>5}".format(word, count)) 输出出现最多的10个单词和其出现次数 print (word) #输出出现最多的10个单词
-
人名独特性统计
描述
编程模板中给出了一个字符串,其中包含了含有重复的人名,请去重后给出独特性人名的统计。
输出模板中字符串共有多少个独特人名。
输入输出示例
这里是个示例,展示输出格式,不是结果。
输入 输出 示例 1 无 10
s = '''双儿 洪七公 赵敏 赵敏 逍遥子 鳌拜 殷天正 金轮法王 乔峰 杨过 洪七公 郭靖 杨逍 鳌拜 殷天正 段誉 杨逍 慕容复 阿紫 慕容复 郭芙 乔峰 令狐冲 郭芙 金轮法王 小龙女 杨过 慕容复 梅超风 李莫愁 洪七公 张无忌 梅超风 杨逍 鳌拜 岳不群 黄药师 黄蓉 段誉 金轮法王 忽必烈 忽必烈 张三丰 乔峰 乔峰 阿紫 乔峰 金轮法王 袁冠南 张无忌 郭襄 黄蓉 李莫愁 赵敏 赵敏 郭芙 张三丰 乔峰 赵敏 梅超风 双儿 鳌拜 陈家洛 袁冠南 郭芙 郭芙 杨逍 赵敏 金轮法王 忽必烈 慕容复 张三丰 杨逍 令狐冲 黄药师 袁冠南 杨逍 完颜洪烈 殷天正 李莫愁 阿紫 逍遥子 乔峰 逍遥子 完颜洪烈 郭芙 杨逍 张无忌 杨过 慕容复 逍遥子 虚竹 双儿 乔峰 郭芙 黄蓉 李莫愁 陈家洛 杨过 忽必烈 鳌拜 王语嫣 洪七公 韦小宝 阿朱 梅超风 段誉 岳灵珊 完颜洪烈 乔峰 段誉 杨过 杨过 慕容复 黄蓉 杨过 阿紫 杨逍 张三丰 张三丰 赵敏 张三丰 杨逍 黄蓉 金轮法王 郭襄 张三丰 令狐冲 郭芙 韦小宝 黄药师 阿紫 韦小宝 金轮法王 杨逍 令狐冲 阿紫 洪七公 袁冠南 双儿 郭靖 鳌拜 谢逊 阿紫 郭襄 梅超风 张无忌 段誉 忽必烈 完颜洪烈 双儿 逍遥子 谢逊 完颜洪烈 殷天正 金轮法王 张三丰 双儿 郭襄 阿朱 郭襄 双儿 李莫愁 郭襄 忽必烈 金轮法王 张无忌 鳌拜 忽必烈 郭襄 令狐冲 谢逊 梅超风 殷天正 段誉 袁冠南 张三丰 王语嫣 阿紫 谢逊 杨过 郭靖 黄蓉 双儿 灭绝师太 段誉 张无忌 陈家洛 黄蓉 鳌拜 黄药师 逍遥子 忽必烈 赵敏 逍遥子 完颜洪烈 金轮法王 双儿 鳌拜 洪七公 郭芙 郭襄''' ls=s.split() print(len(set(ls)))
-
字典翻转输出
描述
读入一个字典类型的字符串,反转其中键值对输出。
即,读入字典key:value模式,输出value:key模式。
输入格式
用户输入的字典格式的字符串,如果输入不正确,提示:输入错误。
输出格式
给定字典d,按照print(d)方式输出
输入输出示例
输入 输出 示例 1 {"a": 1, "b": 2}
{1: 'a', 2: 'b'}
try: d=eval(input()) dd={} for item in d.items(): a,b=item dd[b]=a print(dd) except: print("输入错误") --- s = input() try: d = eval(s) e = {} for k in d: e[d[k]] = k print(e) except: print("输入错误")
-
《沉默的羔羊》之最多单词
## 描述
附件是《沉默的羔羊》中文版内容,请读入内容,分词后输出长度大于2且最多的单词。
如果存在多个单词出现频率一致,请输出按照Unicode排序后最大的单词。
## 输入格式
文件
## 输出格式
字符串
## 输入输出示例
仅提供一个输出示范样例。
输入 输出 示例 1 无
羔羊
import jieba txt=open("沉默的羔羊.txt","r",encoding="utf-8").read() words=jieba.lcut(txt)#words=txt.lcut(txt) d={} for word in words: if len(word)<=2: continue else: d[word]=d.get(word,0)+1 #items=list(m) #items.sort(key=lambda x:x[1],reverse=True) #print(items[0]) maxcnt=0 maxuni="" for k in d: if maxcnt<d[k]: maxcnt=d[k] maxuni=k elif maxcnt==d[k] and (maxuni=="" or maxuni<k): maxcnt=d[k] maxuni=k print(maxuni) --- import jieba f = open("沉默的羔羊.txt") ls = jieba.lcut(f.read()) #ls = f.read().split() d = {} for w in ls: d[w] = d.get(w, 0) + 1 maxc = 0 maxw = "" for k in d: if d[k] > maxc and len(k) > 2: maxc = d[k] maxw = k if d[k] == maxc and len(k) > 2 and k > maxw: maxw = k print(maxw) f.close()
测验
单项选择题
-
列表ls,哪个选项对ls.append(x)的描述是正确的?
A .向列表ls最前面增加一个元素x
B. 向ls中增加元素,如果x是一个列表,则可以同时增加多个元素
C. 替换列表ls最后一个元素为x
D. 只能向列表ls最后增加一个元素x
D
ls.append(x),如果x是一个列表,则该列表作为一个元素增加的ls中。
-
序列s,哪个选项对s.index(x)的描述是正确的?
A. 返回序列s中元素x所有出现位置的序号
B. 返回序列s中x的长度
C. 返回序列s中序号为x的元素
D. 返回序列s中元素x第一次出现的序号
D
注意:s.index(x)返回第一次出现x的序号,并不返回全部序号。
-
以下不是Python序列类型的是:
A. 字符串类型
B. 元组类型
C. 列表类型
D. 数组类型
D
Python内置数据类型中没有数组类型。
-
给定字典d,哪个选项对d.values()的描述是正确的?
A. 返回一种dict_values类型,包括字典d中所有值
B. 返回一个元组类型,包括字典d中所有值
C. 返回一个列表类型,包括字典d中所有值
D. 返回一个集合类型,包括字典d中所有值
A
运行如下代码:(其中d是一个预定义的字典)
d={"a":1, "b":2} type(d.values())
输出结果是:<class ‘dict_values’>
d.values()返回的是dict_values类型,这个类型通常与for..in组合使用。
-
给定字典d,哪个选项对x in d的描述是正确的?
A. 判断x是否是字典d中的值
B. 判断x是否是字典d中的键
C. x是一个二元元组,判断x是否是字典d中的键值对
D. 判断x是否是在字典d中以键或值方式存在
B
键是值的序号,也是字典中值的索引方式。
因此,x in d 中的x被当作d中的序号进行判断。
-
关于Python组合数据类型,以下描述错误的是:
A. Python的字符串、元组和列表类型都属于序列类型
B. 组合数据类型可以分为3类:序列类型、集合类型和映射类型
C. 组合数据类型能够将多个相同类型或不同类型的数据组织起来,通过单一的表示使数据操作更有序、更容易
D. 序列类型是二维元素向量,元素之间存在先后关系,通过序号访问
D
序列类型总体上可以看成一维向量,如果其元素都是序列,则可被当作二维向量。
-
关于大括号{},以下描述正确的是:
A. 直接使用{}将生成一个元组类型
B. 直接使用{}将生成一个集合类型
C. 直接使用{}将生成一个字典类型
D. 直接使用{}将生成一个列表类型
C
集合类型和字典类型最外侧都用{}表示,不同在于,集合类型元素是普通元素,字典类型元素是键值对。
字典在程序设计中非常常用,因此,直接采用{}默认生成一个空字典。
-
关于Python的元组类型,以下选项错误的是:
A. 元组采用逗号和圆括号(可选)来表示
B. 一个元组可以作为另一个元组的元素,可以采用多级索引获取信息
C. 元组中元素必须是相同类型
D. 元组一旦创建就不能被修改
C
序列类型(元组、列表)中元素都可以是不同类型。
-
哪个选项是下面代码的输出结果?
d={'a':1,'b':2,'b':3}
A. 2
B. {‘b’:2}
C. 1
D. 3
D
创建字典时,如果相同键对应不同值,字典采用最后(最新)一个”键值对”。
-
S和T是两个集合,哪个选项对S^T的描述是正确的?
A. S和T的补运算,包括集合S和T中的非相同元素
B. S和T的差运算,包括在集合S但不在T中的元素
C. S和T的并运算,包括在集合S和T中的所有元素
D. S和T的交运算,包括同时在集合S和T中的元素
A
集合”交并差补”四种运算分别对应的运算符是:& - ^
程序设计题
-
**数字不同数之和 **
描述
获得用户输入的一个整数N,输出N中所出现不同数字的和。
例如:用户输入 123123123,其中所出现的不同数字为:1、2、3,这几个数字和为6。
输入输出示例
输入 输出 示例 1 123123123
6
s=str(input())#s=str(eval(input())) when input 0000001 wrong ls=[] for c in s: ls+=c lt=set(ls) ans=0 for i in lt: ans+=eval(i) print(ans) --- n = input() ss = set(n) s = 0 for i in ss: s += eval(i) print(s) 注意,字符串可以通过list()直接变成列表,或通过set()直接变成集合。
-
人名最多数统计
描述
编程模板中给出了一个字符串,其中包含了含有重复的人名,请直接输出出现最多的人名。
输入输出示例
这里是个示例,展示输出格式,不是结果。
输入 输出 示例 1 无 黄蓉
s = '''双儿 洪七公 赵敏 赵敏 逍遥子 鳌拜 殷天正 金轮法王 乔峰 杨过 洪七公 郭靖 杨逍 鳌拜 殷天正 段誉 杨逍 慕容复 阿紫 慕容复 郭芙 乔峰 令狐冲 郭芙 金轮法王 小龙女 杨过 慕容复 梅超风 李莫愁 洪七公 张无忌 梅超风 杨逍 鳌拜 岳不群 黄药师 黄蓉 段誉 金轮法王 忽必烈 忽必烈 张三丰 乔峰 乔峰 阿紫 乔峰 金轮法王 袁冠南 张无忌 郭襄 黄蓉 李莫愁 赵敏 赵敏 郭芙 张三丰 乔峰 赵敏 梅超风 双儿 鳌拜 陈家洛 袁冠南 郭芙 郭芙 杨逍 赵敏 金轮法王 忽必烈 慕容复 张三丰 赵敏 杨逍 令狐冲 黄药师 袁冠南 杨逍 完颜洪烈 殷天正 李莫愁 阿紫 逍遥子 乔峰 逍遥子 完颜洪烈 郭芙 杨逍 张无忌 杨过 慕容复 逍遥子 虚竹 双儿 乔峰 郭芙 黄蓉 李莫愁 陈家洛 杨过 忽必烈 鳌拜 王语嫣 洪七公 韦小宝 阿朱 梅超风 段誉 岳灵珊 完颜洪烈 乔峰 段誉 杨过 杨过 慕容复 黄蓉 杨过 阿紫 杨逍 张三丰 张三丰 赵敏 张三丰 杨逍 黄蓉 金轮法王 郭襄 张三丰 令狐冲 赵敏 郭芙 韦小宝 黄药师 阿紫 韦小宝 金轮法王 杨逍 令狐冲 阿紫 洪七公 袁冠南 双儿 郭靖 鳌拜 谢逊 阿紫 郭襄 梅超风 张无忌 段誉 忽必烈 完颜洪烈 双儿 逍遥子 谢逊 完颜洪烈 殷天正 金轮法王 张三丰 双儿 郭襄 阿朱 郭襄 双儿 李莫愁 郭襄 忽必烈 金轮法王 张无忌 鳌拜 忽必烈 郭襄 令狐冲 谢逊 梅超风 殷天正 段誉 袁冠南 张三丰 王语嫣 阿紫 谢逊 杨过 郭靖 黄蓉 双儿 灭绝师太 段誉 张无忌 陈家洛 黄蓉 鳌拜 黄药师 逍遥子 忽必烈 赵敏 逍遥子 完颜洪烈 金轮法王 双儿 鳌拜 洪七公 郭芙 郭襄 赵敏''' ls=s.split() d={} for item in ls: d[item]=d.get(item,0)+1 #lt=list(d.items()) #lt.sort(key=lambda x:x[1],reverse=True) #print(lt[0][0])#AC maxcnt=0 name="" for k in d: if d[k]>maxcnt: maxcnt=d[k] name=k print(name) --- s = '''双儿 洪七公 赵敏 赵敏 逍遥子 鳌拜 殷天正 金轮法王 乔峰 杨过 洪七公 郭靖 杨逍 鳌拜 殷天正 段誉 杨逍 慕容复 阿紫 慕容复 郭芙 乔峰 令狐冲 郭芙 金轮法王 小龙女 杨过 慕容复 梅超风 李莫愁 洪七公 张无忌 梅超风 杨逍 鳌拜 岳不群 黄药师 黄蓉 段誉 金轮法王 忽必烈 忽必烈 张三丰 乔峰 乔峰 阿紫 乔峰 金轮法王 袁冠南 张无忌 郭襄 黄蓉 李莫愁 赵敏 赵敏 郭芙 张三丰 乔峰 赵敏 梅超风 双儿 鳌拜 陈家洛 袁冠南 郭芙 郭芙 杨逍 赵敏 金轮法王 忽必烈 慕容复 张三丰 赵敏 杨逍 令狐冲 黄药师 袁冠南 杨逍 完颜洪烈 殷天正 李莫愁 阿紫 逍遥子 乔峰 逍遥子 完颜洪烈 郭芙 杨逍 张无忌 杨过 慕容复 逍遥子 虚竹 双儿 乔峰 郭芙 黄蓉 李莫愁 陈家洛 杨过 忽必烈 鳌拜 王语嫣 洪七公 韦小宝 阿朱 梅超风 段誉 岳灵珊 完颜洪烈 乔峰 段誉 杨过 杨过 慕容复 黄蓉 杨过 阿紫 杨逍 张三丰 张三丰 赵敏 张三丰 杨逍 黄蓉 金轮法王 郭襄 张三丰 令狐冲 赵敏 郭芙 韦小宝 黄药师 阿紫 韦小宝 金轮法王 杨逍 令狐冲 阿紫 洪七公 袁冠南 双儿 郭靖 鳌拜 谢逊 阿紫 郭襄 梅超风 张无忌 段誉 忽必烈 完颜洪烈 双儿 逍遥子 谢逊 完颜洪烈 殷天正 金轮法王 张三丰 双儿 郭襄 阿朱 郭襄 双儿 李莫愁 郭襄 忽必烈 金轮法王 张无忌 鳌拜 忽必烈 郭襄 令狐冲 谢逊 梅超风 殷天正 段誉 袁冠南 张三丰 王语嫣 阿紫 谢逊 杨过 郭靖 黄蓉 双儿 灭绝师太 段誉 张无忌 陈家洛 黄蓉 鳌拜 黄药师 逍遥子 忽必烈 赵敏 逍遥子 完颜洪烈 金轮法王 双儿 鳌拜 洪七公 郭芙 郭襄 赵敏''' ls = s.split() d = {} for i in ls: d[i] = d.get(i, 0) + 1 max_name, max_cnt = "", 0 for k in d: if d[k] > max_cnt: max_name, max_cnt = k, d[k] print(max_name) 这是传统解法,先使用字典建立"姓名与出现次数"的关系,然后找出现次数最多数对应的姓名。
7.文件和数据格式化
7.1 文件的使用
文件的类型
-
文件的理解
- 文件是数据的抽象和集合
- 文件是储存在辅助储存器上的数据序列
- 文件是数据存储的一种形式
- 文件展现形态:文本文件和二进制文件
- 文本文件&二进制文件
- 文本文件和二进制文件只是文件的展示方式
- 本质上,所有文件都是二进制形式存储
- 形式上,所有文件采用两种方式展示
- 文件是数据的抽象和集合
- 由单一特定编码组成的文件,如UTF-8编码
- 由于存在编码,文本文件也被看成是存储着的长字符串
- 适用于例如:.txt文件、.py文件
- 文件是数据的抽象和集合
-
二进制文件
- 文件是数据的抽象和集合
- 直接由比特0和1组成,没有统一字符编码
- 一般存在二进制0和1的组织结构,即文件格式
- 适用于例如:.png文件、.avi文件
- 文件是数据的抽象和集合
-
文本文件&二进制文件
-
“中国是个伟大的国家!”
-
文本形式(如UTF-8)
中国是个伟大的国家!
-
二进制形式(对应的存储形态的二进制形式)
b’\xd6\xd0\xb9\xfa\xca\xc7\xb8\xf6\xce\xb0\xb4\xf3\xb5\xc4\xb9\xfa\xbc\xd2\xa3\xa1’
-
-
f.txt文件保存:”中国是个伟大的国家!”
#文本形式打开文件 tf=open("f.txt","rt") print(tf.readline())#读出一行并打印输出 tf.close() --- #二进制形式打开文件 bf=open("f.txt","rb") print(bf.readline()) bf.close()
-
文件的打开和关闭
-
文件处理的步骤:打开-操作-关闭
-
打开:“文件的存储状态”由a=open(,)到“文件的占用状态”
-
关闭:“文件的占用状态”由a.close()到“文件的存储状态”
-
操作:
-
读文件
a.read(size)
a.readline(size)
a.readlines(hint)
-
写文件
a.write(s)
a.writelines(lines)
a.seek(offset)
-
-
-
文件的打开
<变量名>=open(<文件名>,<打开模式>) - 文件名:文件路径和名称(源文件同目录可省去路径) - 打开模式:文本or二进制,读or写 - 变量名:文件句柄 - 例子: - 需要打开的文件是:D:\PYE\f.txt - 绝对路径 由于在windows下文件路径使用的是\反斜杠 而\在python字符串中被解析为转义符 所以一般用/斜杠替代\反斜杠 即"D:/PYE/f.txt" 当然也可以用\\\替代\ 即"D:\\\\PYE\\\\f.txt" - 相对路径(相对于当前.py文件所在的路径) 如当前.py文件存在D盘根目录 "./PYE/f.txt" 如当前.py文件和要打开的f.txt在同一目录 "f.txt" 打开模式>文件名>变量名> -
打开模式
-
‘r’
只读模式,默认值,如果文件不存在,返回FileNotFoundError
-
‘w’
覆盖写模式,文件不存在则创建,存在则完全覆盖
-
‘x’
创建写模式,文件不存在则创建,存在则返回FileExistsError
-
‘a’
追加写模式,文件不存在则创建,存在则在文件最后追加内容
-
‘t’
文本文件模式,默认值
-
‘b’
二进制文件模式
-
’+’
与r/w/x/a一同使用,在原功能基础上增加同时读写功能
-
例子:
-
f=open(“f.txt”)
默认值:文本形式、只读模式
-
f=open(“f.txt”,”rt”)
同默认值:文本形式、只读模式
-
f=open(“f.txt”,”w”)
文本形式、覆盖写模式
-
f=open(“f.txt”,”a+”)
文本形式、追加写模式+可读文件信息
-
f=open(“f.txt”,”x”)
文本形式、创建写模式
-
f=open(“f.txt”,”b”)
二进制形式、只读模式
-
f=open(“f.txt”,”wb”)
二进制形式、覆盖写模式
-
-
-
文件的关闭
<变量名>.close() 如果不在程序中写这句话,文件会在程序运行过程中保持打开状态,而只要程序正常退出,文件也会被自动关闭 变量名>
文件内容的读取
-
文件内容的读取
-
<f>.read(size=-1)
读入全部内容,如果给出参数,读入前size长度
>>>s=f.read(2)
中国
-
<f>.readline(size=-1)
读入一行内容,如果给出参数,读入该行前size长度
>>>s=f.readline()
中国是个伟大的国家!
-
<f>.readlines(hint=-1)
读入文件所有行,以每行为元素形成列表
如果给出参数,读入前hint行
>>>s=f.readlines()
[‘中国是个伟大的国家!’]
-
-
文件的全文本操作
-
遍历全文本:方法一
fname=input("请输入要打开的文件名称:") fo=open(fname,"r") txt=fo.read() #对全文txt进行处理 fo.close() #一次读入,统一处理
弊端:如果文件体量很大,一次读入代价很大,需要分批次读入、处理
-
遍历全文本:方法二
fname=input("请输入要打开的文件名称:") fo=open(fname,"r") txt=fo.read(2) while txt!="": #对txt进行处理 txt=fo.read(2) fo.close() #按数量读入,逐步处理
-
-
文件的逐行操作
-
逐行遍历文件:方法一
fname=input("请输入要打开的文件名称:") fo=open(fname,"r") for line in fo.readlines():#遍历fo.readlines()这个列表 print(line) fo.close() #一次读入,分行处理
-
逐行遍历文件:方法二
fname=input("请输入要打开的文件名称:") fo=open(fname,"r") for line in fo: print(line) fo.close() #分行读入,逐行处理(针对极大文件)
-
数据的文件写入
-
数据的文件写入
-
<f>.write(s)
向文件写入一个字符串或字节流
>>>f.write(“中国是个伟大的国家!”)
-
<f>.writelines(lines)
将一个元素全为字符串的列表写入文件
>>>ls=[“中国”,”法国”,”美国”]
>>>f.writelines(ls)
中国法国美国
虽然叫writelines,写入的方式并不是分行写入,而是直接拼接列表中的字符串写入,没有换行、空格
-
<f>.seek(offset)#辅助写入的函数
改变当前文件操作指针的位置,offset含义如下:
0-文件开头 1-当前位置 2-文件结尾
>>>f.seek(0)#回到文件开头
-
例子:
fo=open("output.txt","w+") ls=["中国","法国","美国"] fo.writelines(ls) for line in fo: print(line) fo.close() #写入一个字符串列表
我们以为在print后会输出中国法国美国,但是实际上却没有任何输出
这是因为输入后指针在文件末尾,而输出则是从当前位置向文件结尾处取出每一行并打印出来
可以用seek(0),将指针回到文件开头
fo=open("output.txt","w+") ls=["中国","法国","美国"] fo.writelines(ls) fo.seek(0) for line in fo: print(line) fo.close()
-
7.2 实例11:自动轨迹绘制
“自动轨迹绘制”问题分析
-
自动轨迹绘制
-
需求:根据脚本来绘制图形
-
不是写代码而是写数据绘制轨迹
-
使用数据脚本是自动化最重要的第一步
-
给出文件,例如文件中有以下内容
300,0,144,1,0,0
300,0,144,0,1,0
300,0,144,0,0,1
300,0,144,1,1,0
300,0,108,0,1,1
184,0,72,1,0,1
-
“自动轨迹绘制”实例讲解
-
基本思路
- 步骤1:定义数据文件格式(接口)
- 步骤2:编写程序,根据文件接口解析参数绘制图形
- 步骤3:编制数据文件
-
数据接口定义
-
非常具有个性色彩(自己决定)
如上面的数据形式中
第一个数据表示行进距离,第二个0为左转1为右转,第三个是转向角度,最后三个是RGB三个通道颜色
-
#AutoTraceDraw.py
import turtle as t
t.title('自动轨迹绘制')
t.setup(800,600,0,0)
t.pencolor("red")
t.pensize(5)
#数据读取
datals=[]
f=open("data.txt")
for line in f:
line=line.replace("\n","")
datals.append(list(map(eval,line.split(","))))
#map可以将第一个参数的功能作用于第二个参数(列表,组合数据类型)的每个元素
#即用line.split生成一个包含多个“内容为数字的字符串”的列表
#用map(eval,列表)将列表中的每个数字字符串变成数字
#将整个列表当作一个元素放入列表datals末尾
f.close()
#自动绘制
for i in range(len(datals)):
t.pencolor(datals[i][3],datals[i][4],datals[i][5])
t.fd(datals[i][0])
if datals[i][1]:
t.right(datals[i][2])
else:
t.left(datals[i][2])
---
在同目录下创建data.txt,输入
300,0,144,1,0,0
300,0,144,0,1,0
300,0,144,0,0,1
300,0,144,1,1,0
300,0,108,0,1,1
184,0,72,1,0,1
184,0,72,0,0,0
184,0,72,0,0,0
184,0,72,0,0,0
184,1,72,1,0,1
184,1,72,0,0,0
184,1,72,0,0,0
184,1,72,0,0,0
184,1,72,0,0,0
184,1,720,0,0,0
或者点这里使用右键,另存为的方式下载data.txt
“自动轨迹绘制”举一反三
- 理解方法思维
- 自动化思维:数据和功能分离,数据驱动的自动进行
- 接口化设计:格式化设计接口,清晰明了
- 二维数据应用:应用维度组织数据,二维数据最常用
- 应用问题的扩展
- 扩展接口设计,增加更多控制接口
- 扩展功能设计,增加弧形等更多功能
- 扩展应用需求,发展自动轨迹绘制到动画绘制
7.3 一维数据的格式化和处理
数据组织的维度
-
从一个数据到一组数据
一个数据表达一个含义->一组数据表达一个或多个含义
-
维度:一组数据的组织形式
线性?二维?
-
一维数据
- 由对等关系的有序或无序数据构成,采用线性方式组织
- 对应列表、数组、集合等概念
- 由对等关系的有序或无序数据构成,采用线性方式组织
-
二维数据
-
由多个一维数据构成,是一维数据的组合形式
如中国大学排行榜
- 表格是典型的二维数据
- 其中,表头可以作为或不作为二维数据的一部分
-
-
多维数据
-
由一维或二维数据在新维度上扩展形成
如中国大学排行榜在时间维度上有2016、2017、2018…
-
-
高维数据
-
仅利用最基本的二元关系展示数据间的复杂结构
-
键值对
如{‘a’:{‘a’:1,’b’:2}}
-
-
-
数据的操作周期
- 存储<->表示<->操作
- 数据存储:我们关心存储格式
- 数据表示:我们关心数据类型
- 数据操作:我们关心操作方式
- 存储<->表示<->操作
一维数据的表示
- 一维数据的表示
- 如果数据间有序:使用列表类型
- 列表类型可以表达一维有序数据
- for循环可以遍历数据,进而对每个数据进行处理
- 如果数据间无序:使用集合类型
- 集合类型可以表达一维无序数据
- for循环可以遍历数据,进而对每个数据进行处理
- 如果数据间有序:使用列表类型
一维数据的存储
-
一维数据的存储
-
存储方式一:空格分隔
中国 美国 日本 德国 法国 英国 意大利
- 使用一个或多个空格分隔进行存储,不换行
- 缺点:要求数据中不能存在空格
-
存储方式二:逗号分隔
中国,美国,日本,德国,法国,英国,意大利
- 使用英文半角逗号分隔数据进行存储,不换行
- 缺点:要求数据中不能有英文逗号
-
存储方式三:其他方式
中国$美国$日本$德国$法国$英国$意大利
- 使用其他符号或符号组合分隔,建议采用特殊符号
- 缺点:需要根据数据特定定义,通用性较差
-
一维数据的处理
-
数据的处理
- 存储<->表示
- 将存储的数据读入程序
- 将程序表示的数据写入文件
- 存储<->表示
-
一维数据的读入处理
-
从空格分隔的文件中读入数据
中国 美国 日本 德国 法国 英国 意大利
txt=open(fname).read() ls=txt.split() f.close()
-
从特殊符号分隔的文件中读入数据
中国$美国$日本$德国$法国$英国$意大利
txt=open(fname).read() ls=txt.split("$") f.close()
-
-
一维数据的写入处理
-
采用空格分隔方式写入文件
ls=['中国','美国','日本'] f=open(fname,'w') f.write(' '.join(ls)) f.close()
-
采用特殊分隔方式将数据写入文件
ls=['中国','美国','日本'] f=open(fname,'w') f.write('$'.join(ls)) f.close()
-
7.4 二维数据的格式化和处理
二维数据的表示
-
二维数据的表示
-
使用列表类型
-
列表类型可以表达二维数据
-
使用二维列表
[[3.1398,3.1349,3.1376],[3.1413,3.1404,3.1401]]
-
使用两层for循环遍历每个元素
-
外层列表中每个元素可以对应一行,也可以对应一列
-
-
-
一二维数据的Python表示
- 数据维度是数据的组织形式
- 一维数据:列表和集合类型
- 二维数据:列表类型
- 数据维度是数据的组织形式
CSV格式于二维数据的存储
-
CSV数据存储格式
-
CSV:Comma-Separated Values
-
国际通用的一二维数据存储格式,一般.csv扩展名
-
每行一个一维数据,采用逗号分隔,无空行
-
Excel和一般编辑软件都可以读入或另存为csv文件
-
实例:
城市 环比 同比 定基 北京 101.5 120.7 121.4 上海 101.2 127.3 127.8 广州 101.3 119.4 120.0 深圳 102.0 140.0 145.5 沈阳 100.0 101.4 101.6 转换为CSV格式后是:
城市,环比,同比,定基 北京,101.5,120.7,121.4 上海,101.2,127.3,127.8 广州,101.3,119.4,120.0 深圳,102.0,140.0,145.5 沈阳,100.0,101.4,101.6
-
如果某个元素缺失,逗号仍要保留
-
二维数据的表头可以作为数据存储,也可以另行存储
-
逗号为英文半角符号,逗号与数据之间无额外空格
-
对于数据中出现的逗号,有两边加“”和\转义符的方法解决,而CSV是一种较成熟的体系,能处理这样的问题,这里我们暂时不考虑这个问题
-
-
-
二维数据的存储
- 按行存?按列存?
- 按行存或者按列存都可以,具体由程序决定
- 一般索引习惯:ls[row][column],先行后列
- 根据一般习惯,外层列表每个元素是一行,按行存
- 按行存?按列存?
二维数据的处理
-
二维数据的读入处理
-
从CSV格式的文件中读入数据
fo=open(fname) ls=[] for line in fo: line=line.replace("\n","") ls.append(line.split(",")) fo.close()
-
将数据写入CSV格式的文件
ls=[[],[],[]]#二维列表 f=open(fname,'w') for item in ls: f.write(','.join(item)+'\n') f.close()
-
-
二维数据的逐一处理
-
采用二层循环
ls=[[1,2],[3,4],[5,6]]#二维列表 for row in ls: for column in row: print(column)
-
7.5 模块6:wordcloud库的使用
wordcloud库基本介绍
-
wordcloud是优秀的词云展示第三方库
- 词云以词语为基本单位,更加直观和艺术的展示文本
-
wordcloud库安装
cmd命令行:pip install wordcloud
wordcloud库使用说明
-
wordcloud库基本使用
- wordcloud库把词云当作一个WordCloud对象
- wordcloud.WordCloud()代表一个文本对应的词云
- 可以根据文本中词语出现的频率等参数绘制词云
- 绘制词云的形状、尺寸和颜色都可以设定
- wordcloud库把词云当作一个WordCloud对象
-
wordcloud库常规方法
-
w=wordcloud.WordCloud()
-
以WordCloud对象为基础
-
配置参数、加载文本、输出文件
-
w.generate(txt)
向WordCloud对象w中加载文本txt
>>>w.generate(“Python and WordCloud”)
-
w.to_file(filename)
将词云输出为图像文件,.png/.jpg/…格式
>>>w.to_file(“outfile.png”)
-
-
步骤1:配置对象参数
-
步骤2:加载词云文本
-
步骤3:输出词云文件
-
实例:
import wordcloud c=wordcloud.WordCloud() c.generate("wordcloud by Python") c.to_file("pywordcloud.png")
其中wordcloud库做了四件事
- 分隔:以空格分隔单词
- 统计:单词出现次数并过滤
- 字体:根据统计配置字号
- 布局:颜色环境尺寸
-
-
配置对象参数
-
w=wordcloud.WordCloud(<参数>)参数>
-
width
指定词云对象生成图片的宽度,默认400像素
>>>w=wordcloud.WordCloud(width=600)
-
height
指定词云对象生成图片的高度,默认200像素
>>>w=wordcloud.WordCloud(height=400)
-
min_font_size
指定词云中字体的最小字号,默认4号
>>>w=wordcloud.WordCloud(min_font_size=10)
-
max_font_size
指定词云中字体的最大字号,根据高度自动调节
>>>w=wordcloud.WordCloud(max_font_size=20)
-
font_step
指定词云中字体字号的步进间隔,默认为1
>>>w=wordcloud.WordCloud(font_step=2)
-
font_path
指定字体文件的路径,默认None
>>>w=wordcloud.WordCloud(font_path=”msyh.ttc”)#这里指中文字体用微软雅黑
-
max_words
指定词云显示的最大单词数量,默认200
>>>w=wordcloud.WordCloud(max_words=20)
-
stop_words#应该是stopwords
指定词云的排除词列表,即不显示的单词列表
>>>w=wordcloud.WordCloud(stop_words={“Python”})#一般用集合类型
-
mask
指定词云形状,默认为长方形,需要引用imread()函数
>>>from scipy.misc import imread
>>>mk=imread(“pic.png”)
>>>w=wordcloud.WordCloud(mask=mk)
-
background_color
指定词云图片的背景颜色,默认为黑色
>>>w=wordcloud.WordCloud(background_color=”white”)
-
-
-
wordcloud应用实例
import wordcloud txt="life is short, you need python" w=wordcloud.WordCloud(background_color="white") w.generate(txt) w.to_file("pywcloud.png") --- import jieba import wordcloud txt="程序设计语言是计算机能够理解和\ 识别用户操作意图的一种交互体系,它按照\ 特定规则组织计算机指令,使计算机能够自\ 动进行各种运算处理" w=wordcloud.WordCloud(width=1000,height=700,font_path="msyh.ttc") w.generate(" ".join(jieba.lcut(txt))) w.to_file("pywcloud.png")
7.6 实例12:政府工作报告词云
“政府工作报告词云”问题分析
-
问题分析
-
直观理解政策文件
-
需求:对于政府工作报告等政策文件,如何直观理解
-
体会直观的价值:生成词云&优化词云
政府报告等文件->有效展示的词云
-
-
“政府工作报告词云”实例解析
-
政府工作报告词云
- 基本思路
- 步骤1:读取文件、分词整理
- 步骤2:设置并输出词云
- 步骤3:观察结果,优化迭代
- 基本思路
-
#GovRptWordCloudv1.py import jieba,wordcloud f=open("新时代中国特色社会主义.txt","r",encoding="utf-8") t=f.read() f.close() ls=jieba.lcut(t) txt=" ".join(ls) w=wordcloud.WordCloud(font_path="msyh.ttc",\ width=1000,height=700,background_color="white",\ max_words=15) w.generate(txt) w.to_file("grwordcloud.png") --- #GovRptWordCloudv1.py import jieba,wordcloud f=open("关于实施乡村振兴战略的意见.txt","r",encoding="utf-8") t=f.read() f.close() ls=jieba.lcut(t) txt=" ".join(ls) w=wordcloud.WordCloud(font_path="msyh.ttc",\ width=1000,height=700,background_color="white",\ max_words=15) w.generate(txt) w.to_file("grwordcloud.png")
-
更有型的词云
需要在根目录提供背景为白色的图案,如下面的fu.png文件
并安装scipy库
#GovRptWordCloudv2.py import jieba,wordcloud from scipy.misc import imread mask=imread("fu.png") f=open("新时代中国特色社会主义.txt","r",encoding="utf-8") t=f.read() f.close() ls=jieba.lcut(t) txt=" ".join(ls) w=wordcloud.WordCloud(font_path="msyh.ttc",mask=mask,\ width=1000,height=700,background_color="white") w.generate(txt) w.to_file("grwordcloud.png") --- 注意,from scipy.misc import imread,imwrite等方法已被弃用,Python已经将imread方法封装在了imageio模块中,需要安装imageio库,使用以下方法 --- #GovRptWordCloudv2.py import jieba,wordcloud import imageio msk=imageio.imread("fu.jpg") f=open("新时代中国特色社会主义.txt","r",encoding="utf-8") t=f.read() f.close() ls=jieba.lcut(t) txt=" ".join(ls) w=wordcloud.WordCloud(font_path="msyh.ttc",mask=msk,\ width=1000,height=700,background_color="white") w.generate(txt) w.to_file("grwordcloud.png")
“政府工作报告词云”举一反三
- 举一反三
- 扩展能力
- 了解wordcloud更多参数,扩展词云能力
- 特色词云:设计一款属于自己的特色词云风格
- 更多文件:用更多文件练习词云生成
- 扩展能力
练习
-
文件行数
描述
打印输出附件文件的有效行数,注意:空行不计算为有效行数。
输入输出示例
这是仅给出输出格式样例,不是结果。
输入 输出 示例 1 `` 共100行
f=open("latex.log","r") cnt=0 for line in f.readlines(): if line=='\n': continue else: cnt+=1 print("共{}行".format(cnt)) --- f = open("latex.log") s = 0 for line in f: line = line.strip('\n') if len(line) == 0: continue s += 1 print("共{}行".format(s)) 需要注意:for line in f方式获得的每行内容(在变量line中)包含换行符,所以,要通过strip()函数去掉换行符后再进行统计。这里,空行指没有字符的行。
-
文件字符分布
描述
统计附件文件的小写字母a-z的字符分布,即出现a-z字符的数量,并输出结果。
同时请输出文件一共包含的字符数量。
注意输出格式,各元素之间用英文逗号(,)分隔。
答案可能包含a-z共26个字符的分布,如果某个字符没有出现,则不显示,输出顺序a-z顺序。
输入输出示例
仅格式示例,非最终答案。
输入 输出 示例 1 `` 共999字符,a:11,b:22,c:33,d:44,e:55
f=open("latex.log") txt=f.read() dic={} for i in txt: if 'a'<=i<='z': dic[i]=dic.get(i,0)+1 print("共{}字符".format(len(txt)),end="") for i in range(ord('a'),ord('z')+1): if dic.get(chr(i),0)!=0: print(",{}:{}".format(chr(i),dic[chr(i)]),end="") --- f = open("latex.log") cc = 0 d = {} for i in range(26): d[chr(ord('a')+i)] = 0 for line in f: for c in line: d[c] = d.get(c, 0) + 1 cc += 1 print("共{}字符".format(cc), end="") for i in range(26): if d[chr(ord('a')+i)] != 0: print(",{}:{}".format(chr(ord('a')+i), d[chr(ord('a')+i)]), end="") 使用 ord('a')+i 配合 range()函数 可以遍历一个连续的字符表。
-
文件独特行数
描述
统计附件文件中与其他任何其他行都不同的行的数量,即独特行的数量。
输入输出示例
此处仅示例输出格式。
输入 输出 示例 1 `` 共99独特行
ans=0 f=open("latex.log") txt=f.readlines() dic={} for lines in txt: if dic.get(lines,0)==0: dic[lines]=1 ans+=1 elif dic[lines]==1: dic[lines]=2 ans-=1 print("共{}独特行".format(ans)) --- f = open("latex.log") ls = f.readlines() s = set(ls) for i in s: ls.remove(i) t = set(ls) print("共{}独特行".format(len(s)-len(t))) 记住:如果需要"去重"功能,请使用集合类型。 ls.remove()可以去掉某一个元素,如果该行是独特行,去掉该元素后将不在集合t中出现。
-
CSV格式列变换
描述
附件是一个CSV文件,请将每行按照列逆序排列后输出,不改变各元素格式(如周围空格布局等)。
输入输出示例
这是一个格式示例,不是正确结果。
输入 输出 示例 1 (以下是文件内容) 1,2,3,4 a,b,c,d
4,3,2,1 d,c,b,a
f=open("data.csv") txt=f.readlines() ls=[] for line in txt: line=line.replace('\n',"") lt=line.split(',') lt.reverse()#lt=lt.reverse() ls.append(lt) for lt in ls: print(','.join(lt)) --- f = open("data.csv") for line in f: line = line.strip("\n") ls = line.split(",") ls = ls[::-1] print(",".join(ls)) f.close()
-
CSV格式数据清洗
描述
附件是一个CSV文件,其中每个数据前后存在空格,请对其进行清洗,要求如下:
(1)去掉每个数据前后空格,即数据之间仅用逗号(,)分割;
(2)清洗后打印输出。
输入输出示例
这里是一个格式示例,不是正确结果。
输入 输出 示例 1 (在文件中) 1, 2, 3, 4, 5 'a', 'b' , 'c' , 'd','e'
1,2,3,4,5 'a','b','c','d','e'
f=open("data.csv") for line in f: line=line.replace(" ","") print(line,end="") --- f = open("data.csv") s = f.read() s = s.replace(" ","") print(s) f.close() 该CSV文件的每个数据中不包含空格,因此,可以通过替换空格方式来清洗。如果数据中包含空格,该方法则不适用。
测验
单项选择题
-
关于数据组织的维度,哪个选项的描述是错误的?
A. 数据组织存在维度,字典类型用于表示一维和二维数据
B. 高维数据由键值对类型的数据构成,采用对象方式组织
C. 一维数据采用线性方式组织,对应于数学中的数组和集合等概念
D. 二维数据采用表格方式组织,对应于数学中的矩阵
A
字典用于表示高维数据,一般不用来表示一二维数据。
-
以下选项不是Python文件读操作的是:
A. readtext()
B. readlines()
C. readline()
D. read()
A
没有readtext()方法
-
对于Python文件,以下描述正确的是:
A. 当文件以文本方式打开时,读取按照字节流方式
B. 根据不同类型的文件,打开方式只能是文本或者二进制中的一种
C. 当文件以二进制文件方式打开时,读取按照字符串方式
D. 同一个文件可以既采用文本方式打开,也可以采用二进制方式打开
D
文件就在那里,二进制或文本方式打开只是对其不同的程序理解。
-
关于CSV文件的描述,哪个选项的描述是错误的?
A. CSV文件的每一行是一维数据,可以使用Python中的列表类型表示
B. 整个CSV文件是一个二维数据
C. CSV文件格式是一种通用的、相对简单的文件格式,应用于程序之间转移表格数据
D. CSV文件通过多种编码表示字符
D
一般来说,CSV文件都是文本文件,由相同编码字符组成。
-
关于Python文件的‘+’打开模式,哪个选项的描述是正确的?
A. 追加写模式
B. 覆盖写模式
C. 与r/w/a/x一同使用,在原功能基础上增加同时读写功能
D. 只读模式
C
’+’打开模式的精髓在于它能够同时赋予文件的读写权限。
-
给定列表ls = [1, 2, 3, “1”, “2”, “3”],其元素包含2种数据类型,哪个选项是列表ls的数据组织维度?
A. 高维数据
B. 二维数据
C. 多维数据
D. 一维数据
D
列表元素如果都是列表,其可能表示二维数据,例如:[[1,2], [3,4], [5,6]]。
如果列表元素不都是的将列表,则它表示一维数据。
-
关于文件关闭的close()方法,哪个选项的描述是正确的?
A. 文件处理后可以不用close()方法关闭文件,程序退出时会默认关闭
B. 如果文件是只读方式打开,仅在这种情况下可以不用close()方法关闭文件
C. 文件处理遵循严格的“打开-操作-关闭”模式
D. 文件处理结束之后,一定要用close()方法关闭文件
A
打开文件后采用close()关闭文件是一个好习惯。如果不调用close(),当前Python程序完全运行退出时,该文件引用被释放,即程序退出时,相当于调用了close()。
-
二维列表ls=[[1,2,3], [4,5,6],[7,8,9]],哪个选项能获取其中元素5?
A. ls[-2][-1]
B. ls[4]
C. ls[-1][-1]
D. ls[1][1]
D
这是二维切片的使用方式。
-
以下选项对文件描述错误的是:
A. 文件是程序的集合和抽象
B. 文件可以包含任何内容
C. 文件是数据的集合和抽象
D. 文件是存储在辅助存储器上的数据序列
A
函数或类是程序的集合和抽象,文件不是。
-
Python对文件操作采用的统一步骤是:
A. 打开—操作—关闭
B. 操作—读取—写入
C. 打开—读写—写入
D. 打开—读取—写入—关闭
A
打开—操作—关闭 是一个统一步骤,其中,关闭可以省略。
程序设计题
-
文本的平均列数
描述
打印输出附件文件的平均列数,计算方法如下:
(1)有效行指包含至少一个字符的行,不计算空行;
(2)每行的列数为其有效字符数;
(3)平均列数为有效行的列数平均值,采用四舍五入方式取整数进位。
输入输出示例
仅给出输出格式示例,非正确答案。
输入 输出 示例 1 无
123
file=open("latex.log") txt=file.readlines() cnt1=0 cnt2=0 for line in txt: line=line.strip("\n") if len(line)==0: continue cnt1+=len(line) cnt2+=1 if cnt2!=0: print(round(cnt1/cnt2)) else: print(0) --- f = open("latex.log") s, c = 0, 0 for line in f: line = line.strip("\n") if line == "": continue s += len(line) c += 1 print(round(s/c)) 请注意:for line in f获取的line包含每行最后的换行符(\n),所以,去掉该换行符进行统计。
-
**CSV格式清洗与转换 **
描述
附件是一个CSV格式文件,提取数据进行如下格式转换:
(1)按行进行倒序排列;
(2)每行数据倒序排列;
(3)使用分号(;)代替逗号(,)分割数据,无空格;
按照上述要求转换后将数据输出。
输入输出示例
以下是一个格式示例,不是最终结果。
输入 输出 示例 1 (以下内容在文件中) 1,2,3 4,5,6 7,8,9
9;8;7 6;5;4 3;2;1
file=open("data.csv") txt=file.readlines() ls=[] for line in txt: line=line.strip("\n") line=line.replace(" ","")## lt=line.split(",") lt=lt[::-1] ls.append(lt) ls.reverse() for lt in ls: print(";".join(lt)) --- f = open("data.csv") ls = f.readlines() ls = ls[::-1] lt = [] for item in ls: item = item.strip("\n") item = item.replace(" ", "") lt = item.split(",") lt = lt[::-1] print(";".join(lt)) f.close() 注意:使用strip()方法去掉每行最后的回车,使用replace()去掉每行元素两侧的空格。
8.程序设计方法学
8.1 实例13:体育竞技分析
“体育竞技分析”问题分析
-
问题分析
-
体育竞技分析
高手过招,胜负只在毫厘之间
- 需求:毫厘是多少?如何科学分析体育竞技比赛?
- IPO
- 输入:球员的水平
- 输出:可预测的比赛成绩
-
体育竞技分析:模拟N场比赛
- 计算思维:抽象+自动化
- 模拟:抽象比赛过程+自动化执行N场比赛
- 当N越大时,比赛结果分析会越科学
-
抽象比赛规则
- 双人击球比赛:A&B,回合制,5局3胜
- 开始时一方先发球,直至判分,接下来胜者发球
- 球员只能在发球局得分,15分胜一局
-
自顶向下和自底向上
-
自顶向下(设计)
-
解决复杂问题的有效方法
-
将一个总问题表达为若干个小问题组成的形式
-
使用同样方法进一步分解小问题
-
直至,小问题可以用计算机简单明了地解决
-
例子:
改善居住条件
分为:种树(简单)、盖楼
盖楼:楼房盖哪里,楼的设计和施工
楼的设计和施工:建筑工人,建筑材料,相关组织监理
-
-
-
自底向上(执行)
-
逐步组建复杂系统的有效测试方法
-
分单元测试,逐步组装
-
按照自顶向下相反的路径操作
-
直至,系统各部分以组装的思路都经过测试和验证
-
例子:
改善居住条件
采购到了建筑材料,有建筑工人对相关楼宇进行建造
建造好后进行测试(对各开发模块进行整合和测试)
形成了大楼
每个区域都这样造楼
-
-
“体育竞技分析”实例解析
-
体育竞技分析
-
程序总体框架及步骤
-
步骤1:打印程序的介绍性信息
-printInfo()
-
步骤2:获得程序运行参数(读入):proA,proB,n
-getInputs()
-
步骤3:利用球员A和B的能力值模拟n局比赛
-simNGames()
-
步骤4:输出球员A和B获胜比赛的场次及概率
-printSummary()
-
-
第一阶段:程序总体框架及步骤
$main()\begin{cases}printInfo()\<-(proA,proB,n)getInputs()\->(proA,proB,n)simNGames()\->(winsA,winsB)printSummary()\end{cases}$
def main(): printInfo() probA,probB,n=getInputs() winsA,winsB=simNGames(n,probA,probB) printSummary(winsA,winsB)
def printIntro(): print("这个程序模拟两个选手A和B的某种竞技比赛") print("程序运行需要A和B的能力值(以0到1之间的小数表示)") #介绍性内容,提高用户体验
def getInputs(): a=eval(input("请输入选手A的能力值(0-1):")) b=eval(input("请输入选手B的能力值(0-1):")) n=eval(input("模拟比赛的场次:")) return a,b,n
def printSummary(winsA,winsB): n=winsA+winsB print("竞技分析开始,共模拟{}场比赛".format(n)) print("选手A获胜{}场比赛,占比{:0.1%}".format(winsA,winsA/n)) print("选手B获胜{}场比赛,占比{:0.1%}".format(winsB,winsB/n))
-
第二阶段:步骤3 模拟N局比赛
$simNGames()<->simOneGame()$
def simNGames(n,probA,probB): winsA,winsB=0,0 for i in range(n): scoreA,scoreB=simOneGame(probA,probB) if scoreA>scoreB: winsA+=1 else: winsB+=1 return winsA,winsB
$simOneGame()<->GameOver()$
-
第三阶段
def simOneGame(probA,probB): scoreA,scoreB=0,0 serving='A' while not gameOver(scoreA,scoreB): if serving=='A': if random()<probA: scoreA+=1 else: serving='B' else: if random()<probB: scoreB+=1 else: serving='A' return scoreA,scoreB
def gameOver(a,b): return a==15 or b==15
-
合并
from random import random def gameOver(a,b): return a==15 or b==15 def simOneGame(probA,probB): scoreA,scoreB=0,0 serving='A' while not gameOver(scoreA,scoreB): if serving=='A': if random()<probA: scoreA+=1 else: serving='B' else: if random()<probB: scoreB+=1 else: serving='A' return scoreA,scoreB def simNGames(n,probA,probB): winsA,winsB=0,0 for i in range(n): scoreA,scoreB=simOneGame(probA,probB) if scoreA>scoreB: winsA+=1 else: winsB+=1 return winsA,winsB def printSummary(winsA,winsB): n=winsA+winsB print("竞技分析开始,共模拟{}场比赛".format(n)) print("选手A获胜{}场比赛,占比{:0.1%}".format(winsA,winsA/n)) print("选手B获胜{}场比赛,占比{:0.1%}".format(winsB,winsB/n)) def getInputs(): a=eval(input("请输入选手A的能力值(0-1):")) b=eval(input("请输入选手B的能力值(0-1):")) n=eval(input("模拟比赛的场次:")) return a,b,n def printIntro(): print("这个程序模拟两个选手A和B的某种竞技比赛") print("程序运行需要A和B的能力值(以0到1之间的小数表示)") #介绍性内容,提高用户体验 def main(): printIntro() probA,probB,n=getInputs() winsA,winsB=simNGames(n,probA,probB) printSummary(winsA,winsB) main()
-
“体育竞技分析”举一反三
- 举一反三
- 理解自顶向下和自底向上
- 理解自顶向下的设计思维:分而治之
- 理解自底向上的执行思维:模块化集成
- 自顶向下是“系统”思维的简化
- 应用问题的扩展
- 扩展比赛参数,增加对更多能力对比情况的判断
- 扩展比赛设计,增加对真实比赛结果的预测
- 扩展分析逻辑,反向推理,用胜率推算能力?
- 理解自顶向下和自底向上
8.2 Python程序设计思维
计算思维与程序设计
-
计算思维
-
第3种人类思维特征
- 逻辑思维:推理和演绎,数学为代表,A->B B->C A->C
- 实证思维:实验和验证,物理为代表,引力波<-实验
- 计算思维:设计和构造,计算机为代表,汉诺塔递归
-
抽象和自动化
- 计算思维:Computational Thinking
- 抽象问题的计算过程,利用计算机自动化求解
- 计算思维是基于计算机的思维方式
-
例子:
-
计数求和:计算1-100的计数和
逻辑思维:高斯小时候的玩法$s=\frac{(a_1+a_n)n}{2}$
计算思维:现代人用计算机的玩法
s=0 for i in range(1,101): s+=i
-
圆周率的计算
逻辑思维:数学家用近似公式$\pi=\sum_{k=0}^{\infty}[\frac{1}{16^{k}}(\frac{4}{8k+1}-\frac{2}{8k+4}-\frac{1}{8k+5}-\frac{1}{8k+6})]$
计算思维:随机大量撒点
-
汉诺塔问题
逻辑思维:推导$2^n-1$
计算思维:递归
-
天气预报
以前大部分地方靠实证思维+逻辑思维
现在超级计算机用MM5模型(计算思维)
-
量化分析
如何买股票?
拿出k线图,看到小坑和小峰,代表什么操作
利用经验预测未来的涨跌
这是实证思维+逻辑思维
计算思维:
利用历史大量数据
以机器学习的方法预测涨跌并用计算机完成自动交易
-
-
抽象问题的计算过程,利用计算机自动化求解
- 计算思维基于计算机强大的算力和海量的数据
- 抽象计算过程,关注过程、构造和设计,而非因果
- 以计算机程序设计为实现的主要手段
-
编程是将计算思维变成现实的手段
- 我们既需要以设计和构造为特征的抽象问题的能力
- 也需要以编程为手段的自动化执行方法
-
计算生态与Python语言
-
计算生态
-
从开源运动说起…
- 1983,Richard Stallman启动GNU项目
- 1989,GNU通用许可协议诞生,自由软件时代到来
- 1991,Linus Torvalds发布了Linux内核
- 1998,网景浏览器开源,产生了Mozilla,开源生态逐步建立
- Richard Stallman-大教堂模式,认为软件是高大上的,应该由精英开发,普通用户使用
- Linus Torvalds-集市模式,认为软件任何人可以开发,贡献之后软件服务于大众
- 集市模式是真真正正推动开源运动进一步演进的主要模式
-
开源思想深入演化和发展,形成了计算生态
计算生态以开源项目为组织形式,充分利用“共识原则”和“社会利他”组织人员,在竞争发展、相互依存和迅速更迭中完成信息技术的更新换代,形成了技术的自我演化路径。
-
没有顶层设计、以功能为单位、具备三个特点
- 竞争发展
- 相互依存
- 迅速更迭
-
-
计算生态与Python语言
-
以开源项目为代表的大量第三方库
Python语言提供>15万个第三方库
-
库的建设经过野蛮生长和自然选择
同一功能,Python语言2个以上第三方库
-
库之间相互关联使用,依存发展
Python库间广泛联系,逐级封装
如数据处理领域的Numpy;Matplotlib、Pandas等数据处理的第三方库都是基于它编写的上层功能
-
社区庞大,新技术更迭迅速
AlphaGo深度学习算法采用Python语言开源
-
API(应用程序编写接口)!=生态
API是经过设计的产物,而不是野蛮生长出来的产物
-
-
计算生态的价值
- 创新:跟随->集成->原始
- 加速科技类应用创新的重要支撑
- 发展科技产品商业价值的重要模式
- 国家科技体系安全和稳固的基础
- 创新:跟随->集成->原始
-
计算生态的运用
刀耕火种->站在巨人的肩膀上
- 编程的起点不是算法而是系统
- 编程如同搭积木,利用计算生态为主要模式
- 编程的目标是快速解决问题
- 优质的计算生态推荐:http://python123.io
用户体验与软件产品
-
用户体验
- 实现功能->关注体验
- 用户体验指用户对产品建立的主观感受和认识
- 关心功能实现,更要关心用户体验,才能做出好产品
- 编程只是手段,不是目的,程序最终为人类服务
- 实现功能->关注体验
-
提高用户体验的方法
-
方法1:进度展示
- 如果程序需要计算时间,可能产生等待,请增加进度展示
- 如果程序有若干个步骤,需要提示用户,请增加进度展示
- 如果程序可能存在大量次数的循环,请增加进度展示
-
方法2:异常处理
- 当获得用户输入,对合规性需要检查,需要异常处理
- 当读写文件时,对结果进行判断,需要异常处理
- 当进行输入输出时,对运算结果进行判断,需要异常处理
-
其他类方法
- 打印输出:特定位置,输出程序运行的过程信息
- 日志文件:对程序异常及用户使用进行定期记录
- 帮助信息:给用户多种方式提供帮助信息
-
软件程序->软件产品
用户体验是程序到产品的关键环节
-
基本的程序设计模式
-
基本的程序设计模式
- 从IPO开始
- I:Input输入,程序的输入
- P:Process处理,程序的主要逻辑
- O:Output输出,程序的输出
- 确定IPO:明确计算部分及功能边界
- 编写程序:将计算求解的设计变为现实
- 调试程序:确保程序按照正常逻辑能够正确运行
- 模块化设计
- 通过函数或对象封装将程序划分为模块和模块间的表达
- 具体包括:主程序、子程序和子程序间关系
- 分而治之:一种分而治之、分层抽象、体系化的设计思想
- 紧耦合:两个部分之间交流很多,无法独立存在
- 松耦合:两个部分之间交流较少,可以独立存在
- 模块内部紧耦合,模块间松耦合
- 配置化设计
- 程序引擎+配置文件
- 引擎+配置:程序执行和配置分离,将可选参数配置化
- 将程序开发变成配置文件编写,扩展功能而不修改程序
- 关键在于接口设计,清晰明了、灵活可扩展
- 从IPO开始
-
应用开发的四个步骤
-
从应用需求到软件产品
-
1-产品定义:对应用需求充分理解和明确定义
产品定义,而不仅是功能定义,要考虑商业模式
-
2-系统架构:以系统方式思考产品的技术实现
系统架构,关注数据流、模块化、体系结构
-
3-设计与实现:结合架构完成关键设计及系统实现
结合可扩展性、灵活性等进行设计优化
-
4-用户体验:从用户角度思考应用效果
用户至上,体验优先,以用户为中心
-
-
8.3 Python第三方库安装
看见更大的Python世界
- Python社区
- PyPI
- PyPI:Python Package Index
- PSF(Python Software Foundation维护)维护的展示全球Python计算生态的主站
- 学会检索并利用PyPI,找到合适的第三方库开发程序
- 实例:开发与区块链相关的程序
- 第1步:在pypi.org搜索blockchain
- 第2步:挑选适合开发目标的第三方库作为基础
- 第3步:完成自己需要的功能
- PyPI
- 安装Python第三方库
- 三种方法
- 方法1(主要):使用pip命令
- 方法2:集成安装方法
- 方法3:文件安装方法
- 三种方法
第三方库的pip安装方法
-
pip安装方法
-
使用pip安装工具(命令行下执行)
- 命令行中输入pip -h可以查看帮助信息
-
常用的pip命令
-
pip install <第三方库名>第三方库名>
安装指定的第三方库
-
pip install -U <第三方库名>第三方库名>
使用-U标签更新已安装的指定第三方库
-
pip uninstall <第三方库名>第三方库名>
卸载指定的第三方库
-
pip download <第三方库名>第三方库名>
下载但不安装指定的第三方库
-
pip show <第三方库名>第三方库名>
列出某个指定第三方库的详细信息
-
pip search <关键词>关键词>
根据关键词在名称和介绍中搜索第三方库
-
pip list
列出当前系统已经安装的第三方库
-
-
主要方法,适合99%以上情况
- 适合Windows、Mac和Linux等操作系统
- 未来获取第三方库的方式,目前的主要方式
- 适合99%以上情况,需要联网安装
-
第三方库的集成安装方法
- 集成安装方法
- Anaconda
- 支持近800个第三方库
- 包含多个主流工具
- 适合数据计算领域开发(数据分析数据展示)
- Anaconda
第三方库的文件安装方法
-
文件安装方法
-
为什么有些第三方库用pip可以下载,但无法安装?
- 某些第三方库pip下载后,需要编译再安装
- 如果操作系统没有编译环境,则能下载但不能安装
- 可以直接下载编译后的版本用于安装吗?
-
给出了Windows下一批可以下载,但需编译再安装的第三方库的直接编译后的版本
- 实例:安装wordcloud库
- 步骤1:在UCI页面上搜索wordcloud
- 步骤2:下载对应版本的文件
- 步骤3:使用pip install <文件名> 安装文件名>
- 实例:安装wordcloud库
-
8.4 模块7:os库的使用
os库基本介绍
- os库基本介绍
- os库提供通用的、基本的操作系统(包括windows、linux、macos)交互功能
- os库是Python标准库,包含几百个函数
- 常用路径操作、进程管理、环境参数等几类
- 路径操作:os.path子库,处理文件路径及信息
- 进程管理:启动系统中其他程序
- 环境参数:获得系统软硬件信息等环境参数
- os库提供通用的、基本的操作系统(包括windows、linux、macos)交互功能
os库之路径操作
-
路径操作
-
os.path子库以path为入口,用于操作和处理文件路径
import os.path import os.path as op
-
os.path.abspath(path)
返回path在当前系统中的绝对路径
>>>os.path.abspath(“file.txt”)
‘C:\\Users\\Tian Song\\Python36-32\\file.txt’
-
os.path.normpath(path)
归一化path的表示形式,统一用\\分隔路径
>>>os.path.normpath(“D://PYE//file.txt”)
‘D:\\PYE\\file.txt’
-
os.path.relpath(path)
返回当前程序与文件之间的相对路径(relative path)
>>>os.path.relpath(“C://PYE//file.txt”)
’..\\..\\..\\..\\..\\..\\..\\PYE\\file.txt’
-
os.path.dirname(path)
返回path中的目录名称
>>>os.path.dirname(“D://PYE//file.txt”)
‘D://PYE’
-
os.path.basename(path)
返回path最后的文件名称
>>>os.path.dirname(“D://PYE//file.txt”)
‘file.txt’
-
os.path.join(path,*paths)
组合path与paths,返回一个路径字符串
>>>os.path.join(“D:/”,”PYE/file.txt”)
‘D:/PYE/file.txt’
-
os.path.exists(path)
判断path对应文件或目录是否存在,返回True或False
>>>os.path.exists(“D://PYE//file.txt”)
False
-
os.path.isfile(path)
判断path所对应是否为已存在的文件,返回True或False
>>>os.path.isfile(“D://PYE//file.txt”)
True
-
os.path.isdir(path)
判断path所对应是否为已存在的目录,返回True或False
>>>os.path.isdir(“D://PYE//file.txt”)
False
-
os.path.getatime(path)#a-access访问
返回path对应文件或目录上一次的访问时间
>>>os.path.getatime(“D:/PYE/file.txt”)
1518356633.7551725
-
os.path.getmtime(path)#m-modify修改
返回path对应文件或目录最近一次的修改时间
>>>os.path.getmtime(“D:/PYE/file.txt”)
1518356633.7551725
-
os.path.getctime(path)#c-create创建
返回path对应文件或目录的创建时间
>>>time.ctime(os.path.getctime(“D:/PYE/file.txt”))
‘Sun Feb 11 21:43:53 2018’
-
os.path.getsize(path)
返回path对应文件的大小,以字节为单位
>>>os.path.getsize(“D:/PYE/file.txt”)
180768
-
os库之进程管理
-
进程管理
-
os.system(command)
-
执行程序或命令command
-
在Windows系统中,返回值为cmd的调用返回信息
-
例子:
import os os.system("C:\\Windows\\System32\\calc.exe") #调用了计算机自带的计算器程序,并给出返回值0(指程序正确运行) --- import os os.system("C:\\Windows\\System32\\mspaint.exe D:\\PYECourse\\grwordcloud.png") #使用Windows自带画图程序打开grwordcloud.png文件
-
-
os库之环境参数
-
环境参数
-
获取或改变系统环境信息
-
os.chdir(path)
修改当前程序操作的路径
>>>os.chdir(“D:”)
-
os.getcwd()
返回程序的当前路径
>>>os.getcwd()
‘D:\\’
-
os.getlogin()
获得当前系统登录用户名称
>>>os.getlogin()
‘Tian Song’
-
os.cpu_count()
获得当前系统的CPU数量
>>>os.cpu_count()
8
-
os.urandom(n)
获得n个字节长度的随机字符串,通常用于加解密运算
>>>os.urandom(10)
b’&\xd9\t\x85\xf9\xc7\xf6\x8c\t\xba’
(由于某些字符串不能被有效打印出来,它将会用16进制的形式表示)
-
-
8.5 实例14:第三方库安装脚本
“第三方库安装脚本”问题分析
- 问题分析
- 第三方库自动安装脚本
- 需求:批量安装第三方库需要人工干预,能否自动安装?
- 自动执行pip逐一根据安装需求安装
- 如何自动执行一个程序?例如pip?
- 比如我们要自动安装20个第三方库
- NumPy:N维数据表示和运算;pip install numpy
- Matplotlib:二维数据可视化;pip install matplotlib
- PIL:图像处理;pip install pillow
- Scikit-Learn:机器学习和数据挖掘;pip install sklearn
- Requests:HTTP协议访问及网络爬虫;pip install requests
- Jieba:中文分词;pip install jieba
- Beautiful Soup:HTML和XML解析器;pip install beautifulsoup4
- Wheel:Python第三方库打包工具;pip install wheel
- PyInstaller:打包Python源文件为可执行文件;pip install pyinstaller
- Django:Python最流行的Web开发框架;pip install django
- Flask:轻量级Web开发框架;pip install flask
- WeRoBot:微信机器人开发框架;pip install werobot
- SymPy:数学符号计算工具;pip install sympy
- Pandas:高效数据分析和计算;pip install pandas
- Networkx:复杂网络和图结构的建模和分析;pip install networkx
- PyQt5:基于Qt的专业级GUI开发框架;pip install pyqt5
- PyOpenGL:多平台OpenGL开发接口;pip install pyopengl
- PyPDF2:PDF文件内容提取及处理;pip install pypdf2
- docopt:Python命令行解析;pip install docopt
- PyGame:简单小游戏开发框架;pip install pygame
- 第三方库自动安装脚本
“第三方库安装脚本”实例解析
-
第三方库自动安装脚本
#BatchInstall.py import os libs={"numpy","matplotlib","pillow","sklearn","requests","jieba",\ "beautifulsoup4","wheel","pyinstaller","django","flask","werobot",\ "sympy","pandas","networkx","pyqt5","pyopengl","pypdf2","docopt","pygame"} #try: # for lib in libs: # os.system("pip install "+lib) # print("Successful") #except: # print("Failed Somehow") for lib in libs: try: os.system("pip install "+lib) print("Succeed in installing "+lib) except: print("Failed in installing "+lib)
“第三方库安装脚本”举一反三
- 举一反三
- 自动化脚本+
- 编写各类自动化运行程序的脚本,调用已有程序
- 扩展应用:安装更多第三方库,增加配置文件(如自动轨迹绘制实例)
- 扩展异常检测:捕捉更多异常类型,程序更稳定友好
- 自动化脚本+
测验
单项选择题
-
关于用户体验,以下选项描述正确的是:
A. 好产品不一定有好的用户体验,关键在于功能创意
B. 用户体验是客观的,完全可以靠技术来实现
C. 用户体验不重要,只要有程序功能即可
D. 编程只是手段,程序最终为人类服务,用户体验很重要
D
一个提醒进度的进度条、一个永不抛出异常的程序、一个快速的响应、一个漂亮的图标、一个合适尺寸的界面等都是用户体验的组成部分。总的来说,用户体验是一切能够提升程序用户感受的组成。
-
以下选项关于计算生态描述错误的是:
A. 计算生态类似自然生态,不受单一组织或人物的控制,形成了技术演化路径
B. 计算生态主要以开源项目为组织形式
C. 计算生态存在竞争发展、相互依存和迅速更迭的特点
D. 高质量计算生态需要顶层设计的参与才能保障
D
计算生态以竞争发展、相互依存和迅速更迭为特点,在开源项目间不存在顶层设计,以类自然界”适者生存”的方式形成技术演进路径。
-
以下选项对计算思维本质描述正确的是:
A. 计算和思维
B. 描述和执行
C. 抽象和自动化
D. 抽象和执行
C
计算思维的本质是:抽象和自动化。
抽象一个运算过程,以能够按步骤描述为目标;并利用计算机运算的高速特性自动化执行。
-
关于软件产品和程序的区别,以下描述正确的是:
A. 软件产品=程序功能+用户体验
B. 软件产品=程序功能+速度优化
C. 从程序功能到软件产品的产品化代价很小
D. 软件程序就是软件产品
A
产品不仅需要功能,更需要更好的用户体验。往往,产品都需要综合考虑技术功能和人文设计,这源于产品的商业特性。即,商业竞争要求产品不能只关心技术功能,更要关心用户易用和喜好需求。
-
关于Python第三方库安装方法,以下选项描述错误的是:
A. 使用集成安装工具
B. 使用pip命令
C. 访问UCI网站下载安装文件
D. 联系第三方库作者索要安装文件
D
请不要联系作者索要第三方库,这不是获取第三方库的合理模式。
-
关于Python的os库,以下选项描述正确的是:
A. os库是一个第三方库,需要安装后使用
B. os库提供了路径操作、进程管理等若干类功能
C. os库仅适用于Windows平台
D. os库提供了几十个函数,功能比较有限
B
os库是Python重要的标准库之一,提供了几百个函数功能,覆盖与操作系统、文件操作等相关的众多功能。os库适合所有操作系统。
-
关于os.path子库,以下选项中用来计算相对路径的函数是:
A. os.path.relpath(path)
B. os.path.abspath(path)
C. os.path.basename(path)
D. os.path.normpath(path)
A
顾名思义:os.path.relpath(path) 是 relative path处理函数。
-
关于os库,以下选项中可以启动进程执行程序的函数是:
A. os.process()
B. os.start()
C. os.system()
D. os.run()
C
除了os.system(),选项其他函数都不存在。
-
自顶向下设计主要由下列哪个语法元素实现?
A. 过程
B. 对象
C. 循环结构
D. 函数
D
函数是自顶向下设计的关键元素,通过定义函数及其参数逐层开展程序设计。
-
关于计算思维,以下选项描述正确的是:
A. 计算思维是基于计算机的思维模式
B. 计算思维是逻辑思维的演进
C. 计算思维关于设计和构造,可以脱离计算机而存在
D. 计算思维从古至今一直存在
A
计算思维是基于计算机的思维模式,计算机出现之前,由于没有快速计算装置,计算所反映的思维模式主要是数学思维,即通过公式来求解问题。当快速计算装置出现后,计算思维才真正形成。
程序设计题
-
英文字符的鲁棒输入
描述
获得用户的任何可能输入,将其中的英文字符进行打印输出,程序不出现错误。
输入输出示例
输入 输出 示例 1 *&^123abc0e
abce
string=str(input()) for c in string: if 'A'<=c<='Z' or 'a'<=c<='z': print(c,end="") --- alpha = [] for i in range(26): alpha.append(chr(ord('a') + i)) alpha.append(chr(ord('A') + i)) s = input() for c in s: if c in alpha: print(c, end="") 注意:这里采用遍历字符的方式实现,通过约束字母表达到鲁棒效果。
-
数字的鲁棒输入
描述
获得用户输入的一个数字,可能是浮点数或复数,如果是整数仅接收十进制形式,且只能是数字。对输入数字进行平方运算,输出结果。
要求:
(1)无论用户输入何种内容,程序无错误;
(2)如果输入有误,请输出”输入有误”。
输入输出示例
输入 输出 示例 1 1+2j
(-3+4j)
示例2 abd
输入有误
try: a=str(input()) b=eval(a) if str(b).strip("()")!=a:#处理复数eval后两边加() print("输入有误") else: print(b**2) except: print("输入有误") --- s = input() try: if complex(s) == complex(eval(s)): print(eval(s)**2) except: print("输入有误") complex()和complex(eval())之间的比较将能够排除非数字类型的输入。 注意:不能直接使用eval(),否则,用户可以通过输入表达式(如100**2)输入数字,与要求不同(在实际应用中带来安全隐患)。
9.Python计算生态概览
9.1 从数据处理到人工智能
-
从数据处理到人工智能
-
数据表示->数据清洗->数据统计->数据可视化->数据挖掘->人工智能
- 数据表示:采用合适方式用数据表达数据
- 数据清洗:数据归一化、数据转换、异常值处理
- 数据统计:数据的概要理解,数量、分布、中位数等
- 数据可视化:直观展示数据内涵的方式
- 数据挖掘:从数据分析获得知识,产生数据外的价值
- 人工智能:数据、语言、图像、视觉等方面深度分析与决策
本单元要求:了解Python庞大的计算生态,只要知道有这样的库和名称即可
-
Python库之数据分析
-
Numpy:表达N维数组的最基本库
-
Python接口使用,C语言实现,计算速度优异
-
Python数据分析及科学计算的基础库,支撑Pandas等
-
提供直接的矩阵运算、广播函数、线性代数等功能
由 def pySum(): a=[0,1,2,3,4] b=[9,8,7,6,5] c=[] for i in range(len(a)): c.append(a[i]**2+b[i]**3) return c print(pySum()) 到 import numpy as np def npSum(): a=np.array([0,1,2,3,4]) b=np.array([9,8,7,6,5]) c=a**2+b**3 return c print(npSum())
-
-
Pandas:Python数据分析高层次应用库
- 提供了简单易用的数据结构和数据分析工具
- 理解数据类型与索引的关系,操作索引即操作数据
- Python最主要的数据分析功能库,基于Numpy开发
- Pandas提供了两个数据结构:
- Series=索引+一维数据
- DataFrame=行列索引+二维数据
- pandas库通过扩展对一维数据和二维数据的表示,因而能够形成更高层次对数据的操作,简化数据分析的运行
-
SciPy:数学、科学和工程计算功能库
- 提供了一批数学算法及工程数据运算功能
- 类似Matlab,可用于如傅里叶变换、信号处理等应用
- Python最主要的科学计算功能库,基于Numpy开发
- 提供的功能:
- 傅里叶变换类
- 信号处理类
- 线性代数类
- 图像处理类
- 稀疏图压缩类
- 稀疏图运算类
- 优化算法类
Python库之数据可视化
- Matplotlib:高质量的二维数据可视化功能库
- 提供了超过100种数据可视化展示效果
- 通过matplotlib.pyplot子库调用各可视化效果
- Python最主要的数据可视化功能库,基于Numpy开发
- Seaborn:统计类数据可视化功能库
- 提供了一批高层次的统计类数据可视化展示效果
- 主要展示数据间分布、分类和线性关系等内容
- 基于Matplotlib开发,支持Numpy和Pandas
- Mayavi:三维科学数据可视化功能库
- 提供了一批简单易用的3D科学计算数据可视化展示效果
- 目前版本是Mayavi2,三维可视化最主要的第三方库
- 支持Numpy、TVTK、Traits、Envisage等第三方库
Python库之文本处理
-
PyPFD2:用来处理pdf文件的工具集
-
提供了一批处理PDF文件的计算功能
-
支持获取信息、分隔/整合文件、加密解密等
-
完全Python语言实现,不需要额外依赖,功能稳定
#整合两个pdf文件 from PyPDF2 import PdfFileReader,PdfFileMerger merger=PdfFileMerger() input1=open("document1.pdf","rb") input2=open("document2.pdf","rb") merger.append(fileobj=input1,pages=(0,3)) merger.merge(position=2,fileobj=input2,pages=(0,1)) output=open("document-output.pdf","wb") merger.write(output)
-
-
NLTK:自然语言文本处理第三方库
-
提供了一批简单易用的自然语言文本处理功能
-
支持语言文本分类、标记、语法语句、语义分析等
-
最优秀的Python自然语言处理库
from nltk.corpus import treebank t=treebank.parsed_sents('wsj_0001.mrg')[0] t.draw()
-
-
Python-docx:创建或更新Microsoft Word文件的第三方库
-
提供创建或更新.doc/.docx等文件的计算功能
-
增加并配置段落、图片、表格、文字等,功能全面
from docx import Document document=Document() document.add_heading('Document Title',0) p=document.add_paragraph('A plain paragraph having some ') document.add_page_break()#分页符 document.save('demo.docx')
-
Python库之机器学习
-
Scikit-learn:机器学习方法工具集
- 提供一批统一化的机器学习方法功能接口
- 提供聚类、分类、回归、强化学习等计算功能
- 机器学习最基本且最优秀的Python第三方库
-
TensorFlow:AlphaGo背后的机器学习计算框架
-
谷歌公司推动的开源机器学习框架
-
将数据流图作为基础,图节点代表运算,边代表张量
-
应用机器学习方法的一种方式,支撑谷歌人工智能应用
import tensorflow as tf init=tf.global_variables_initializer() sess=tf.Session() sess.run(init) res=sess.run(result) print('result:',res)
-
-
MXNet:基于神经网络的深度学习计算框架
- 提供可扩展的神经网络及深度学习计算框架
- 可用于自动驾驶、机器翻译、语音识别等众多领域
- Python最重要的深度学习计算框架
9.2 实例15:霍兰德人格分析雷达图
“霍兰德人格分析雷达图”问题分析
- 问题分析
- 雷达图 Radar Chart
- 雷达图是多特性直观展示的重要方式
- 霍兰德人格分析
- 霍兰德认为:人格兴趣与职业之间应有一种内在的对应关系
- 人格分类:研究型、艺术型、社会型、企业型、传统型、现实型
- 职业:工程师、实验员、艺术家、推销员、记事员、社会工作者
- 霍兰德人格分析雷达图
- 需求:雷达图方式验证霍兰德人格分析
- 输入:各职业人群结合兴趣的调研数据
- 输出:雷达图
- 通用雷达图绘制:matplotlib库
- 专业的多维数据表示:numpy库
- 雷达图 Radar Chart
“霍兰德人格分析雷达图”实例展示
#HollandRadarDraw
import numpy as np
import matplotlib.pyplot as plt
import matplotlib
matplotlib.rcParams['font.family']='SimHei'
radar_labels=np.array(['研究型(I)','艺术型(A)','社会型(S)',\
'企业型(E)','常规型(C)','现实型(R)'])
data = np.array([[0.40,0.32,0.35,0.30,0.30,0.88],
[0.85,0.35,0.30,0.40,0.40,0.30],
[0.43,0.89,0.30,0.28,0.22,0.30],
[0.30,0.25,0.48,0.85,0.45,0.40],
[0.20,0.38,0.87,0.45,0.32,0.28],
[0.34,0.31,0.38,0.40,0.92,0.28]]) #数据值
data_labels = ('艺术家','实验员','工程师','推销员','社会工作者','记事员')
angles = np.linspace(0,2*np.pi, 6, endpoint=False)
data = np.concatenate((data, [data[0]]))
angles = np.concatenate( (angles,[angles[0]]))
fig = plt. figure(facecolor= "white" )
plt.subplot(111, polar= True)
plt.plot(angles,data,'o-',linewidth=1,alpha=0.2)
plt.fill(angles,data, alpha=0.25)
plt.thetagrids(angles*180/np.pi,radar_labels,frac = 1.2)
plt.figtext(0.52, 0.95,'霍兰德人格分析', ha='center', size=20)
legend = plt.legend(data_labels, loc=(0.94,0.80), labelspacing=0.1)
plt.setp(legend.get_texts(), fontsize='large')
plt.grid(True)
plt.savefig('holland_radar.jpg')
plt.show()
#运行报错可能是库更新导致
“霍兰德人格分析雷达图”举一反三
- 举一反三
- 目标+沉浸+熟练
- 编程的目标感:寻找感兴趣的目标,寻觅之,挖掘之
- 编程的沉浸感:寻找可实现的方法,思考之,琢磨之
- 编程的熟练度:练习、练习、练习,熟练之
- 目标+沉浸+熟练
9.3 从Web解析到网络空间
Python库之网络爬虫
-
Requests:最友好的网络爬虫功能库
-
提供了简单易用的类HTTP协议网络爬虫功能
-
支持连接池、SSL、Cookies、HTTP(S)代理等
-
Python最主要的页面级网络爬虫功能库
import requests r=requests.get('https://api.github.com/user',\ auth=('user','pass')) r.status_code r.headers['content-type'] r.encoding r.text
-
-
Scrapy:优秀的网络爬虫框架
- 提供了构建网络爬虫系统的框架功能,功能半成品
- 支持批量和定时网页爬取、提供数据处理流程等
- Python最主要且最专业的网络爬虫框架
-
pyspider:强大的Web页面爬取系统
- 提供了完整的网页爬取系统构建功能
- 支持数据库后端、消息队列、优先级、分布式架构等
- Python重要的网络爬虫第三方库
Python库之Web信息提取
-
Beautiful Soup:HTML和XML的解析库
- 提供了解析HTML和XML等Web信息的功能
- 又名beautifulsoup4或bs4,可以加载多种解析引擎
- 常与网络爬虫库搭配使用,如Scrapy、requests等
- bs4中将所有HTML页面以树形结构进行组织,通过上行遍历、下行遍历、平行遍历等操作去解析其中内容
- 使用该库需先理解HTML和XML的设计原理
-
Re(regular expression):正则表达式解析和处理功能库
-
提供了定义和解析正则表达式的一批通用功能
-
可用于各类场景,包括定点的Web信息提取
-
Python最主要的标准库之一,无需安装
如定义字符串,它是正则表达式格式
r’\d{3}-\d{8} \d{4}-\d{7}’ Re库有search(),match(),findall(),split(),finditer(),sub()等函数
来围绕它进行信息查找和信息匹配,有利于我们查找文本中的特定模式
-
-
Python-Goose:提取文章类型Web页面的功能库
-
提供了对Web页面中文章信息/视频等元数据的提取功能
-
针对特定类型Web页面,应用覆盖面较广
-
Python最主要的Web信息提取库
from goose import Goose url = 'http://www.elmundo.es/elmundo/2012/10/28/espana/1351388909.html' g = Goose({'use_meta_language': False, 'target_language':'es'}) article = g.extract(url=url) article.cleaned_text[:150]
-
Python库之Web网站开发
-
Django:最流行的Web应用框架
- 提供了构建Web系统的基本应用框架
- MTV模式:模型(model)、模板(Template)、视图(Views)
- Python最重要的Web应用框架,略微复杂的应用框架
- 需要了解WSGI、路由、功能处理逻辑、数据库与展示层面如何构建
-
Pyramid:规模适中的Web应用框架
-
提供了简单方便构建Web系统的应用框架
-
不大不小,规模适中,适合快速构建并适度扩展类应用
-
Python产品级Web应用框架,起步简单可扩展性好
-
比如可以用10行左右代码构建一个Web应用系统
from wsgiref.simple_server import make_server from pyramid.config import Configurator from pyramid.response import Response def hello_world(request): return Response('Hello World!') if __name__ == '__main__': with Configurator as config config.add_route('hello','/') config.add_view(hello_world,route_name='hello') app=config.make_wsgi_app() server=make_server('0.0.0.0',6543,app) server.serve_forever()
-
-
Flask:Web应用开发微框架
-
提供了最简单构建Web系统的应用框架
-
特点是:简单、规模小、快速
-
规模上:Django>Pyramid>Flask
from flask import Flask app=Flask(__name__) @app.route('/') def hello_world(): return 'Hello,World!'
-
Python库之网络应用开发
-
WeRoBot:微信公众号开发框架
-
提供了解析微信服务器信息及反馈消息的功能
-
建立微信机器人的重要技术手段
#对微信每个消息反馈一个Hello World import werobot robot=werobot.WeRoBot(token='tokenhere') @robot.handler def hello(message): return 'Hello World!'
-
-
aip:百度AI开发平台接口
- 提供了访问百度AI服务的Python功能接口
- 语言、人脸、OCR、NLP、知识图谱、图像搜索等领域
- Python百度AI应用的最主要方式
-
MyQR:二维码生成第三方库
- 提供了生成二维码的系列功能
- 基本二维码、艺术二维码和动态二维码
9.4 从人机交互到艺术设计
Python库之图形用户界面
-
PyQt5:Qt开发框架的Python接口
- 提供了创建Qt5程序的Python API接口
- Qt是非常成熟的跨平台桌面应用开发系统,完备GUI(图形用户界面)
- 推荐的Python GUI开发第三方库
-
wxPython:跨平台GUI开发框架
-
提供了专用于Python的跨平台GUI开发框架
-
理解数据类型与索引的关系,操作索引即操作数据
-
Python最主要的数据分析功能库,基于Numpy开发
import wx app=wx.App(False) frame=wx.Frame(None,wx.ID_ANY,"Hello World") frame.Show(True) app.MainLoop()
-
-
PyGObject:使用GTK+开发GUI的功能库
-
提供了整合GTK+、WebKitGTK+等库的功能
-
GTK+:跨平台的一种用户图形界面GUI框架
-
实例:Anaconda采用该库构建GUI
import gi gi.require_version("Gtk","3.0") from gi.repository import Gtk window=Gtk.Window(title="Hello World") window.show() window.connect("destroy",Gtk.main_quit) Gtk.main()
-
Python库之游戏开发
- PyGame:简单的游戏开发功能库
- 提供了基于SDL的简单游戏开发功能及实现引擎
- 理解游戏对外部输入的响应机制及角色构建和交互机制
- Python游戏入门最主要的第三方库
- Panda3D:开源、跨平台的3D渲染和游戏开发库
- 一个3D游戏引擎,提供Python(推荐)和C++两种接口
- 支持很多先进特性:法线贴图、光泽贴图、卡通渲染等
- 由迪士尼和卡内基梅隆大学共同开发
- cocos2d:构建2D游戏和图形界面交互式应用的框架
- 提供了基于OpenGL的游戏开发图形渲染功能
- 支持GPU加速,采用树形结构分层管理游戏对象类型
- 适用于2D专业级游戏开发
Python库之虚拟现实
- VR Zero:在树莓派上开发VR应用的Python库
- 提供大量与VR开发相关的功能
- 针对树莓派的VR开发库,支持设备小型化,配置简单化
- 非常适合初学者实践VR开发及应用
- Raspberry Pi(中文名为“树莓派”,简写为RPi,(或者RasPi / RPI) 是为学习计算机编程教育而设计),只有信用卡大小的微型电脑,其系统基于Linux。随着Windows 10 IoT的发布,我们也将可以用上运行Windows的树莓派。
- pyovr:Oculus Rift的Python开发接口
- 针对Oculus VR设备的Python开发库
- 基于成熟的VR设备,提供全套文档,工业级应用设备
- Python+虚拟现实领域探索的一种思路
- Vizard:基于Python的通用VR开发引擎
- 专业的企业级虚拟现实开发引擎
- 提供详细的官方文档
- 支持多种主流的VR硬件设备,具有一定通用性
Python库之图形艺术
- Quads:迭代的艺术
- 对图片进行四分迭代,形成像素风
- 可以生成动图或静图图像
- 简单易用,具有很高展示度
- ascii_art:ASCII艺术库
- 将普通图片转为ASCII艺术风格
- 输出可以是纯文本或彩色文本
- 可采用图片格式输出
- turtle:海龟绘图体系
- Random Art
- 可以用turtle绘制与Random Art相关的艺术图形
9.5 实例16:玫瑰花绘制
“玫瑰花绘制”问题分析
- 玫瑰花绘制
- 需求:用Python绘制一朵玫瑰花,献给所思所想
- 输入:你的想象力!
- 输出:玫瑰花
- 绘制机理:turtle基本图形绘制
- 绘制思想:因人而异
- 思想有多大、世界就有多大
“玫瑰花绘制”实例展示
# RoseDraw.py
import turtle as t
# 定义一个曲线绘制函数
def DegreeCurve(n, r, d=1):
for i in range(n):
t.left(d)
t.circle(r, abs(d))
# 初始位置设定
s = 0.2 # size
t.setup(450*5*s, 750*5*s)
t.pencolor("black")
t.fillcolor("red")
t.speed(100)
t.penup()
t.goto(0, 900*s)
t.pendown()
# 绘制花朵形状
t.begin_fill()
t.circle(200*s,30)
DegreeCurve(60, 50*s)
t.circle(200*s,30)
DegreeCurve(4, 100*s)
t.circle(200*s,50)
DegreeCurve(50, 50*s)
t.circle(350*s,65)
DegreeCurve(40, 70*s)
t.circle(150*s,50)
DegreeCurve(20, 50*s, -1)
t.circle(400*s,60)
DegreeCurve(18, 50*s)
t.fd(250*s)
t.right(150)
t.circle(-500*s,12)
t.left(140)
t.circle(550*s,110)
t.left(27)
t.circle(650*s,100)
t.left(130)
t.circle(-300*s,20)
t.right(123)
t.circle(220*s,57)
t.end_fill()
# 绘制花枝形状
t.left(120)
t.fd(280*s)
t.left(115)
t.circle(300*s,33)
t.left(180)
t.circle(-300*s,33)
DegreeCurve(70, 225*s, -1)
t.circle(350*s,104)
t.left(90)
t.circle(200*s,105)
t.circle(-500*s,63)
t.penup()
t.goto(170*s,-30*s)
t.pendown()
t.left(160)
DegreeCurve(20, 2500*s)
DegreeCurve(220, 250*s, -1)
# 绘制一个绿色叶子
t.fillcolor('green')
t.penup()
t.goto(670*s,-180*s)
t.pendown()
t.right(140)
t.begin_fill()
t.circle(300*s,120)
t.left(60)
t.circle(300*s,120)
t.end_fill()
t.penup()
t.goto(180*s,-550*s)
t.pendown()
t.right(85)
t.circle(600*s,40)
# 绘制另一个绿色叶子
t.penup()
t.goto(-150*s,-1000*s)
t.pendown()
t.begin_fill()
t.rt(120)
t.circle(300*s,115)
t.left(75)
t.circle(300*s,100)
t.end_fill()
t.penup()
t.goto(430*s,-1070*s)
t.pendown()
t.right(30)
t.circle(-600*s,35)
t.done()
“玫瑰花绘制”举一反三
-
举一反三
-
艺术之于编程,设计之于编程
- 艺术:思想优先,编程是手段
- 设计:想法和编程同等重要
- 工程:编程优先,思想次之
-
编程不重要,思想才重要!
老师在布置玫瑰花的绘制作业后,有一位学生的作业打开只输出了rose,但是老师给了很高的分,因为他对艺术绘制的理解很有创新思维QAQ
- 认识自己:明确自己的目标,有自己的思想和想法
- 方式方法:编程只是手段,熟练之,未雨绸缪为思想服务
- 为谁编程:将自身发展与祖国发展相结合,创造真正价值
-
测验
单项选择题
-
以下选项不是Python网络爬虫方向第三方库的是:
A. Scrapy
B. Python-Goose
C. pyspider
D. Requests
B
Python-Goose是Web提取第三方库。
-
以下选项不是Python人工智能方向第三方库的是:
A. MXNet
B. Seaborn
C. Scikit-Learn
D. TensorFlow
B
Seaborn是数据可视化第三方库。
-
以下选项不是Python文本处理方向第三方库的是:
A. PyPDF2
B. pyovr
C. NLTK
D. python-docx
B
pyovr是增强现实开发库。
-
以下选项不是Python Web信息提取方向第三方库的是:
A. Python-Goose
B. wxPython
C. Beautiful Soup
D. Re
B
wxPython是GUI第三方库。
-
以下选项不是Python网站开发框架方向第三方库的是:
A. Flask
B. redis-py
C. Pyramid
D. Django
B
redis-py是redis数据的Python访问接口。
-
以下选项不是Python网络应用开发方向第三方库的是:
A. WeRobot
B. MyQR
C. numpy
D. aip
C
numpy是多维度数据处理第三方库。
-
以下选项不是Python图形用户界面方向第三方库的是:
A. wxPython
B. PyQt5
C. PyGObject
D. Vizard
D
Vizard是虚拟现实第三方库。
-
以下选项不是Python游戏开发方向第三方库的是:
A. PyGame
B. cocos2d
C. aip
D. Panda3D
C
aip是baidu的人工智能功能Python访问接口。
-
以下选项不是Python数据分析方向第三方库是:
A. Pandas
B. Numpy
C. Scrapy
D. SciPy
C
Scrapy是网络爬虫库
-
以下选项不是Python数据可视化方向第三方库的是:
A. Pyramid
B. Matplotlib
C. Mayavi
D. Seaborn
A
Pyramid是Web开发框架库。
程序设计题
-
系统基本信息获取
描述
获取系统的递归深度、当前执行文件路径、系统最大UNICODE编码值等3个信息,并打印输出。
输出格式如下:
RECLIMIT:<深度>, EXEPATH:<文件路径>, UNICODE:<最大编码值>最大编码值>文件路径>深度>
提示:请在sys标准库中寻找上述功能。
输入输出示例
这里仅是格式参考,非正确答案,请注意,输出中每个逗号(,)后面都有一个空格。
输入 输出 示例 1 无
RECLIMIT:500, EXEPATH:/bin/python, UNICODE:1411
import sys print("RECLIMIT:{}, EXEPATH:{}, UNICODE:{}".format(sys.getrecursionlimit(),sys.executable,sys.maxunicode)) --- import sys print("RECLIMIT:{}, EXEPATH:{}, UNICODE:{}".format(sys.getrecursionlimit(), sys.executable, sys.maxunicode)) 基本信息获取
-
二维数据表格输出
描述
tabulate能够对二维数据进行表格输出,是Python优秀的第三方计算生态。
参考编程模板中给定的数据和代码,编写程序,能够输出如下风格效果的表格数据。
输入输出示例
输入 输出 示例 1 参考编程模板
如题干图
import tabulate data = [ ["北京理工大学", "985", 2000], \ ["清华大学", "985", 3000], \ ["大连理工大学", "985", 4000], \ ["深圳大学", "211", 2000], \ ["沈阳大学", "省本", 2000], \ ] print(tabulate.tabulate(data,tablefmt='grid')) --- from tabulate import tabulate data = [ ["北京理工大学", "985", 2000], \ ["清华大学", "985", 3000], \ ["大连理工大学", "985", 4000], \ ["深圳大学", "211", 2000], \ ["沈阳大学", "省本", 2000], \ ] print(tabulate(data, tablefmt="grid")) tabulate库更多使用请参考该库的文档。
10.全课程总结与学习展望
期末测验:课程水平综合测验
-
无空隙回声输出
描述
获得用户输入,去掉其中全部空格,将其他字符按收入顺序打印输出。
输入输出示例
输入 输出 示例 1 Alice + Bob
Alice+Bob
s=str(input()) s=s.replace(" ","") print(s) --- txt = input() print(txt.replace(" ", ""))
-
文件关键行数
描述
关键行指一个文件中包含的不重复行。关键行数指一个文件中包含的不重复行的数量。
统计附件文件中与关键行的数量。
输入输出示例
此处仅示例输出格式。
输入 输出 示例 1 `` 共99关键行
f=open("latex.log") txt=f.readlines() s=set(txt) print("共{}关键行".format(len(s))) --- f = open("latex.log") ls = f.readlines() s = set(ls) print("共{}关键行".format(len(s))) 记住:如果需要"去重"功能,请使用集合类型。
-
字典翻转输出
描述
读入一个字典类型的字符串,反转其中键值对输出。
即,读入字典key:value模式,输出value:key模式。
输入格式
用户输入的字典格式的字符串,如果输入不正确,提示:输入错误。
输出格式
给定字典d,按照print(d)方式输出
输入输出示例
输入 输出 示例 1 {"a": 1, "b": 2}
{1: 'a', 2: 'b'}
try: dic1=eval(input()) dic2={} for key in dic1: dic2[dic1[key]]=key print(dic2) except: print("输入错误") --- s = input() try: d = eval(s) e = {} for k in d: e[d[k]] = k print(e) except: print("输入错误")
-
《沉默的羔羊》之最多单词
描述
附件是《沉默的羔羊》中文版内容,请读入内容,分词后输出长度大于2且最多的单词。
如果存在多个单词出现频率一致,请输出按照Unicode排序后最大的单词。
输入格式
文件
输出格式
字符串
输入输出示例
仅提供一个输出示范样例。
输入 输出 示例 1 无
羔羊
import jieba f=open("沉默的羔羊.txt",encoding="utf-8").read() txt=jieba.lcut(f) maxword="" maxcnt=0 dic={} for word in txt: if len(word)<=2: continue else: dic[word]=dic.get(word,0)+1 for key in dic: if dic[key]>maxcnt: maxcnt=dic[key] maxword=key elif dic[key]==maxcnt and (maxword=="" or key>maxword): maxword=key print(maxword) --- import jieba f = open("沉默的羔羊.txt") ls = jieba.lcut(f.read()) #ls = f.read().split() d = {} for w in ls: d[w] = d.get(w, 0) + 1 maxc = 0 maxw = "" for k in d: if d[k] > maxc and len(k) > 2: maxc = d[k] maxw = k if d[k] == maxc and len(k) > 2 and k > maxw: maxw = k print(maxw) f.close()
全课程总结
-
课程内容设计
-
第一部分:Python快速入门(2周)
围绕2个具体实例,讲解Python基本语法元素,感性认识
-
第二部分:Python基础语法(5周)
从5个方面讲解基础语法全体系,提供10个实例,理性学习
-
第三部分:Python程序思维(2周)
从方法学角度开阔认识,提升整体编程能力,展望未来
-
面向过程编程的“Python基础语法”全体系
- Python基础语法
- Python计算生态
- Python实例解析
-
-
Python基础语法(全体系)
- 基本数据类型
- 整数、浮点数、复数
- 字符串
- 程序的控制结构
- 分支机构与异常处理
- 遍历循环、无限循环
- 函数和代码复用
- 函数定义和使用
- 函数递归
- 组合数据类型
- 集合类型
- 序列类型:元组和列表
- 字典类型
- 文件和数据格式化
- 文件的使用
- 一二维数据的表示存储和处理
- 基本数据类型
-
Python计算生态(详解7个)
- turtle库:基本图形绘制
- time库:时间的基本处理
- random库:随机数产生及应用
- PyInstaller库:源代码打包为可执行文件
- jieba库:简洁的中文分词
- wordcloud库:中英文词云生成
- os库:操作系统小功能
-
Python计算生态(概览36个)
- 从数据处理到人工智能
- 数据分析
- 数据可视化
- 文本处理
- 机器学习
- 从Web解析到网络空间
- 网络爬虫
- Web信息提取
- Web网站开发
- 网络应用开发
- 从人机交互到艺术设计
- 图形用户界面
- 游戏开发
- 虚拟现实
- 图形艺术
- 从数据处理到人工智能
-
Python实例(16个)
- 实例1:温度转换
- 实例2:Python蟒蛇绘制
- 实例3:天天向上的力量
- 实例4:文本进度条
- 实例5:身体质量指数BMI
- 实例6:圆周率的计算
- 实例7:七段数码管绘制
- 实例8:科赫雪花小包裹
- 实例9:基本统计值计算
- 实例10:文本词频统计
- 实例11:自动轨迹绘制
- 实例12:政府工作报告词云
- 实例13:体育竞技分析
- 实例14:第三方库安装脚本
- 实例15:霍兰德人格分析雷达图
- 实例16:玫瑰花绘制
学习展望
- Python从入门到精通
- Python语法的三个阶段
- Python基础语法-函数式编程(即本课程内容)
- Python进阶语法-面向对象编程
- Python高级语法-Pythonic编程
- Python语法深度(网易云课堂 微专业课程)
- Python基础语法
- Python进阶语法
- Python高级语法
- Python应用深度(爱课程中国大学MOOC,在线开放课堂&微专业课程)
- Python网络爬虫与信息提取
- Python数据分析与展示
- Python机器学习应用
- Python游戏开发入门
- Python云端系统开发入门
- Python科学计算三维可视化
- Python+大数据+人工智能
- Python+嵌入式+可编程硬件
- Python语法的三个阶段
- Python的未来之路在哪里?
- Python Everywhere,Python无处不在
- Python Only Not Enough,只有Python可以但不足够
- Python EcoSystem,Python计算生态将成为编程主流