(个人学习笔记)
文章目录
- 前言
- 一、自顶向下是什么?(定义)
- 二、自底向上是什么?(定义)
- 三、例题源代码
- 四、修改(照葫芦画瓢)
- 1.乒乓球规则
- 2.代码
- 3.结果展示
- 其他相关学习链接
- 加料区
前言
本文通过对书上例题进行举一反三,根据乒乓球实际规则进行修改代码,从而加深对于自顶向下程序设计思想的认识与了解。程序需要采用自顶向下设计方法,采用自底向上的执行过程。利用函数进行封装。
程序设计需要了解自顶向下的设计方法,自底向上的执行过程
一、自顶向下是什么?(定义)
以一个总问题开始,试图把它表达为很多小问题组成的解决方案。再用同样的技术依次攻破每个小问题,最终问题变得非常小,以至于可以很容易解决。然后只需把所有的碎片组合起来,就可以得到一个程序。
二、自底向上是什么?(定义)
开展测试的更好办法也是将程序分成小部分逐个测试 执行中等规模程序的最好方法是从结构图最底层开始,而不是从顶部开始,然后逐步上升。或者说,先运行和测试每一个基本函数,再测试由基础函数组成的整体函数,这样有助于定位错误。
三、例题源代码
from random import random
def printIntro(): #输出比赛相关信息的函数(无参数)
print("这个程序模拟两个选手A和B的某种竞技比赛")
print("程序运行需要A和B的能力值(以0到1之间\
的小数表示)")
def getInputs():#输入函数(无参数)#得到a,b,n
a = eval(input("请输入选手A的能力值(0-1):"))
b = eval(input("请输入选手B的能力值(0-1):"))
n = eval(input("模拟比赛的场次:"))
return a,b,n
def simNGames(n,probA,probB):#模拟N场比赛
#(三个参数:n,probA,probB
#得到winsA,winsB
winsA , winsB = 0,0 #wins为胜利的场数
for i in range(n):
scoreA,scoreB = simOneGame(probA,probB)
if scoreA > scoreB:
winsA += 1
else:
winsB += 1
return winsA,winsB
def gameOver(a,b): #比赛结束的条件函数
#得到判断是否结束的逻辑值
return a == 15 or b == 15
def simOneGame(probA,probB): #模拟单场比赛
#参数: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 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 main():
printIntro()
probA,probB,n = getInputs()
winsA,winsB =simNGames(n,probA,probB)
printSummary(winsA, winsB)
main()
四、修改(照葫芦画瓢)
1.乒乓球规则
乒乓球比赛以11分为一局,一般采用七局四胜制或五局三胜制。正式比赛中,在一局比赛中,先得11分的一方为胜方,10平后,先多得2分的一方为胜方。
一场比赛,单打淘汰赛采用七局四胜制,双打淘汰赛和团体赛采用五局三胜制。
2.代码
'''
乒乓球规则赛制:
乒乓球比赛以11分为一局,一般采用七局四胜制或五局三胜制。
正式比赛中,在一局比赛中,先得11分的一方为胜方,10平后,
先多得2分的一方为胜方。
'''
from random import random
def printIntro():
print("我的学号后两位信息为10")
print("这个程序模拟两个队伍A和B的乒乓球比赛(A,B的人数相同且为1或2)")
print("程序运行需要队伍A和队伍B的能力值(以0到1之间的小数表示)")
print("如若比赛是双打,则队伍A和队伍B的能力值比较,采用两个队员能力的平均值代表队伍的水平")
print("程序运行需要指定比赛类型(单打的淘汰赛采用七局四胜制,双打淘汰赛和团体赛采用五局三胜制)")
def getInputs():
st = input("模拟比赛的类型(单打淘汰赛或双打淘汰赛):")
a = input("请输入队伍A的能力值(0-1)(若为双打则以逗号隔开):").split(',')#此处的a,b为列表数据类型
b = input("请输入队伍B的能力值(0-1)(若为双打则以逗号隔开):").split(',')
if (len(a) == 1 and len(b) == 1) or (len(a) == 2 and\
len(b) == 2):
if len(a) == 1:
a = eval(a[0])
b = eval(b[0])
else:
a = (eval(a[0]) + eval(a[1])) / 2
b = (eval(b[0]) + eval(b[1])) / 2
else:
print("输入信息错误,本次模拟失败,请重新输入信息后再次尝试")
n = eval(input("模拟比赛的场次:"))
return st,a,b,n
def simN_changGames(n,st,probA,probB):#模拟n场比赛
winsA , winsB = 0,0
for i in range(n):
scoreA,scoreB = simOne_changGame(st,probA,probB)
if scoreA > scoreB:
winsA += 1
else:
winsB += 1
return winsA,winsB
def signal_gameOver(a,b):#单局比赛结束条件
if (a == 11 and b < 10 )or\
(b == 11 and a < 10):
return True
elif (a >= 10 and b >= 10):
if a > b and a - b == 2 :
return True
elif a < b and b - a == 2:
return True
def all_gameOver(st,c,d):#单场比赛结束条件
if st == "单打淘汰赛":
if (c == 4 and d < 4) or (d == 4 and c < 4):
return True
if st == '双打淘汰赛':
if (c == 3 and d < 3) or (d == 3 and c < 3):
return True
def simOne_juGame(probA,probB):#模拟单局比赛
scoreA,scoreB = 0,0 #小比分
serving = 'A'
while not signal_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 simOne_changGame(st,probA,probB):#模拟单场比赛
scoA,scoB = 0,0 #大比分
while not all_gameOver(st,scoA,scoB):
scoreA,scoreB = simOne_juGame(probA, probB)
if scoreA > scoreB:
scoA += 1
else:
scoB += 1
return scoA,scoB
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 main():
printIntro()
st,probA,probB,n = getInputs()
winsA,winsB =simN_changGames(n,st,probA,probB)
printSummary(winsA, winsB)
main()
3.结果展示
我的学号后两位信息为10
这个程序模拟两个队伍A和B的乒乓球比赛(A,B的人数相同且为1或2)
程序运行需要队伍A和队伍B的能力值(以0到1之间的小数表示)
如若比赛是双打,则队伍A和队伍B的能力值比较,采用两个队员能力的平均值代表队伍的水平
程序运行需要指定比赛类型(单打的淘汰赛采用七局四胜制,双打淘汰赛和团体赛采用五局三胜制)
模拟比赛的类型(单打淘汰赛或双打淘汰赛):单打淘汰赛
请输入队伍A的能力值(0-1)(若为双打则以逗号隔开):0.45
请输入队伍B的能力值(0-1)(若为双打则以逗号隔开):0.61
模拟比赛的场次:1000
竞技分析开始,共模拟1000场比赛
队伍A获胜24场比赛,占比2.4%
队伍B获胜976场比赛,占比97.6%
我的学号后两位信息为10
这个程序模拟两个队伍A和B的乒乓球比赛(A,B的人数相同且为1或2)
程序运行需要队伍A和队伍B的能力值(以0到1之间的小数表示)
如若比赛是双打,则队伍A和队伍B的能力值比较,采用两个队员能力的平均值代表队伍的水平
程序运行需要指定比赛类型(单打的淘汰赛采用七局四胜制,双打淘汰赛和团体赛采用五局三胜制)
模拟比赛的类型(单打淘汰赛或双打淘汰赛):双打淘汰赛
请输入队伍A的能力值(0-1)(若为双打则以逗号隔开):0.56,0.48
请输入队伍B的能力值(0-1)(若为双打则以逗号隔开):0.87,0.32
模拟比赛的场次:1000
竞技分析开始,共模拟1000场比赛
队伍A获胜235场比赛,占比23.5%
队伍B获胜765场比赛,占比76.5%
此代码仅为个人学习所用,运行结果尚未进行检验,仅供参考。
其他相关学习链接
https://blog.csdn.net/qq_40855366/article/details/81177203
https://blog.csdn.net/sxingming/article/details/51235650
https://blog.csdn.net/qq_40390825/article/details/82467008
加料区
(2)采用篮球或者足球规则模拟比赛,分析体育竞技规则,模拟比赛。(良好),基本要求同上。
(3)采用乒乓球、羽毛球、篮球、足球等规则中的一种。同时采用循环赛或者晋级赛形式,模拟分析4个队及以上体育竞技,并输出排名。建议可以采用面向对象方法或者改动上面程序。参考面向对象:https://www.cnblogs.com/wangmo/p/7751199.html