Python程序设计 课件汇 苏琳 第7-12章 循环结构和布尔值 - Python库及计算生态_第1页
Python程序设计 课件汇 苏琳 第7-12章 循环结构和布尔值 - Python库及计算生态_第2页
Python程序设计 课件汇 苏琳 第7-12章 循环结构和布尔值 - Python库及计算生态_第3页
Python程序设计 课件汇 苏琳 第7-12章 循环结构和布尔值 - Python库及计算生态_第4页
Python程序设计 课件汇 苏琳 第7-12章 循环结构和布尔值 - Python库及计算生态_第5页
已阅读5页,还剩467页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

循环结构和布尔值第七章课程目标课程目标2理解交互式循环和哨兵循环的编程模式,以及它们用Python的while语句的实现1理解确定和不定循环的概念,以及它们用Python的for和while语句的实现3理解文件结束循环的编程模式,以及在Python中实现这种循环的方法4能为涉及循环模式(包括嵌套循环结构)的问题设计和实现解决方案5理解布尔代数的基本思想,并能分析和编写涉及布尔运算符的布尔表达式PART1for循环:快速回顾1for循环:快速回顾for循环语句允许我们访问一系列值,它的基本形式:for<var>in<sequence>:<body>依次取序列中的每个值,循环体中的语句针对每个值执行一次。主要用于遍历,但是不能实现下标访问1for循环:快速回顾阿基米德与国王下棋,国王输了,国王问阿基米德要什么奖赏?阿基米德对国王说:“只要在棋盘上第一个放一粒米,第二格放二粒,第三格放四粒,第四格放十六粒……按这个方法放满整个棋盘就行。”国王以为要不了多少粮食,就随口答应了,结果国王输了。国际象棋一共有64格,现在请大家来算算一共要多少粒米。1for循环:快速回顾importmathdefmain():all_sum=0n=int(input("输入整数:"))

foriinrange(1,n+1):all_sum=all_sum+pow(2,i-1)print(all_sum)

main()1for循环:快速回顾输入整数:64184467440737095516151公斤大米约4万粒,所以是46万亿公斤大米。中国一年的大米产量约13277亿斤1for循环:快速回顾了解计数循环设计和实现能工作的程序了解累积器PART2不定循环2不定循环for循环是一个有限循环,这意味着循环开始时确定迭代次数。方法:用另一种循环,即“不定循环”或“条件循环”。一个独立的循环保持迭代,直到满足某些条件。2不定循环在Python中,用while语句实现了一个不定循环。while<condition>:<body>是一个布尔表达式。是一个或多个语句的序列。2不定循环图7.1

while循环的流程图“先测试”循环2不定循环i=0

whilei<=10:

print(i)

i=i+1while要求在循环之前负责初始化i,并在循环体的底部让i增加。在for循环中,循环变量是自动处理的。PART3交互式循环3交互式循环交互式循环:允许用户根据需要重复程序的某些部分。例:以数字求平均值。为了允许用户在任何时间停止,循环的每次迭代将询问是否有更多的数据要处理。3交互式循环defmain():total=0.0count=0moredata="yes"whilemoredata[0]=="y":x=float(input("输入一个数>>"))

total=total+xcount=count+1moredata=input("是否还要继续输入(y/n)?")print("\n平均值为:",total/count)main()将交互式循环模式和累加器结合得到求平均值的算法。3交互式循环输入一个数>>5是否还要继续输入(y/n)?y输入一个数>>6是否还要继续输入(y/n)?y输入一个数>>7是否还要继续输入(y/n)?n

平均值为:6.0PART4哨兵循环(改进)4哨兵循环哨兵循环不断处理数据,直到达到一个特殊值,表明迭代结束。特殊值称为“哨兵”。可以选择任何值作为哨兵。唯一的限制是能与实际数据值区分开来。哨兵不作为数据的一部分进行处理。4哨兵循环获取第一个数据项当该数据不是哨兵时处理数据获取下一个数据项有时被称为“启动读入”4哨兵循环设计一个可以计算任何实数平均值的算法。选择一个与正实数和负实数都不同的“哨兵”当输入不是“哨兵”时,可以一直进行数据的输入当输入“哨兵”时,程序则退出输入并计算平均值4哨兵循环初始化total为0.0初始化count为0输入数据为字符串,xStrwhilexStr不为空将xStr转换为浮点型,x将x与total相加count加1输入下一个字符串数据,xStr输出total/count4哨兵循环defmain():total=0.0count=0xStr=input("输入一个数字(<Enter>退出)>>")

whilexStr!="":#“”空字符串这个就是哨兵x=float(xStr)total=total+xcount=count+1xStr=input("输入一个数字(<Enter>退出)>>")

print("\n平均值为:",total/count)main()4哨兵循环输入一个数字(<Enter>退出)>>5输入一个数字(<Enter>退出)>>6输入一个数字(<Enter>退出)>>7输入一个数字(<Enter>退出)>>4输入一个数字(<Enter>退出)>>3输入一个数字(<Enter>退出)>>

平均值为:5.0PART5文件循环(进一步优化)5文件循环所有平均值程序都有一个缺点:它们是互动的,不能返回修改数据。如果你正在尝试求87个数字的平均值,而恰巧在接近尾声时发生了打字错误。用我们的互动程序,你只能重新开始。将所有数字输入到文件中。5文件循环defmain():fileName=input("选择文件")infile=open(fileName,’r’)total=0.0count=0forlineininfile:total=total+float(line)count=count+1print("\n平均值为:",total/count)main()将文件作为行序列,遍历该文件。使用文件对象作为for循环中的序列,可以查看文件中的数据。将这种技术直接应用于数字平均值问题。假设数字被输入一个文件,每行一个,可以用下列程序计算平均值。5文件循环line=infile.readline()whileline!="":#processlineline=infile.readline()下面是Python中使用readline()的“文件结束循环”的一般模式。5文件循环文本文件中的空白行包含单个换行符("\n"),而且readline方法在其返回值中包含换行符。由于"\n"!="",所以循环将继续。我担心如果文件中遇到空行,该循环会过早停止。如:1234565文件循环defmain():fileName=input("输入文件名:")

infile=open(fileName,'r')total=0.0count=0line=infile.readline()whileline!="":ifline!="\n":total=total+float(line)count=count+1line=infile.readline()print("\n平均值为:",total/count)main()PART6嵌套循环(提高)6嵌套循环以求平均值为例子。假设文件不是每行一个数,而是每行有多个数,每个数之间以逗号隔开。如:1,2,3,4,57,8,9,116,5,4,5在顶层,基本算法将是某种文件处理循环,计算不断增长的总和与计数。在实践中,我们使用文件结束循环。6嵌套循环外部循环total=0.0count=0line=infile.readline()whileline!="":#updatetotalandcountforvaluesinlineline=infile.readline()print("\nTheaverageofthenumbersis",total/count)6嵌套循环1由于文件中每个单独的行包含一个或多个由逗号分隔的数字,所以我们可以将该行分割成子字符串,每个代表一个数字。2我们需要循环遍历这些子字符串,将每个子字符串转换成一个数字,并将它加到total中。3对每个数字,我们还需要让count加1。6嵌套循环内部循环forxStrinline.split(","):total=total+float(xStr)count=count+1迭代由line的值控制。366嵌套循环defmain():fileName=input("输入文件名:")

infile=open(fileName,'r')total=0.0count=0line=infile.readline()whileline!="":#更新total和count的值

forxStrinline.split(","):total=total+float(xStr)count=count+1line=infile.readline()print("\n平均值为:",total/count)main()对文件的每一行进行一次迭代。迭代的次数等于该行中数字的次数。6嵌套循环01设计嵌套循环02先设计外层,不考虑内层的内容03设计内层的内容,忽略外层循环放在一起,注意保留嵌套PART7布尔值计算第二课时7布尔值计算我们现在有两种控制结构(if和while)使用条件,即布尔表达式。在概念上,布尔表达式求值为假或真两个值之一。在Python中,这些值由字面量False和True表示。到目前为止,我们使用简单的布尔表达式来比较两个值(如x>=0)。PART8布尔运算符8布尔运算符<expr>and<expr><expr>or<expr>有时,我们使用的简单条件似乎不足以表达。那我们就可以使用“布尔运算”来构造更复杂的表达式。与(and)或(or)非(not)布尔运算符8布尔运算符表7-1

and的真值表P表达式1,Q表达式2PQPandQTTTTFFFTFFFF8布尔运算符表7-2

or的真值表pqPorQTTTTFTFTTFFF8布尔运算符表7-3

not的真值表PnotPTFFT8布尔运算符Python遵循一个标准惯例:与(and)或(or)非(not)高低当在一个运算表达式中有多个布尔表达式,那么应该先计算那个呢?8布尔运算符ifp1.getX()==p2.getX()andp2.getY()==p1.getY():print("两点在同一位置")else:print("两点不在同一位置")用布尔表达式测试两点是否在同一位置。PART9布尔代数9布尔代数计算机程序中的所有判断都归结为适当的布尔表达式。布尔表达式遵循一些代数定律,类似于适用于数字运算的定律。这些定律称为“布尔逻辑”或“布尔代数”。我能用布尔表达式来表达、操作和推理。and与乘法有相似之处,or与加法相似,0和1对应于假和真。9布尔代数代数布尔代数a*0=0aandfalse==falsea*1=aaandtrue==aa+0=aaorfalse==a表7-4

一些代数规则和布尔代数中相关的规则9布尔代数and和or满足分配律:下面两个恒等式称为DeMorgan定律:(aor(bandc))==((aorb)and(aorc))(aand(borc))==((aandb)or(aandc))(not(aorb))==((nota)and(notb))(not(aandb))==((nota)or(notb))9布尔代数表7-5

DeMorgan第一定律abaorbnot(aorb)notanotb(nota)and(notb)TTTFFFFTFTFFTFFTTFTFFFFFTTTT布尔代数有一个不错的特性:这种简单的恒等式很容易用真值表验证。PART10其他常见结构10其他常见结构判断结构(if)以及先测试循环(while)提供了一套完整的控制结构。对于某些类型的问题,替代结构有时会比较方便。PART11后测试循环11后测试循环假设你正在编写一个输入算法,该算法需要从用户那里获取一个非负数。如果用户键入错误的输入,程序会要求另一个值。它不断重新提示,直到用户输入一个有效值。这个过程称为输入验证。11后测试循环repeatgetanumberfromtheuseruntilnumberis>=011后测试循环图7.2测试后循环的流程图11后测试循环number=-1whilenumber<0: number=float(input("输入正数:"))Python没有直接实现后测试循环的语句。但是,该算法可以用while来实现,只要预设第一次迭代的循环条件。这迫使循环体至少执行一次,并且等价于后测试算法。11后测试循环whileTrue: number=float(input("输入正数:")) ifnumber>=0:break也可以使用Python的break语句来直接模拟后测试循环。执行break会导致Python立即退出围绕它的循环。通常用break语句来跳出语法上像是无限的循环。PART12循环加一半12循环加一半whileTrue:

number=float(input("Enterapositivenumber:"))

ifx>=0:break#Loopexit

print("Thenumberyouenteredwasnotpositive")这里的循环出口实际上位于循环体的中间,这称为“循环加一半”。12循环加一半whileTrue:获取下一个数据项如果该数据为哨兵:break处理数据“循环加一半”是避免在哨兵循环中启动读取的一种很好的方式。12循环加一半这个实现忠实于哨兵循环的第一规则——避免处理哨兵值。图7.3哨兵循环的流程图12循环加一半#8_6new_sentry.pydefmain():total=0.0count=0whileTrue:#哨兵为""空字符串xStr=input("输入一个数字(<Enter>退出)>>")ifxStr=="":breakx=float(xStr)total=total+xcount=count+1print("\n平均值为:",total/count)main()PART13布尔表达式作为判断13布尔表达式作为判断有时布尔表达式本身也可以作为控制结构。整数1整数0真假事实上,bool类型只是一个“特殊”的int类型,其中0和1的值打印为False和True。13布尔表达式作为判断True和False分别表示布尔值真和假。Python条件运算符总是求值为bool类型的值。任何内置类型都可以解释为布尔值。对于数字(int和floats),零值被认为是假,除零之外的任何值都被认为是真。13布尔表达式作为判断>>>bool(1)True>>>bool(-1)True>>>bool(0)False>>>bool("abc")True>>>bool("")False>>>bool([1,2,3])True>>>bool([])False13布尔表达式作为判断对于序列类型,空序列被解释为假,而任何非空序列被用来表示真。Python布尔值的灵活性扩展到布尔运算符。操作符操作定义xandy如果x为假,返回x,否则返回yxory如果x为真,返回x,否则返回ynotx如果x为假,返回真,否则返回假表7-6

布尔运算符的行为13布尔表达式作为判断whileresponse[0]=="y"or"Y":while(response[0]=="y")or("Y"):如果我们输入下面这样一句代码会发生什么呢?我们可以将其写为aorb的形式:PART14示例:一个简单的事件循环14示例:一个简单的事件循环包含图形用户界面(GUI)的现代程序通常以事件驱动的方式编写。程序显示图形界面,然后“等待”用户事件,诸如单击菜单或按键盘上的一个键。该程序通过处理该事件做出响应。在背后,驱动这种风格的程序的机制是所谓的“事件循环”。14示例:一个简单的事件循环绘制GUIwhileTrue:获取下一个事件if事件是"退出信号":break处理事件清理并退出14示例:一个简单的事件循环例:打开图形窗口,允许用户通过键入不同的键来改变其背景颜色,如R为红色、G为灰色等。用户可以随时通过按下Q键退出。14示例:一个简单的事件循环fromgraphicsimport*defmain():win=GraphWin("颜色窗口",500,500)

whileTrue:key=win.getKey()ifkey=="q"orkey=="Q":break#根据不同按键进行处理

ifkey=="r"orkey=="R":win.setBackground("pink")elifkey=="w"orkey=="W":win.setBackground("white")elifkey=="g"orkey=="G":win.setBackground("lightgray")elifkey=="b"orkey=="B":win.setBackground("lightblue")win.close()main()强制用户按一个键继续14示例:一个简单的事件循环更灵活的用户界面可能允许用户以各种方式进行交互。课程目标小结希望大家能够为涉及循环模式(包括嵌套循环结构)的问题设计和实现解决方案、理解布尔代数的基本思想,并能分析和编写涉及布尔运算符的布尔表达式。课程目标实践任务1.假设我们要编写一个程序,计算用户输入的一系列数字的平均值。为了让程序通用,它应该适用于任意大小的数字。你知道平均值是通过对数字求和并除以数字的个数来计算的。我们不需要记录所有输入的数字,只需要一个不断增长的总和,以便最后计算平均值。课程目标实践任务2.数字平均值问题有一个更好的解决方案,即采用一种名为“哨兵循环”的模式。哨兵循环不断处理数据,直到达到一个特殊值,表明迭代结束。我们可以将哨兵模式应用于数字平均值问题。第一步是选择哨兵。假设我们正在使用该程序来计算考试成绩的平均值。在这种情况下,我们可以放心地假设没有得分低于0。用户可以输入负数来表示数据结束。课程目标实践任务3.作为一个简单的例子,请考虑一个程序,它只是打开图形窗口,允许用户通过键入不同的键来改变其颜色,如R为红色、G为灰色等。用户可以随时通过按下Q键退出。我们可以将它编码为一个简单的事件循环,用getKey()来处理按键。课程目标课后习题选择题1.在循环体中可以执行_______语句让它终止。a.if b.inputc.break d.Exit

2.循环直到输入特殊值的循环模式称为_______。a.交互式循环 b.文件结束循环c.哨兵循环 d.无限循环

3.在执行循环体后测试循环条件的循环结构称为_______。a.先测试循环 b.循环加一半.c.哨兵循环 d.后测试循环

4.以下_______项不是布尔代数的有效规则。a.(Trueorx)==Trueb.(Falseandx)==Falsec.not(aandb)==not(a)andnot(b)d.(TrueorFalse)==True

5.没有终止的循环称为_______。a.忙循环 b.不定循环c.紧循环 d.无限循环课程目标课后习题判断题1.Python的while实现了一个有限循环。

2.在Python中迭代文件行的最简单方法是用while循环。

3.如果两个运算数都为真,则布尔运算符or返回True。

4.aand(borc)==(aandb)or(aandc)

5.not(aorb)==(nota)ornot(b) 课程目标课后习题简答题1.输入n的值,求出n的阶乘。2.求和求s=a+aa+aaa+…+aa…a的值(最后一个数中a的个数为n),其中a是一个1~9的数字,例如:2+22+222+2222+22222(此时a=2n=5)3.我国现有13亿人口,设每年增长0.8%,编写程序,计算多少年后达到26亿?4.在屏幕上输出小九九乘法表(三角形式)。5.求1!+2!+3!+4!+5!的和。THANKSFORYOURATTENTION谢谢聆听Python程序设计集合和字典第八章课程目标课程目标1掌握集合和字典的创建方法32熟悉集合和字典的操作方法会使用集合和字典在相关应用程序中解决问题PART1集合1集合集合是一个无序且无重复元素的序列。集合中的所有元素包含在一对大括号{}中,各元素之间用逗号“,”分隔。由于集合中的元素是无序的,因此集合输出时顺序不唯一。1集合一、集合的创建1.直接创建可以将一组用逗号分隔的元素使用大括号{}括起来,然后赋值给集合变量。

>>>mySet

={1,2,3,'45','张三'}>>>print(mySet){1,2,3,'45','张三'}1集合2.用内置set()函数创建创建空集合可以使用set()函数。>>>mySet1=set()>>>print(mySet1)Set()>>>mySet2={1,2,3,'45','张三'}>>>print(mySet2){1,2,3,'45','张三'}1集合二、集合的基本操作1.添加元素语法格式如下:s.add(x)将元素x添加到集合s中,如果元素已存在,则不进行任何操作。>>>thisset=set(("Google","Runoob","Taobao"))>>>thisset.add("Facebook")>>>print(thisset){'Taobao','Facebook','Google','Runoob'}1集合>>>thisset=set(("Google","Runoob","Taobao"))>>>thisset.update({1,3})>>>print(thisset){1,3,'Google','Taobao','Runoob'}>>>thisset.update([1,4],[5,6])

>>>print(thisset){1,3,4,5,6,'Google','Taobao','Runoob'}>>>还有一个方法,也可以添加元素,且参数可以是列表,元组,字典等,语法格式如下:s.update(x)x可以有多个,用逗号分开。1集合2.移除元素语法格式如下:s.remove(x)将元素x从集合s中移除,如果元素不存在,则会发生错误。>>>thisset=set(("Google","Runoob","Taobao"))>>>thisset.remove("Taobao")>>>print(thisset){'Google','Runoob'}>>>thisset.remove("Facebook")

#不存在会发生错误Traceback(mostrecentcalllast):

File"<stdin>",line1,in<module>KeyError:'Facebook'>>>1集合3.计算集合元素的个数语法格式如下:len(s)计算集合s中元素的个数。>>>thisset=set(("Google","Runoob","Taobao"))>>>len(thisset)31集合4.清空集合语法格式如下:s.clear()清空集合s。>>>thisset=set(("Google","Runoob","Taobao"))>>>thisset.clear()>>>print(thisset)set()1集合5.判断元素是否在集合中存在语法格式如下:xins判断元素x是否在集合s中,存在返回True,不存在返回False。>>>thisset=set(("Google","Runoob","Taobao"))>>>"Runoob"inthissetTrue>>>"Facebook"inthissetFalse>>>1集合三、集合的常用内置操作方法方法含义<set>.add()为集合添加元素<set>.clear()移除集合中的所有元素<set>.copy()拷贝一个集合<set>.difference()返回多个集合的差集<set>.difference_update()移除集合中的元素,该元素在指定的集合也存在。<set>.discard()删除集合中指定的元素PART2字典2字典允许查找与任意键相关联的信息的集合称为映射。Python的字典是映射。在Python中创建一个字典是通过在大括号内列出键值对来实现的。下面是一个简单的字典:>>>dict={'a':1,'b':2,'c':3}请注意,键和值用“:”连接,逗号用于分隔每个键值对。字典的主要用途是查找与特定键相关的值。这是通过索引符号来完成的。2字典一、字典的创建可以在花括号中明确列出键值对,从而定义字典,还可以通过添加新条目来扩展字典。延续上面的示例:>>>dict['d']=5>>>dict{'a':4,'b':2,'c':3,'d':5}2字典方法含义<key>in<dict>如果字典包含指定的键就返回真,否则返回假<dict>.keys()返回键的序列<dict>.values()返回值的序列<dict>.items()返回一个元组(key,value)的序列,表示键值对<dict>.get(<key>,<default>)如果字典包含键key就返回它的值,否则返回defaultdel<dict>[<key>]删除指定的条目<dict>.clear()删除所有条目for<var>in<dict>:循环遍历所有键二、Python字典的操作方法及其含义课程目标小结希望大家能够熟悉集合和字典的基本操作,理解和编写处理文本信息的程序。课程目标实践任务编写程序实现如下功能:用户输入国家名称,输出该国家名称和首都。(提示:为了完成这个程序,需要首先创建国家名称和首都的映射关系)课程目标课后习题操作题已知字典d={'数学':101,'语文':202,'英语':203,'物理':204,'生物':206}(1)分别输出字典d中所有的“键”(key)、“值”(value)的信息。代码:

>>>(2)将字典d中所有的“键”(key)、“值”(value)的信息分别以列表形式输出。代码:

>>>(3)输出字典d中“物理”的值。代码:

>>>(4)修改字典d中“数学”对应的值为201。代码:

>>>(5)向字典d中添加键值对“'化学':205”。代码:

>>>(6)用两种方法删除字典d中的“生物”对应的键对值。代码:

>>>(7)随机删除字典d中的一个“键值对”。代码:

>>>(8)清空字典d。代码:

>>>THANKSFORYOURATTENTION谢谢聆听Python程序设计模拟与设计第九章课程目标课程目标1理解模拟的应用可能是解决现实问题的一种方式324理解伪随机数及其在蒙特卡罗模拟中的应用理解并能应用自顶向下和螺旋式设计技术来编写复杂的程序理解单元测试,并能将这种技术应用于复杂程序的实现和调试PART1模拟短柄壁球1模拟短柄壁球解决现实问题的一个特别强大的技术就是“模拟”。开发一个短柄壁球比赛的简单模拟。PART2一个模拟问题2一个模拟问题Denny酷爱打短柄壁球,但是这几年来,他经常与那些比他好一点点的球员竞争,期间他大多数是被击败的,这让他很困扰。他觉得如果别人只是比他好一点点他应该不会输这么多。或许是他对自己的实力评价过高,又或许是对别人的实力评价过低。又或者是游戏本身的性质,能力上的小差异会导致球场上的不平衡比赛。编一个计算机程序来模拟短柄壁球的某些方面。PART3分析和规格说明3分析和规格说明短柄壁球是在两名球员之间使用球拍在四壁球场上打球的运动。3分析和规格说明比赛开始时,一名选手将球击出:这被称为“发球”选手交替击球,使其保持比赛状态,这是一个“回合”当其中一名选手未能有效击球时,对打结束输家是发球选手,则发球权转给另一名选手发球选手赢得了这一回合,则会得1分选手只能在自己发球时得分,第一名得到15分的选手赢得比赛。击球失误的选手输掉这一回合3分析和规格说明在模拟中,选手的能力水平将由选手在发球时赢得回合的概率来表示。程序将打印结果摘要将提示用户输入两名选手的发球回合得分概率用这些概率模拟多局短柄壁球比赛3分析和规格说明输入:该程序先提示并获取两名选手(称为“选手A”和“选手B”)的发球回合得分概率。然后程序提示并获取要模拟的比赛局数。输出:该程序将提供一系列的初始提示,如:A赢得比赛的概率是多少?B赢得比赛的概率是多少?一共模拟多少场比赛?3分析和规格说明游戏模拟:500A赢:268(53.6%)B赢:232(46.4%)注意:所有输入都被假定为合法的数值,不需要错误或有效性检查。在每次模拟比赛中,都是选手A先发球。PART4伪随机数4伪随机数伪随机数发生器从某个“种子”值开始工作。该值被送入一个函数以产生“随机”数字。下次需要一个随机数时,将当前值反馈到该函数中以产生一个新的数字。通过仔细选择的函数,得到的值序列基本上是随机的。一切都取决于生成函数和种子的值。4伪随机数Python提供了一个库模块,其中包含一些有用的函数来生成伪随机数。该模块中的函数根据模块加载的日期和时间推导出初始种子值,因此每次运行程序时都会获得不同的种子值。randrangerandom

重要函数4伪随机数>fromrandomimport*>>>randrange(1,6)2>>>randrange(1,6)1>>>randrange(1,6)1>>>randrange(5,105,5)20>>>randrange(5,105,5)70>>>randrange(5,105,5)70>>>randrange(5,105,5)75从给定范围中选择一个伪随机整数4伪随机数>>>fromrandomimport*>>>random()0.7635543105304049>>>random()0.31164370051447243>>>random()0.7039672847873445>>>random()0.5959989547801257用于生成伪随机浮点值4伪随机数假设选手的发球回合得分概率是0.70。if<playerwinsserve>:score=score+14伪随机数ifrandom()<prob:score=score+1假设生成一个0~1之间的随机值。区间(0,1)的70%正好在0.7的左边。所以70%的时间随机数将小于0.7,而其他30%的次数将大于等于0.7。一般来说,如果prob表示选手获胜的概率,则random()<prob就成功地表示了正确的概率。PART5自顶而下的设计5自顶而下的设计一种成熟的解决复杂问题的技术称为“自顶向下”。从总问题开始,尝试用较小的问题来表达解决方案问题变得很小,以至于它们可以轻松得到解决依次使用相同的技术,攻克每个较小的问题把所有的小块都拼回来,大功告成,得到一个程序PART6顶层设计6顶层设计打印介绍获取输入:probA,probB,n用probA和probB模拟n局短柄壁球比赛打印playerA和playerB的获胜报告输入处理输出遵循模式:6顶层设计打印介绍:defmain():printIntro()

6顶层设计从用户获取输入:probA,probB,n:defmain():printIntro()probA,probB,n=getInputs()6顶层设计用probA和probB模拟n局短柄壁球比赛:调用函数simNGames进行模拟比赛需要模拟的场n模拟使用怎样的probA和probB的值6顶层设计用probA和probB模拟n局短柄壁球比赛:defmain():printIntro()probA,probB,n=getInputs()winsA,winsB=simNGames(n,probA,probB)6顶层设计defmain():printIntro()probA,probB,n=getInputs()winsA,winsB=simNGames(n,probA,probB)printSummary(winsA,winsB)打印playerA和playerB的获胜报告:PART7关注点分离7关注点分离defmain():printIntro()probA,probB,n=getInputs()winsA,winsB=simNGames(n,probA,probB)printSummary(winsA,winsB)7关注点分离我们已经指定了执行这些任务的函数名称、参数和预期返回值。这些信息称为函数的“接口”或“签名”。唯一关注的是,如果给出比赛局数和两个概率,它必须返回每名选手获胜的正确局数。main函数只关心每个(子)函数“做什么”。7关注点分离图9.1短柄壁球模拟的一级结构图7关注点分离在设计的每个层次上,接口告诉我们下层的哪些细节很重要,其他东西都可以暂时忽略确定某些重要特征并忽略其他细节的一般过程称为“抽象”可以将自顶向下设计的整个过程视为发现有用抽象的系统方法PART8第二层设计第二课时defprintIntro():print("这个程序模拟了选手A和选手B之间的短柄垒球游戏,每个选手")

print("在发球阶段的得分可能性由一个概率(0和1之间的数字)来表示,")

print("总是选手A先发球。")8第二层设计8第二层设计defgetInputs():#返回三个参数probA,probB和na=float(input("A赢得发球的概率为多少?"))

b=float(input("B赢得发球的概率是多少?"))

n=int(input("一共模拟多少场比赛?"))

returna,b,n函数中的变量是该函数的局部变量。提示输入获取三个值,返回给主程序。PART9设计simNGames9设计simNGames初始化A和B的胜利场数为0循环n次模拟比赛如果A赢A的胜场叫1elseB的胜场加1基本思想是模拟n局比赛,并记录每名选手的胜利局数。defsimNGames(n,probA,probB):#模拟n次比赛返回winsA和winsBwinsA=0winsB=0foriinrange(n):9设计simNGames9设计simNGames下面模拟一句短柄垒球比赛。更新结构图以反映这些决定采用一个simOneGame函数来表示一场比赛以他们的成绩为输出,让simOneGame返回两名球员的最终成绩9设计simNGames图9.2短柄壁球模拟的二级结构图9设计simNGamesdefsimNGames(n,probA,probB):winsA=winsB=0foriinrange(n):scoreA,scoreB=simOneGame(probA,probB)ifscoreA>scoreB:winsA=winsA+1else:winsB=winsB+1returnwinsA,winsBPART10第三层设计10第三层设计对短柄壁球规则的逻辑进行编码:如何记录谁在发球呢?我要解决simOneGame问题!需要记录得分知道是谁在发球用存储“A”或“B”的字符串变量10第三层设计初始化scores为0选手"A"发球游戏没结束时一直循环:模拟任何一个正在发球的球员的发球更新游戏状态返回scores10第三层设计defsimOneGame(probA,probB):scoreA=0scoreB=0erving="A"while<condition>:10第三层设计只要比赛没结束,就需要继续循环这个条件到底是什么?将细节隐藏在另一个函数gameOver中,如果比赛结束,则返回True,否则返回False通过查看分数来判断游戏是否结束10第三层设计图9.3短柄壁球模拟的第三层结构图10第三层设计defsimOneGame(probA,probB):scoreA=0scoreB=0serving="A"whilenotgameOver(scoreA,scoreB):如果A在发球,那么我们需要使用A的概率,并且根据发球的结果,更新A的分数,或将发球更改为B。10第三层设计ifserving=="A":ifrandom()<probA:scoreA=scoreA+1else:serving="B"10第三层设计ifserving=="A":ifrandom()<probA:scoreA=scoreA+1else:serving="B"else:ifrandom()<probB:scoreB=scoreB+1else:serving="A"10第三层设计defsimOneGame(probA,probB):scoreA=0scoreB=0serving="A"whilenotgameOver(scoreA,scoreB):ifserving=="A":ifrandom()<probA:scoreA=scoreA+1else:serving="B"else:ifrandom()<probB:scoreB=scoreB+1else:serving="A"returnscoreA,scoreBPART11整理完成11整理完成defgameOver(a,b):#a和b表示一场壁球游戏的得分#如果游戏结束,则返回True,否则返回Falsereturna==15orb==1511整理完成fromrandomimportrandomdefmain():printIntro()probA,probB,n=getInputs()winsA,winsB=simNGames(n,probA,probB)printSummary(winsA,winsB)

defprintIntro():

print("这个程序模拟了选手A和选手B之间的短柄垒球游戏,每个选手")

print("在发球阶段的得分可能性由一个概率(0和1之间的数字)来表示,")

print("总是选手A先发球。")11整理完成defgetInputs():#返回三个参数probA,probB和na=float(input("A赢得发球的概率为多少?"))

b=float(input("B赢得发球的概率是多少?"))

n=int(input("一共模拟多少场比赛?"))

returna,b,n

defsimNGames(n,probA,probB):winsA=winsB=0foriinrange(n):scoreA,scoreB=simOneGame(probA,probB)ifscoreA>scoreB:winsA=winsA+1else:winsB=winsB+1returnwinsA,winsB11整理完成defsimOneGame(probA,probB):serving="A"scoreA=0scoreB=0whilenotgameOver(scoreA,scoreB):ifserving=="A":ifrandom()<probA:scoreA=scoreA+1else:serving="B"else:ifrandom()<probB:scoreB=scoreB+1else:serving="A"returnscoreA,scoreB11整理完成defgameOver(a,b):#a和b表示一场壁球游戏的得分

#如果游戏结束,则返回True,否则返回Falsereturna==15orb==15

defprintSummary(winsA,winsB):#打印选手的胜利场数即概率.

n=winsA+winsBprint("\n模拟游戏:",n)print("A赢:{0}({1:0.1%})".format(winsA,winsA/n))print("B赢:{0}({1:0.1%})".format(winsB,winsB/n))

if__name__=='__main__':main()PART12设计过程总结12设计过程总结自顶向下的设计实战:从结构图的最高层开始,一路向下。在每个层次上,我们从总算法开始,然后逐渐将它提炼为精确的代码。这种方法有时称为“逐步求精”。将算法表示为一系列较小的问题用较小问题的接口来表示该算法,从而描述算法的细节为每个小问题开发一个接口对每个较小的问题重复此过程PART13自底向上的实现13自底向上的实现当我们有一段完整代码时,即使我们再小心,但当我们测试验证时,还是有时可能会对结果有些失望。PART14单元测试14单元测试图9.4短柄壁球模拟的第三层结构图14单元测试>>>gameOver(0,0)False>>>gameOver(5,10)False>>>gameOver(15,3)True>>>gameOver(3,15)True14单元测试>>>simOneGame(.5,.5)(13,15)>>>simOneGame(.5,.5)(15,11)>>>simOneGame(.3,.3)(15,11)>>>simOneGame(.3,.3)(11,15)>>>simOneGame(.4,.9)(4,15)>>>simOneGame(.4,.9)(1,15)>>>simOneGame(.9,.4)(15,3)>>>simOneGame(.9,.4)(15,0)>>>simOneGame(.4,.6)(9,15)>>>simOneGame(.4,.6)(6,15)当概率相等时,分数接近。当概率相差较大时,比赛就是一边倒。14单元测试我们可以继续这样的部分实现,将组件添加到代码中,同时测试每个组件。软件工程师称这个过程为“单元测试”。独立测试每个函数更容易发现错误。当你测试整个程序的时候,有可能一切顺利。PART15模拟结果15模拟结果假设Denny赢球的概率为55%,比他强一点的选手赢球概率为60%,我们模拟1000次,运行结果如下:这个程序模拟了选手A和选手B之间的短柄垒球游戏,每个选手在发球阶段的得分可能性由一个概率(0和1之间的数字)来表示,总是选手A先发球。A赢得发球的概率为多少?0.55B赢得发球的概率是多少?0.6一共模拟多少场比赛?1000

模拟游戏:1000A赢:389(38.9%)B赢:611(61.1%)当相差很小时,Denny获胜的概率大概为三分之一。所以Denny输的不冤。PART16其他设计技术16其他设计技术自顶向下的设计是一种非常强大的程序设计技术,但并不是创建程序的唯一方法。PART17原型与螺旋式开发17原型与螺旋式开发另一种设计方法是从程序或程序组件的简单版本开始,然后尝试逐渐添加功能,直到满足完整的规格说明。初始的朴素版本称为“原型”。原型通常会导致一种“螺旋式”开发过程。设计、实现并测试一个原型新功能被设计、实现和测试在开发过程中,完成许多小循环,原型逐渐扩展为最终的程序17原型与螺旋式开发例:如何开发短柄壁球模拟。问题的本质在于模拟一个短柄壁球的比赛。我们可能就从simOneGame函数开始。进一步简化,的原型可以假设每名选手有一半对一半的机会赢得每一分,并且只比赛30回合。这需要考虑问题的关键,即处理得分和换发球。17原型与螺旋式开发fromrandomimportrandomdefsimOneGame():scoreA=0scoreB=0serving="A"foriinrange(30):ifserving=="A":ifrandom()<.5:scoreA=scoreA+1else:serving="B"else:ifrandom()<.5:scoreB=scoreB+1else:serving="A"print(scoreA,scoreB)

if__name__==’__main__’:simOneGame()17原型与螺旋式开发101020...777817原型与螺旋式开发初始原型。比赛30回合,发球者总是有50%的获胜机率。打印出每次发球后的分数。添加两个参数,表示两名选手的不同概率。比赛直到其中一名选手得到15分。此时,我们有了能工作的一局比赛的模拟。构建完整的程序。添加交互式输入和格式漂亮的结果报告。扩展进行多局比赛。输出是每名选手赢得的比赛数量。阶段1阶段3阶段4阶段2阶段5PART18设计的艺术18设计的艺术要注意的是,螺旋式开发不是自顶向下设计的替代品。相反,它们是互补的方法。在设计原型时,你仍然会使用自顶向下的技术。设计没有“唯一正确的方式”。事实上,良好的设计与科学一样是一个创造性的过程。事后可以对设计细致地分析,但是没有生成设计的硬性规则。课程目标小结希望大家能够理解伪随机数及其在蒙特卡罗模拟中的应用、理解并能应用自顶向下和螺旋式设计技术来编写复杂的程序、理解单元测试,并能将这种技术应用于复杂程序的实现和调试。课程目标实践任务一种成熟的解决复杂问题的技术称为“自顶向下”。基本思想是从总问题开始,尝试用较小的问题来表达解决方案。然后依次使用相同的技术,攻克每个较小的问题。最终,问题变得如此之小,以至于它们可以轻松得到解决。然后把所有的小块都拼回来,大功告成,你得到了一个程序。我们将开发一个短柄壁球比赛的简单模拟。课程目标课后习题选择题1.表达式_______在大约66%的时间里为真。a.random()>=66 b.random()<66c.random()<0.66 d.random()>=0.66

2.以下_______项不是纯粹的自顶向下设计的一步。a.对较小的问题重复该过程 b.用较小问题的接口详细说明算法c.构建一个简化的系统原型 d.用较小的问题来表示算法

3.模块层次结构图中的箭头表示_______。a.信息流 b.控制流c.粘贴附件 d.单行道

4.使用概率事件的模拟称为_______。a.伪随机 b.蒙特卡罗c.MontyPython d.混沌

5.字符串格式化模板中百分号表示_______。a.% b.\%c.%% d.\%%课程目标课后习题判断题1.Python的random函数返回伪随机整数。 2.自顶向下的设计也称为逐步求精。

3.在自顶向下的设计中,主要算法是根据尚未存在的函数编写的。 4.单元测试是单独测试较大程序的组件的过程。

5.开发人员应使用自顶向下或螺旋式设计,但不能同时使用。 课程目标课后习题简答题1._______函数能够从给定范围中选择一个伪随机整数。

2.在自顶向下的设计中,设计的子组件是_______。

3.设计中组件之间依赖关系视图称为_______。

4.在螺旋式开发中使用的系统的初始版本称为_______。

5.系统结构中,最容易开始单元测试的地方是_______。THANKSFORYOURATTENTION谢谢聆听Python程序设计类与对象第十章课程目标课程目标1领会如何通过定义新类为复杂程序提供结构3524能够阅读并编写Python类定义理解封装的概念并知道它如何帮助构建模块化的、可维护的程序能够编写包含简单类定义的程序能够编写包含创新(程序员设计的)控件的交互式图形程序PART1对象的快速复习1对象的快速复习程序“计算”结构化程序“数据”结构化1对象的快速复习对象是管理复杂数据的重要工具对象一组相关信息一组信息的操作存储信息的变量

称为属性“存在”于对象内的函数

称为方法这些操作又称为方法实例变量中一组相关信息被称为对象的“属性”1对象的快速复习例子一个Circle对象

属性:center:记住圆的中心点radius:保存圆的半径

方法:draw方法:检查center和radius,以确定窗口中的哪些像素应该着色着Move方法:改变中心的值,以反映圆的新位置1对象的快速复习记住每个对象都是一个类的一个实例,对象的类决定对象将具有什么属性。一个类描述它的实例知道什么和做什么创建新对象调用构造方法可视为创建新实例的工厂交通工具

是一个类某一辆汽车、某一架飞机、某一辆自行车等

是这个交通工具类的实例对象1对象的快速复习创建一个新的Circle对象:myCircle=Circle(Point(0,0),20)Circle是类的名称,用于调用构造方法实例被创建后,可通过调用它的方法来操作它:myCircle.draw(win)myCircle.move(dx,dy)

创建了一个新的Circle实例,并将引用保存到变量myCircle构造方法的参数用于初始化myCircle内部的一些实例变量(即center和radius)PART2示例程序:炮弹2示例程序:炮弹程序规格说明解决的问题:输入各种发射角度和初始速度,计算炮弹飞多远模拟炮弹程序输入参数输出结果炮弹的发射角(以度为单位)初始速度(以米每秒为单位)初始高度(以米为单位)抛体在撞击地面前飞行的距离(以米为单位)2示例程序:炮弹程序规格说明重力加速度:g≈9.8m/s2用模拟来跟踪炮弹每个时刻的位置计算原理:物体在给定时间内飞行的距离等于其速率乘以时间(d=rt)2示例程序:炮弹程序设计炮弹的两个维度:高度:知道炮弹什么时候碰到地面一距离:记录炮弹飞多远二2示例程序:炮弹程序设计炮弹的位置可视为二维图中的点(x,y)xyx值:炮弹与起点的水平距离y值:炮弹与地面的高度,即垂直距离2示例程序:炮弹程序设计xy(0,0)炮弹飞行过程中,它在二维图中点的坐标是时刻更新的

每隔十分之一秒定时检查炮弹的位置每个维度的精确距离由炮弹在该方向上的速度决定2示例程序:炮弹程序设计分离速度的x和y分量可以让问题变得更容易x速度y速度由于忽略风的阻力,x速度在整个飞行中保持不变由于重力的影响,y速度随时间而变化速度开始为正,后随着炮弹开始下降变为负值2示例程序:炮弹程序设计根据分析,模拟程序要做的事情如下:输入模拟参数:角度、速度、高度、间隔计算炮弹的初始位置:xpos、ypos计算炮弹的初始速度:xvel、yvelwhile炮弹仍在飞行时:将xpos,ypos和yvel的值更新为飞行输出中距离作为xpos的距离2示例程序:炮弹算法的第一行很简单,只需要合适的输入语句序列:程序设计defmain():

angle=float(input("Enterthelaunchangle(indegrees):"))

vel=float(input("Entertheinitialvelocity(inmeters/sec):"))

h0=float(input("Entertheinitialheight(inmeters):"))

time=float(input("Enterthetimeintervalbetweenpositioncalcula

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论