函数定义
函数定义:使用def语句
def<name>(<parameters>):
<body>
函数名<name>:可以是任何有效的python标识符;
参数列表<parameterrs>:是调用函数时传递给它的值(可以由多个,一个,或者零个参数组成,当有多个参数时,各个参数用逗号分隔)。
参数可以分为形参和实参:
形式参数:定义函数时,函数名后面圆括号中的变量,简称“形参”。形参只在函数内部有效。
实际参数:调用函数时,函数名后面圆括号中的变量,简称“实参”
自定义函数:用户自己编写的
系统自带函数:python内嵌的函数(如abs()、eval())、python标准库中的函数(如math库中的sqrt())、图形库中的方法(如myPoint.getX())等。
使用函数的目的:降低编程的难度,代码重用;
return语句:结束函数调用,并将结果返回给调用者。
函数接口:返回值和参数。
函数传递信息的主要途径:
通过函数返回值的方式传递信息;
通过参数传递信息;
函数调用
函数调用执行的四个步骤:
调用程序在调用处暂停执行;
函数的形参在调用时备赋值为实参;
执行函数体;
函数被调用结束,给出返回值。、
函数可以使模块程序化:
1 def createTable (pri,apr): 2 #为每一年绘制星号的增长图 3 for year in range(1,11): 4 pri = pri * (1 + apr) 5 print("%2d"%year,end = '') 6 total = caculateNum(pri) 7 print("*" * total) 8 print("0.0k 2.5k 5.0k 7.5k 10.0k") 9 def caculateNum(pri): 10 #计算星号数量 11 total = int(pri*4/1000.0) 12 return total 13 def main(): 14 print("This program plots the growth of a 10-year investment.") 15 #输入本金和利率 16 pri = eval(input("Enter the initial principal:")) 17 apr = eval(input("Enter the annualized interest rate:")) 18 #建立图表 19 createTable(pri,apr) 20 main()
递归
递归:函数定义中使用函数自身的方法。经典例子:阶乘
阶乘的递归定义函数:
1 def fact(n): 2 if n == 0: 3 return 1 4 else: 5 return n*fact(n-1)
运行递归函数fact()计算阶乘:
>>> fact(4) 24 >>> fact(10) 3628800
字符串反转定义函数:
1 def reverse(s): 2 if s == "": 3 return s 4 else: 5 return reverse(s[1:])+s[0]
运行结果:
>>> reverse("Hello!") '!olleH'
Turtle 库回顾:
Turtle中的指令,形象而简单,他绘制的坐标轴以屏幕中心为原点。具体见1.28笔记。
树的绘制算法设计
1 from turtle import Turtle, mainloop 2 3 def tree(plist, l, a, f): 4 """ plist is list of pens 5 l is length of branch 树枝长度 6 a is half of the angle between 2 branches 角度 7 f is factor by which branch is shortened 8 from level to level.""" 9 if l > 5: # 10 lst = [] 11 for p in plist: 12 p.forward(l)#沿着当前的方向画画 13 q = p.clone()#Create and return a clone of the turtle with same position, heading and turtle properties. 14 p.left(a) #Turn turtle left by angle units 15 q.right(a)# turn turtle right by angle units, nits are by default degrees, but can be set via the degrees() and radians() functions. 16 lst.append(p)#将元素增加到列表的最后 17 lst.append(q) 18 tree(lst, l*f, a, f) 19 20 21 22 def main(): 23 p = Turtle() 24 p.color("green") 25 p.pensize(5) #p.setundobuffer(None) 27 p.hideturtle() #Make the turtle invisible. It’s a good idea to do this while you’re in the middle of doing some complex drawing, 28 #because hiding the turtle speeds up the drawing observably. 29 #p.speed(10) 30 #p.getscreen().tracer(1,0)#Return the TurtleScreen object the turtle is drawing on. 31 p.speed(10) 32 #TurtleScreen methods can then be called for that object. 33 p.left(90) # Turn turtle left by angle units. direction 调整画笔 34 35 p.penup() #Pull the pen up – no drawing when moving. 36 p.goto(0,-200)#Move turtle to an absolute position. If the pen is down, draw line. Do not change the turtle’s orientation. 37 p.pendown()# Pull the pen down – drawing when moving. #这三条语句是一个组合相当于先把笔收起来再移动到指定位置,再把笔放下开始画;否则turtle一移动就会自动的把线画出来 38 39 #t = tree([p], 200, 65, 0.6375) 40 t = tree([p], 200, 65, 0.6375) 41 42 main()
组合类型
编码:信息从一种形式转化为另一种形式的过程。
ASCII码、Unicode、UTF-8...
Unicode:
跨语言,跨平台进行文本转换和处理;
对每种语言中字符设定统一且唯一的二进制编码;
每个字符两个字节长;
65536个字符的编码空间;
“严”:Unicode的十六进制数为4E25;
UTF-8编码:
可变长度的Unicode的实现方式;
“严”:十六进制数为E4B8A5;
Unicode与UTF-8编码字节范围对应关系:
GBK编码:
双字节编码
文件:存储在外部介质上的数据或信息的集合。
文本文件:以ASCII码方式存储文件。
打开文件:open()
建立磁盘上的文件与程序中的对象相关联;
通过相关的文件对象获得;
打开模式如下:
<variable> = (<name>,<mode>)
<name>:磁盘文件名;<mode> :打开模式;
文件操作:
文件读取:
read() 返回值为包含整个文件内容的一个字符串;
readline() 返回值为文件下一行内容的字符串;
Readlines() 返回值为整个文件内容的列表,每项是以换行符为结尾的一行字符串。
例:将文件内容输出到屏幕上。
1 def main(): 2 fname = eval(input("Enter filename:")) 3 infile = open(fname,"r") 4 data = infile.read() 5 print(data) 6 main()
例:输出文件前五行内容。
1 infile = open("mood.txt","r") 2 for i in range(5): 3 line = infile.readline() 4 print(line[: -1])
运行结果:
happy
joy
nice
wonderful
pretty
文件内容:
写入文件:从计算机内存向文件写入数据。
write():把含有本文数据或者二进制数据块的字符串写入文件中。
writelines():针对列表操作,接受一个字符串列表作为参数,将它们写入文件。 例:
>>> outfile = open("mood.txt","w") >>> outfile.writelines(["Hello"," ","world"]) >>> outfile.close() >>> infile = open("mood.txt","r") >>> infile.read() 'Hello world'
文件遍历
关闭文件:
file.close()
字典:
字典是针对非序列集合而提供的一种数据类型;
映射:通过任意键值查找集合中值信息的过程;
字典是键值对的集合:
该集合以键为索引;
同一个键信息对应一个值;
字典类型与序列类型的区别:
- 存取和访问的方式不同
- 键的类型不同:
序列类型只能用数字类型的键;
字典类型可以用其他对象类型作键;
- 排列方式不同:
序列保持了元素的相对关系;
而字典中的数据是无序排列的
- 映射方式不同:
序列类型通过地址映射到值;
字典类型通过键直接映射到值;
字典的操作:
为字典增加一项 : dictionaryName[key] = value
访问字典中的值 :dictionaryName[key]返回键key对应的值value
删除字典中的一项:del dictionaryName[key]
字典的遍历:
遍历字典的键key:
for key in dictionaryName.keys():print.(key)
遍历字典的值value:
for value in dictionaryName.values():print.(value)
遍历字典中的项:
for item in dictionaryName.items():print.(item)
遍历字典的key-value:
for item,value in adict.items():print(item,value)
是否一个键在字典中:in 或者 not in
字典的标准操作符:-,<,>,<=,>=,==,!=,and,or,not
“统计词频”问题解决步骤:
输入英文文章;
建立用于词频计算的空字典;
对文本的每一行计算词频;
从字典中获取数据对到列表中;
对列表中的数据对交换位置,并从大到小进行排序
输出结果
最后用Turtle库绘制统计词频结果图表
计算思维的本质:
抽象、自动化
实证思维、逻辑思维、计算思维
随机算计科学发展而提出
理解计算特性
将计算特性抽象为计算问题
程序设计实现问题的在自动求解
自顶而下的设计过程总结:
步骤1:将算法表达为一系列小问题;
步骤2:为每个小问题涉及接口;
步骤3:通过将算法表达为接口关联的多个小问题来细化算法;
步骤4:为每个小问题重复上述过程。
自底向上的执行
体育竞技分析的例子(已知两个运动员单次比赛获得胜利的概率,求在规定的比赛次数中两人分别获得最终胜利的概率)
1 from random import * 2 3 def main(): 4 printIntro() 5 probA,probB,n = getInputs() 6 winsA, winsB = simNGames(n,probA,probB) 7 PrintSummary(winsA, winsB) 8 9 def printIntro(): 10 print('This program simulates a game between two') 11 print('There are two players, A and B') 12 print('Probability(a number between 0 and 1)is used') 13 14 def getInputs(): 15 a = eval(input('What is the prob.player A wins?')) 16 b = eval(input('What is the prob.player B wins?')) 17 n = eval(input('How many games to simulate?')) 18 return a,b,n 19 20 def simNGames(n,probA,probB): 21 winsA = 0 22 winsB = 0 23 for i in range(n): 24 scoreA,scoreB = simOneGame(probA,probB) 25 if scoreA >scoreB: 26 winsA = winsA + 1 27 else: 28 winsB = winsB + 1 29 return winsA,winsB 30 def simOneGame(probA,probB): 31 scoreA = 0 32 scoreB = 0 33 serving = "A" 34 while not gameOver(scoreA,scoreB): 35 if serving == "A": 36 if random() < probA: 37 scoreA = scoreA + 1 38 else: 39 serving = "B" 40 else: 41 if random() < probB: 42 scoreB = scoreB + 1 43 else: 44 serving = "A" 45 return scoreA,scoreB 46 47 def gameOver(a,b): 48 return a==15 or b==15 49 50 def PrintSummary(winsA, winsB): 51 n = winsA + winsB 52 print(' Games simulated:%d'%n) 53 print('Wins for A:{0}({1:0.1%})'.format(winsA,winsA/n)) 54 print('Wins for B:{0}({1:0.1%})'.format(winsB,winsB/n)) 55 56 if __name__ == '__main__': 57 main()
软件开发方法:
软件工程
软件开发生命周期:
确定问题、可行性分析、系统分析、系统设计、编码、测试、安装维护
软件开发模式:
瀑布模式(重视各个阶段的顺序性)、螺旋模式(设计、执行并测试原型,再设计、执行并测试新特征,将原型逐步扩展为最终程序)、快速原型模式、喷泉模式、混合模式、敏捷开发模式
原型的例子:
import random def simOneGame(): scoreA = 0 scoreB = 0 serving = "A" for i in range(30): if serving == "A": if random.random() < 0.5: scoreA = scoreA + 1 else: serving = "B" else: if random.random() < 0.5: scoreB = scoreB + 1 else: serving = "A" print(scoreA) print(scoreB) simOneGame()
阶段1:构建最初的原型;
阶段2:添加两个参数代表两个球员赢球的概率;
阶段3:进行比赛,直到一个球员达到15分;
阶段4:将比赛扩展为多场比赛;
阶段5:建立完整的程序;
敏捷开发方法:
以人为核心、迭代、循序渐进;
针对传统的瀑布开发模式的弊端;
分为多个相互联系,独立运行的小项目;
软件一直处于可使用状态。
敏捷开发典型过程:
- 对产品形成共识;
- 建立和维护产品需求列表,并进行优先级排序;
- 筛选高优先级需求进入本轮迭代开发;
- 细化本轮迭代需求,一次在本轮迭代完成;
- 每日召开站立会议。(任务看板)
- 对每轮迭代交付的可工作软件,进行现场验收和反馈;
- 从第3步开始,进行下一轮迭代。
面向过程的程序设计:
以程序执行过程为设计流程的思想,结构化编程;
例:输入铅球的初始角度、高度、速度和飞行时间,求铅球的飞行距离(为简化问题忽略空气阻力,重力加速度为9.8米每二次方秒)。
1 from math import pi,sin,cos,radians 2 3 def main(): 4 angle = eval(input("Enter the launch angle (in degrees):")) 5 vel = eval(input("Enter the initial velocity (in meters/sec):")) 6 h0 = eval(input("Enter the initial height (in meters):")) 7 time = eval(input("Enter the time interval: ")) 8 9 xpos = 0 10 ypos = h0 11 12 theta = radians(angle) #将角度转换为弧度制 13 xvel = vel * cos(theta) 14 yvel = vel * sin(theta) 15 16 while ypos >= 0: 17 xpos = xpos + time * xvel 18 yvell = yvel - time * 9.8 19 ypos = ypos + time * (yvel + yvell)/2.0 20 yvel = yvell 21 print(" Distance traveled:{0:0.1f}meters.".format(xpos)) 22 23 if __name__ == "__main__": 24 main()
面向过程程序设计基本步骤:
分析程序从输入到输出的各步骤;
按照执行过程从前到后编写程序;
将高耦合部分封装成模块或函数;
输入参数,按照程序执行过程调试;
面向对象的程序设计:
类:某种类型集合的描述,包含属性和方法。
类的定义:
class classname[(父类名)]:[成员函数及成员变量]
_init_构造函数:初始化对象的各属性;
_del_析构函数:销毁对象。
面向对象实例(铅球飞行距离):
定义类:
1 from math import sin, cos, radians 2 3 class Projectile: 4 def __init__(self, angle, velocity, height): 5 #根据给定的发射角度、初始速度和位置创建一个投射体对象 6 self.xpos = 0.0 7 self.ypos = height 8 theta = radians(angle) 9 self.xvel = velocity * cos(theta) 10 self.yvel = velocity * sin(theta) 11 12 def update(self, time): 13 #更新投射体的状态 14 self.xpos = self.xpos + time * self.xvel 15 yvell = self.yvel - 9.8 * time 16 self.ypos = self.ypos + time * (self.yvel + yvell) / 2.0 17 self.yvel = yvell 18 19 def getY(self): 20 #返回投射体的角度 21 return self.ypos 22 23 def getX(self): 24 #返回投射体的距离 25 return self.xpos
调用类模块的主函数:
1 from Projectile import * 2 3 def getInputs(): 4 a = eval(input("Enter the launch angle (in degrees):")) 5 v = eval(input("Enter the initial velocity (in meters/sec):")) 6 h = eval(input("Enter the initial height (in meters):")) 7 t = eval(input("Enter the time interval: ")) 8 return a,v,h,t 9 10 def main(): 11 angle,vel,h0,time = getInputs() 12 shot = Projectile(angle,vel,h0) 13 while shot.getY() >=0: 14 shot.update(time) 15 print(" Distance traveled:{0:0.1f}meters.".format(shot.getX())) 16 17 if __name__ == "__main__": 18 main()
面型对象的特点:
封装、多态、继承