1、潘理潘理Email:panlisjtu.eduv什么是函数什么是函数v为什么需要函数为什么需要函数v函数和参数函数和参数v带有返回值的函数带有返回值的函数v函数和程序结构函数和程序结构v函数是一种程序构件,是构成大程序的小程序函数是一种程序构件,是构成大程序的小程序.函数定义:将一组完成某个特定功能的语句组合起来,取一函数定义:将一组完成某个特定功能的语句组合起来,取一个名字个名字函数调用:通过函数名执行者组语句函数调用:通过函数名执行者组语句函数的输入称为参数函数的输入称为参数函数的输出称为返回值函数的输出称为返回值v我们已经熟悉的函数我们已经熟悉的函数:自己编的自己编的函数,如常用的函数,
2、如常用的main()Python内建函数,如内建函数,如abs()Python标准库函数,如标准库函数,如math.sqrt()和和string.split()对象的方法,如对象的方法,如win.close()和和p.draw()3v什么是函数什么是函数v为什么需要函数为什么需要函数v函数和参数函数和参数v带有返回值的函数带有返回值的函数v函数和程序结构函数和程序结构v编程更容易把握编程更容易把握复杂程序分解成较小部件复杂程序分解成较小部件v代码可重用代码可重用提高开发效率提高开发效率更易维护更易维护v代码更简洁代码更简洁v程序更易理解程序更易理解5v用函数减少重复代码用函数减少重复代码def
3、 main():print“Happy birthday to you!”print“Happy birthday to you!”print“Happy birthday,dear Fred.”print“Happy birthday to you!”重复代码的坏处重复代码的坏处:1.费时费力费时费力2.代码维护的代码维护的一致性一致性def happy():print happy birthday to you!def singFred():happy()happy()print Happy birthday,dear Fred.happy()def main():singFred()ma
4、in()v什么是函数什么是函数v为什么需要函数为什么需要函数v函数和参数函数和参数v带有返回值的函数带有返回值的函数v函数和程序结构函数和程序结构v如果要为如果要为tom唱一首数据生日歌,必须另外唱一首数据生日歌,必须另外写一个函数写一个函数singTomvsingTom和和singFred的区别在于第三个语句的区别在于第三个语句v将将Tom或或Fred写成一个变量,这两个函数变写成一个变量,这两个函数变成一个函数。成一个函数。v这个变量称为函数的参数,它是函数的输入这个变量称为函数的参数,它是函数的输入。def happy():print happy birthday to youdef s
5、ing(person):happy()happy()print“appy birthday,dear”,person,.happy()print “def main():sing(Fred)sing(Lucy)sing(Elmer)main()v计算利息程序中两处画柱子的代码是类似的计算利息程序中两处画柱子的代码是类似的循环外的初始柱子循环外的初始柱子循环内的每年的柱子循环内的每年的柱子v解决方法:定义一个函数解决方法:定义一个函数def drawBar(win,year,height):bar=Rectangle(Point(year+1,1),Point(year+2,height)bar
6、.setFill(green)bar.draw(win)11def main():win=GraphWin(Investment Growth Chart,512,384)win.setCoords(0.0,0.0,14.0,6.0)Text(Point(0.5,1),0.0K).draw(win)Text(Point(0.5,2),2.5K).draw(win)Text(Point(0.5,3),5.0K).draw(win)Text(Point(0.5,4),7.5K).draw(win)Text(Point(0.5,5),10.0K).draw(win)principal=input(e
7、nter initial principal:)apr=input(enter interest rate:)drawBar(win,0,1+principal*0.0004)for year in range(1,11):principal=principal*(1+apr)drawBar(win,year,1+principal*0.0004)raw_input(press any key to quit:)win.close()main()v函数定义:函数定义:def drawBar(window,year,height)window,year,height成为形式参数,表示函数成为形式
8、参数,表示函数执行时的输入执行时的输入v函数调用:函数调用:drawBar(win,0,1+principal*0.0004)win,0,1+principal*0.0004称为实际参数称为实际参数,代表某次函数函数执行的输入,代表某次函数函数执行的输入v参数传递:将实际参数赋给形式参数参数传递:将实际参数赋给形式参数v函数定义函数定义def():v函数调用函数调用()调用程序暂停调用程序暂停函数形参被赋值为实参函数形参被赋值为实参(按位置对应按位置对应)执行函数体执行函数体控制返回调用点的下一条语句控制返回调用点的下一条语句v什么是函数什么是函数v为什么需要函数为什么需要函数v函数和参数函数
9、和参数v带有返回值的函数带有返回值的函数v函数和程序结构函数和程序结构v函数的返回值:函数执行的结果函数的返回值:函数执行的结果v函数与调用者之间的沟通函数与调用者之间的沟通:通过参数从调用者输入值通过参数从调用者输入值通过返回值向调用者输出值通过返回值向调用者输出值v定义定义def(形参形参):return Python遇见遇见return语句时即退出函数语句时即退出函数,并计算表达式并计算表达式将结果返回给调用者将结果返回给调用者v使用使用x=()v计算计算n!v该函数是一个有参数又有返回值的函数该函数是一个有参数又有返回值的函数。参数是。参数是n,返回值是,返回值是n!#coding=g
10、bkdef p(n):x=1 for i in range(1,n+1):x=x*i return xdef main():n=input(“请输入一个整数:请输入一个整数:)print n,!的值为:的值为:,p(n)main()v什么是函数什么是函数v为什么需要函数为什么需要函数v函数和参数函数和参数v带有返回值的函数带有返回值的函数v函数和程序结构函数和程序结构v函数不只是为了减少重复代码函数不只是为了减少重复代码.v函数还使程序更加模块化函数还使程序更加模块化(modular).即使增加了代码量即使增加了代码量!v编程实例:计算利率编程实例:计算利率将主程序中并未重复出现的语句序列改写
11、成将主程序中并未重复出现的语句序列改写成了一个函数,原地方改成一个函数调用。了一个函数,原地方改成一个函数调用。代码量不减反增,但程序可读性大大增强代码量不减反增,但程序可读性大大增强!def createWin():win=GraphWin(Investment Growth Chart,512,384)win.setCoords(0.0,0.0,14.0,6.0)Text(Point(0.5,1),0.0K).draw(win)Text(Point(0.5,2),2.5K).draw(win)Text(Point(0.5,3),5.0K).draw(win)Text(Point(0.5,4
12、),7.5K).draw(win)Text(Point(0.5,5),10.0K).draw(win)return windef main():win=createWin()principal=input(enter initial principal:)apr=input(enter interest rate:)drawBar(win,0,1+principal*0.0004)for year in range(1,11):principal=principal*(1+apr)drawBar(win,year,1+principal*0.0004)raw_input(press any k
13、ey to quit:)win.close()main()ENDv前面出现的所有程序的执行过程都是从前面出现的所有程序的执行过程都是从第一个语句执行到最后一个语句,这称第一个语句执行到最后一个语句,这称为顺序执行。为顺序执行。v例如求一元二次方程的解例如求一元二次方程的解#equation1.pyimport mathdef main():a,b,c=input(Enter three coefficients:)discRoot=math.sqrt(b*b-4*a*c)r1=(-b+discRoot)/(2*a)r2=(-b-discRoot)/(2*a)print The solution
14、s are:,r1,r2main()当当b*b 4*a*c 0时,时,程序执行出错!程序执行出错!v单分支单分支v多分支多分支v异常处理异常处理v分支语句的基本格式及应用分支语句的基本格式及应用v条件执行条件执行303030v语法语法if:布尔表达式布尔表达式:语句序列语句序列.v语义:计算语义:计算的真假的真假.若为真若为真,则执行则执行,并把控制转向下一条语句;若为假,并把控制转向下一条语句;若为假,则直接把控制转向下一条语句则直接把控制转向下一条语句.3131v简单条件简单条件:关系表达式,比较两个表达式关系表达式,比较两个表达式 关系运算关系运算:,=,!=数值比较数值比较字符串比较字
15、符串比较:按字典序按字典序.v复杂条件:复杂条件:布尔表达式布尔表达式.布尔运算符:布尔运算符:and,or,not布尔表达式布尔表达式:结果为结果为true/false3232vand表示表示“并且并且”:PQP and QFFFFTFTFFTTT3333vor表示表示“或者或者”:v日常用语中的日常用语中的“或或”往往具有互斥的涵义往往具有互斥的涵义,即即二选一二选一.与此处的与此处的or有不同有不同!PQP or QFFFFTTTFTTTT3434vnot表示表示“否定否定”:Pnot PTFFTvnot最高最高,and次之次之,or最低最低思考思考:a or not b and c何意
16、何意?最好使用括号最好使用括号!35if p1.getX()=p2.getX()and p1.getY()=p2.getY():#points are the sameelse:#points are different36import mathdef main():a,b,c=input(input a,b,c:)d=b*b-4*a*c if(d 0):x1=(-b+math.sqrt(d)/2/a x2=(-b-math.sqrt(d)/2/a print x1=,x1,x2=,x2main()v在在 b*b 4*a*c 0时,程序没有任何时,程序没有任何反应反应v改进:在改进:在 b*b
17、 4*a*c 0时,输出一时,输出一个出错信息个出错信息v语法语法if:else:v语义语义若若为真为真,执行执行,控制转,控制转向下一条语句;否则执行向下一条语句;否则执行,控,控制转向下一条语句制转向下一条语句.39import mathdef main():a,b,c=input(input a,b,c:)d=b*b-4*a*c if(d 0):print no root else:x1=(-b+math.sqrt(d)/2/a x2=(-b-math.sqrt(d)/2/a print x1=,x1,x2=,x2main()v当当a等等0时,程序会异常终止。因为遇到时,程序会异常终止。
18、因为遇到了除数为了除数为0的问题的问题v在解一元二次方程时增加一个检测条件在解一元二次方程时增加一个检测条件,检验方程是不是一元二次方程,检验方程是不是一元二次方程#coding=gbkimport mathdef main():a,b,c=input(input a,b,c:)if(abs(a)0.000001):print 不是一元二次方程不是一元二次方程 else:d=b*b-4*a*c if(d 0):print no root else:x1=(-b+math.sqrt(d)/2/a x2=(-b-math.sqrt(d)/2/a print x1=,x1,x2=,x2main()v
19、分支语句的基本格式及应用分支语句的基本格式及应用v条件执行条件执行444444v回顾回顾:Python模块分为模块分为程序程序/脚本脚本:可直接执行可直接执行l模块最后一行是模块最后一行是main(),main(),即启动程序的语句即启动程序的语句l执行方式执行方式直接执行直接执行 WindowsWindows下双击模块图标下双击模块图标 DOSDOS命令行下命令行下:python.py:python.py在会话或其他程序中在会话或其他程序中importimport并执行并执行库库:不能直接执行不能直接执行l模块中没有模块中没有main()main()一行一行l被其他程序被其他程序import
20、import但不执行但不执行454545v混合型模块混合型模块:既能作为独立程序直接执行既能作为独立程序直接执行,又能作为库被其他程序又能作为库被其他程序import而不执行而不执行.#myfile.pydef main():def other():if _name_=_main_:main()import import一个模块时一个模块时,Python,Python将该将该模块中的一个特殊变量模块中的一个特殊变量_name_name_设设置为该模块的名字置为该模块的名字;直接执行模块时直接执行模块时,_name_,_name_被设被设置为置为_main_main_v单分支单分支v多分支多分支
21、v异常处理异常处理v语法语法if:elif:.elif else v语义语义:找到第一个为真的条件并执行对应语:找到第一个为真的条件并执行对应语句序列,句序列,控制转向下一条语句控制转向下一条语句;若无,;若无,则执则执行行else下的语句序列下的语句序列,控制转向下一条语句。,控制转向下一条语句。47v考虑等根的情况考虑等根的情况import mathdef main():a,b,c=input(input a,b,c:)if(abs(a)0.000001):print input illegal else:d=b*b-4*a*c if(d 0):print no root elif(abs
22、(d)0.0000001):x=-b/2/a print x=,x else:x1=(-b+math.sqrt(d)/2/a x2=(-b-math.sqrt(d)/2/a print x1=,x1,x2=,x2main()49v单分支单分支v多分支多分支v异常处理异常处理v为保证程序的正确性,当程序中充斥着为保证程序的正确性,当程序中充斥着许多错误检测代码,使许多错误检测代码,使 解决问题的算法解决问题的算法反而不明显了反而不明显了.v例如求一元二次方程的解,就是利用标例如求一元二次方程的解,就是利用标准的公式。但为了用此公式,必须判断准的公式。但为了用此公式,必须判断a是否为是否为0,是否
23、小于是否小于0。51v异常处理机制:把错误集中在一起处理异常处理机制:把错误集中在一起处理,以免影响算法的主线条。,以免影响算法的主线条。vPython提供提供try.except.v可使程序不因运行错误而崩溃,尽量让可使程序不因运行错误而崩溃,尽量让用户不受意外结果的困扰。用户不受意外结果的困扰。v语法语法try:except:except:.except:.v语义:语义:执行执行。若无错,控制转下一语句;若。若无错,控制转下一语句;若有错,查找匹配该错误的有错,查找匹配该错误的except子句,找到则执行相子句,找到则执行相应的处理程序,找不到则程序崩溃,系统报错。应的处理程序,找不到则程
24、序崩溃,系统报错。53v用异常处理语句来捕获用异常处理语句来捕获math.sqrt的溢出错误的溢出错误try:.except ValueError:.v错误类型错误类型:从系统报错信息中可得从系统报错信息中可得.如如ValueError,TypeError,NameError等等54import mathdef main():a,b,c=input(input a,b,c:)if(abs(a)0.000001):print input illegal else:d=b*b-4*a*c try:x1=(-b+math.sqrt(d)/2/a x2=(-b-math.sqrt(d)/2/a pri
25、nt x1=,x1,x2=,x2 except ValueError:print no rootmain()v将将a等于等于0的判断也作为异常,是程序更的判断也作为异常,是程序更加简洁加简洁import mathdef main():a,b,c=input(input a,b,c:)d=b*b-4*a*c try:x1=(-b+math.sqrt(d)/2/a x2=(-b-math.sqrt(d)/2/a print x1=,x1,x2=,x2 except ValueError:print no root except ZeroDivisionError:print input error
26、main()ENDFor循环回顾循环回顾While循环循环嵌套循环嵌套循环后测试循环和后测试循环和Break语句语句循环的中途退出循环的中途退出606060v语法语法for in:v语义:循环标志变量语义:循环标志变量var取遍序列取遍序列sequence中中的每个值;对的每个值;对var所取的每个值执行一遍循环所取的每个值执行一遍循环体体body。v需求需求:输入若干个数输入若干个数,求平均值求平均值.v显然可用熟悉的累积器算法模式显然可用熟悉的累积器算法模式v算法算法:输入数值个数输入数值个数n初始化累积变量初始化累积变量sum=0循环循环n次次输入数值输入数值x累加到累加到sum输出平均
27、值输出平均值sum/nv翻译到翻译到Python:avg.py61def main():n=input(input a num:)sum=0 for i in range(n):sum=sum+input()print average=,sum/nmain()va-D、b-E、c-F、d-G、e-H s-V 、z-C veg.明文:明文:access control v可变为:可变为:DFFHVV FRQWURO#coding gbkdef main():str_before=raw_input(请输入明文:请输入明文:)str_after=for ch in str_before:if or
28、d(ch)ord(x):str_after=str_after+chr(ord(ch)+3)else:str_after=str_after+chr(ord(ch)-23)print str_aftermain()For循环回顾循环回顾While循环循环嵌套循环嵌套循环后测试循环和后测试循环和Break语句语句循环的中途退出循环的中途退出6666vavg.py的缺点:需要用户输入的缺点:需要用户输入n,不适合事,不适合事先不知道先不知道n的场合的场合v解决方法:每次询问是否还有数据要输入解决方法:每次询问是否还有数据要输入v不确定的条件循环不确定的条件循环:while语法语法while:语义语
29、义:只要条件成立就反复执行循环体只要条件成立就反复执行循环体;当条件当条件不成立则执行下一条语句不成立则执行下一条语句.676767v循环前测试条件循环前测试条件若不满足若不满足,则循环体一次都不执行则循环体一次都不执行v循环体影响下一次条件测试循环体影响下一次条件测试否则导致否则导致无穷循环无穷循环例如:例如:for循环改写成循环改写成while循环循环i=0while i=0:sum=sum+data num=num+1 data=input(input data:)print average=,sum/nummain()vavgavg2都是交互式输入数据的都是交互式输入数据的不便处理大数
30、据量不便处理大数据量.一个输入错误即导致需要重新运行程序一个输入错误即导致需要重新运行程序.v改进改进:建立一个数据文件建立一个数据文件.数据处理应用中广泛使用数据处理应用中广泛使用v模式模式:打开数据文件打开数据文件ffor line in f:处理每个数据处理每个数据v编程实例编程实例:avg3.py72def main():sum=0.0 num=0 infile=open(data.txt,r)for line in infile.readlines():sum=sum+eval(line)num=num+1 print average=,sum/nummain()v在处理前,将整个文
31、件读入内存,导致在处理前,将整个文件读入内存,导致运行速度减慢,甚至无法运行。运行速度减慢,甚至无法运行。v解决方法:分批读入,每次读入一行。解决方法:分批读入,每次读入一行。文件结束时,文件结束时,readline返回一个空串。返回一个空串。def main():sum=0.0 num=0 infile=open(data.txt,r)line=infile.readline()while line!=:sum=sum+eval(line)num=num+1 line=infile.readline()print average=,sum/nummain()For循环回顾循环回顾While循
32、环循环嵌套循环嵌套循环后测试循环和后测试循环和Break语句语句循环的中途退出循环的中途退出v嵌套循环嵌套循环:一个循环语句的循环体内有另一个一个循环语句的循环体内有另一个循环语句循环语句.v用途用途:遍历一维空间的元素只需一个循环变量遍历一维空间的元素只需一个循环变量,遍历二维空间的元素需要两个循环变量遍历二维空间的元素需要两个循环变量,遍历遍历n维空间的元素需要维空间的元素需要n个循环变量个循环变量.v例如例如:假设数据文件包含多段数据,段与段之假设数据文件包含多段数据,段与段之间用空行分开,需要分段统计。间用空行分开,需要分段统计。77def main():sum=0.0 num=0 i
33、nfile=open(data1.txt,r)line=infile.readline()while line!=:while line!=n and line!=:sum=sum+eval(line)num=num+1 line=infile.readline()print average=,sum/num sum=0.0 num=0 line=infile.readline()main()For循环回顾循环回顾While循环循环嵌套循环嵌套循环后测试循环和后测试循环和Break语句语句循环的中途退出循环的中途退出v问题问题:输入验证输入验证检查用户输入是否符合要求检查用户输入是否符合要求,
34、不符合就要求用户重不符合就要求用户重新输入新输入,直至符合为止直至符合为止.v这是一种后测试循环这是一种后测试循环:执行循环体后才测试条件执行循环体后才测试条件循环体至少执行一次循环体至少执行一次直至条件成立才退出循环直至条件成立才退出循环有些语言提供有些语言提供repeatuntil语句语句80vPython没有提供特殊的语句没有提供特殊的语句v可以用可以用while循环实现,只要保证第一次进循环实现,只要保证第一次进入循环时条件为真入循环时条件为真v例如:要求用户输入一个大于例如:要求用户输入一个大于0的数,如果的数,如果不满足要求,则重新输入。可用语句:不满足要求,则重新输入。可用语句:
35、Data=-1While data=0:break比用一个非法值比用一个非法值(如前面的如前面的 1)来强制来强制while循环一次循环一次的做法好的做法好.v慎用慎用break,尤其是一个循环体用多个,尤其是一个循环体用多个break出出口口.For循环回顾循环回顾While循环循环嵌套循环嵌套循环后测试循环和后测试循环和Break语句语句循环的中途退出循环的中途退出v循环出口在循环体中间循环出口在循环体中间.例如例如while 1:x=input(Enter a nonnegative number:)if x=0:break print negative!v用半路循环实现哨兵循环用半路循
36、环实现哨兵循环:while 1:读取下一数据读取下一数据x if x是哨兵是哨兵:break 处理处理xEND878787v计算机有远远高于人类的计算能力,能计算机有远远高于人类的计算能力,能解决人类所不能解决的一些问题。如天解决人类所不能解决的一些问题。如天气预报,设计飞机等气预报,设计飞机等v模拟:用计算机为实际问题建模模拟:用计算机为实际问题建模,从而提从而提供非如此不能获得的信息供非如此不能获得的信息.v我们已经掌握的工具足以让我们编程解我们已经掌握的工具足以让我们编程解决有意思的问题决有意思的问题.v问题问题:为什么球技只比对手略差为什么球技只比对手略差,却输掉绝却输掉绝大多数的比赛
37、大多数的比赛?一种可能是心理上的一种可能是心理上的:你头脑中自以为比对你头脑中自以为比对手只是略差手只是略差,实际情况是你差很多实际情况是你差很多.另一种可能另一种可能:这是壁球运动本身的特性这是壁球运动本身的特性,能力能力上的细微差距却导致压倒性的胜负上的细微差距却导致压倒性的胜负.v解决方法:用计算机模拟壁球,通过模拟不同解决方法:用计算机模拟壁球,通过模拟不同水平球员之间的数千场比赛来看看这是必然的水平球员之间的数千场比赛来看看这是必然的还是偶然的,还是偶然的,888989v球球,球拍球拍,场地场地v一人发球开始比赛一人发球开始比赛v然后两人交替击球然后两人交替击球(称为一个称为一个ra
38、lly)v当一人未能击出合法球当一人未能击出合法球,则输掉本则输掉本rally;发球方输则交换发球权发球方输则交换发球权;发球方赢则得发球方赢则得1分分.v先得先得15分者赢分者赢1局局.v球技水平球技水平:用球员作为发球方的获胜概率用球员作为发球方的获胜概率来模拟来模拟.v程序规格程序规格输入输入:两个球员的水平两个球员的水平,模拟比赛局数模拟比赛局数.输出输出:两球员各自的获胜局数及比例两球员各自的获胜局数及比例.90v模拟的是不确定性事件:模拟的是不确定性事件:rally的输赢是随机的的输赢是随机的.这类模拟也称为这类模拟也称为Monte Carlo算法算法v如何用确定性的计算机模拟非确
39、定性如何用确定性的计算机模拟非确定性?用函数生成随机数用函数生成随机数(实际上是伪随机数实际上是伪随机数).l从种子值开始从种子值开始,计算出一个计算出一个“随机随机”数数;l如果还需要如果还需要,就用上一个随机数反馈给生成函数就用上一个随机数反馈给生成函数,生成下一个生成下一个随机数随机数.Python库库random提供了一些伪随机数生成函数提供了一些伪随机数生成函数:l从加载库的日期时间导出种子值从加载库的日期时间导出种子值.lrandrange():randrange():生成指定范围生成指定范围(类似类似range)range)内的一个整数内的一个整数lrandom():random
40、():生成生成0,1)0,1)间的一个浮点数间的一个浮点数91v设发球人获胜概率是设发球人获胜概率是probv程序中显然需要这样的代码程序中显然需要这样的代码:if 发球者胜了本回合发球者胜了本回合:score=score+1并且要使该条件为真的情况占并且要使该条件为真的情况占probv用用random函数模拟函数模拟:if random()scoreB:winsA=winsA+1else:winsB=winsB+1return winsA,winsBvsimOneGame:整个模拟程序的关键整个模拟程序的关键.是个不确定循环:不断进行回合较量,直至是个不确定循环:不断进行回合较量,直至一局结
41、束一局结束需要两个累积器:记分需要两个累积器:记分需要一个二值累积器:记录发球方需要一个二值累积器:记录发球方得分初始化为得分初始化为0发球方置为发球方置为A当本局未结束就循环当本局未结束就循环:模拟一次发球模拟一次发球修改比赛状态修改比赛状态返回比分返回比分def simOneGame(probA,probB):scoreA=0scoreB=0serving=Awhile not gameOver(scoreA,scoreB):if serving=A:if random()probA:scoreA=scoreA+1else:serving=Belse:if random()probB:sc
42、oreB=scoreB+1else:serving=Areturn scoreA,scoreBv函数函数gameOverdef gameOver(a,b):#a and b represent scores for a racquetball game#RETURNS true if the game is over,false otherwise.return a=15 or b=15v函数函数printSummarydef printSummary(winsA,winsB):#Prints a summary of wins for each player.n=winsA+winsB pr
43、int nGames simulated:,n print Wins for A:%d(%0.1f%)%(winsA,float(winsA)/n*100)print Wins for B:%d(%0.1f%)%(winsB,float(winsB)/n*100)v完整程序完整程序:rball.py运行之运行之,看看技术的小差距是否导致大胜负差看看技术的小差距是否导致大胜负差?试一试试一试:修改成模拟多局制比赛修改成模拟多局制比赛.v自顶向下自顶向下,逐步求精逐步求精将算法表达为一系列较小问题将算法表达为一系列较小问题为每个小问题设计一个为每个小问题设计一个(函数函数)接口接口用各小问题的接口
44、细化算法用各小问题的接口细化算法对各小问题重复此过程对各小问题重复此过程v自顶向下的设计自顶向下的设计v自底向上的实现自底向上的实现从结构图的底层开始实现从结构图的底层开始实现,逐级向上逐级向上.每完成一个模块,进行单元测试每完成一个模块,进行单元测试.v原型技术原型技术(prototyping):从程序的一个简单版本从程序的一个简单版本开始开始,逐步增加功能逐步增加功能,直至完全满足程序规格直至完全满足程序规格.初始的简单版本称为初始的简单版本称为原型(prototype).v原型技术导致螺旋式开发过程原型技术导致螺旋式开发过程:原型的设计原型的设计,实现实现,测试测试新功能的设计新功能的设
45、计,实现实现,测试测试v适合情况适合情况:对程序功能不熟悉对程序功能不熟悉,难以按自顶向下难以按自顶向下设计方法给出完整设计设计方法给出完整设计.vsimOneGame()固定水平五五开固定水平五五开固定比赛固定比赛30个个rallyfrom random import randomdef simOneGame():scoreA=0 scoreB=0 serving=A for i in range(30):if serving=A:if random().5:scoreA=scoreA+1 else:serving=B else:if random()=0.0:更新更新print Dista
46、nce:%0.1f meters.%(xpos)114114114v算法核心部分算法核心部分:更新各值更新各值xpos=xpos+xvel*timeyvel_new=yvel 9.8*timeypos=ypos+time*(yvel+yvel_new)/2yvel=yvel_newv抽象函数,得到的抽象函数,得到的main函数为函数为def main():angle,vel,h0,time=getInput()xpos,ypos=0,h0 xvel,yvel=getXYComponents(vel,angle)while ypos=0.0:xpos,ypos,yvel=updatePos(ti
47、me,xpos,ypos,xvel,yvel)print Distance:%0.1f meters.%(xpos)v过多参数过多参数:5个参数,个参数,3个返回值个返回值.v函数参量过多通常意味着有更好的组织方式函数参量过多通常意味着有更好的组织方式vOO设计:设计一个抛物体类设计:设计一个抛物体类Projectile,让它,让它自己记住当前的位置、速度、以及自己记住当前的位置、速度、以及y方向速度方向速度的变化,使的变化,使main函数不用操心这些细节函数不用操心这些细节def main():angle,vel,h0,time=getInput()cball=Porjectile(angl
48、e,vel,h0)while cball.getY()=0.0:cball.update(time)print Distance:%0.1f meters.%(cball.getX()对象回顾对象回顾类的定义类的定义封装封装编程实例编程实例v语法语法class:方法定义方法定义:同函数定义同函数定义.l方法是依附于类的函数方法是依附于类的函数.一般函数则是独立的一般函数则是独立的.l方法的第一个参量是专用的方法的第一个参量是专用的:指向方法的作用指向方法的作用对象对象.传统上习惯用传统上习惯用selfself这个名字这个名字.回忆回忆:对象是数据和操作的结合对象是数据和操作的结合.l上面的类定
49、义中上面的类定义中,方法对应于操作方法对应于操作.但数据呢但数据呢?117118118118v多面骰子多面骰子#msdie.pyfrom random import randrangeclass MSDie:def _init_(self,s):self.sides=sself.value=1def roll(self):self.value=randrange(1,self.sides+1)def getValue(self):return self.valuedef setValue(self,v):self.value=vvPython的类并不明显定义实例变量的类并不明显定义实例变量,而
50、是在方而是在方法中直接使用法中直接使用.主要是在主要是在_init_方法中方法中(见后见后)l用用self.self.的方式给出的方式给出l如如MSDieMSDie中的中的sidessides和和valuevaluev每个类的实例每个类的实例(对象对象)具有自己的实例变量副本具有自己的实例变量副本,用来存储该对象自己的数据用来存储该对象自己的数据.v对实例变量的访问对实例变量的访问:.v实例变量与函数局部变量不同实例变量与函数局部变量不同!119v方法调用方法调用:同函数调用同函数调用,但需指明作用对象但需指明作用对象.因此不需要再为形参因此不需要再为形参self提供实参了提供实参了.v例如例