如果现在要编写一个关于“体育竞技分析”的程序:要求用计算机模拟不同能力的运动员,体育竞技时的胜负概率,从而做出分析。这个问题如何求解呢?
程序总体框架分析
通过对题目的分析,我们可以知道,可以通过设计以下四个功能去完成此程序:
-步骤一:打印程序的介绍性信息
-步骤二:获得程序运行参数:personA,personB,n.(运动员A和B的能力值以及模拟比赛的场次数量)
-步骤三:利用运动员A和运动员B的能力值,模拟n场比赛。
-步骤四:输出运动员A和B获胜比赛的场次和概率。
根据以上产品功能我们可以设计相应的功能接口:
1:printInfo() :输出产品功能信息。
2:getInputs():获得运动员的能力值以及比赛的场数。
3. simNGames():根据运动员的能力值模拟n场比赛。
4. printSummary():输出运动员A和B获胜比赛的场次和概率。
以上就是我们根据前期分析得到的产品接口,经过整理,此程序的主函数可以如下设计:
有了这样的分解,我们可以不用关心这四个函数里面是什么,也不用关心函数怎么写,但是我们可以将这样的组合形成一段代码:
#第一阶段:
def main():
printIntro()#输出产品功能信息。
proA,proB,n = getInputs()#获得运动员的能力值以及比赛的场数。
winsA,winsB = simNGames(n,probA,probB)#根据运动员的能力值模拟n场比赛。
peintSummary(winsA,winsB)#输出运动员A和B获胜比赛的场次和概率。
完成分析之后,我们可以试着看一看相应的功能可以不可以实现:
首先我们来看printInfo()函数,无非是打印一些功能信息:
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("竞技分析开始!")
print("共模拟{}场比赛!\n{:*^20}\n选手A获胜{}场比赛,占比{:0.1%}\n选手B获胜{}场比赛,占比{:0.1%}".format(n,"比赛结果",winsA,winsA/n,winsB,winsB/n))
看着也同样不难,最后让我们分析稍稍有点难度的第三个函数:simNGames()
模拟n场比赛,相当于模拟n次一场比赛,也即是将“模拟n场比赛”细分为“模拟一场比赛n次”。在这里我们可以再写一个函数 simOneGame(),通过将选手A和选手B的能力值输入给电脑,电脑模拟出来选手A和B的比赛得分并返回。
def simNGames(n,proA,proB):
winsA , winsB = 0 , 0
for i in range(n):
scoreA,scoreB = simOneGame(proA,proB)
if scoreA > scoreB :
winsA += 1
else:
winsB += 1
return winsA,winsB
我们规定:在1场比赛中,谁先获得15分谁赢。
那么怎么才能写出simOneGame()函数呢?
def simOneGame(proA,proB):
scoreA,scoreB = 0,0
serving = "A"#A先发球
while not gameOver(scoreA,scoreB):
if serving == "A":
if random() < proA:
scoreA += 1
else:
serving = "B"
else:
if random() < proB:
scoreB += 1
else:
serving = "A"
return scoreA,scoreB
gameOver(scoreA,scoreB)函数用来判定游戏是否结束,因此可以这样写:
def gameOver(a,b):
return a==15 or b==15
如此一来,我们就将一个大的问题通过分析,拆分成若干个小问题,通过对若干个小问题的求解,我们便可以完成对整个问题的求解,让我们来回顾一下整个过程
这就是“自顶向下”设计过程!
我们来运行一下这个程序:
可以发现一个很有趣的现象:两个选手能力相差百分之5,但是比赛结果却并不止相差百分之5!而是十分悬殊!这就是体育竞技的本质:可能两个选手水平相差不大,但是比赛结果却大相径庭!所以,当你看到两个选手在体育比赛时,比赛结果相差很近时,很有可能两个选手的水平其实几乎一样,相差十分小,但这也告诉我们:脚踏实地,撸起袖子加油干吧!
源代码:
from random import random
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("竞技分析开始!")
print("共模拟{}场比赛!\n{:*^30}\n选手A获胜{}场比赛,占比{:0.1%}\n选手B获胜{}场比赛,占比{:0.1%}".format(n,"比赛结果",winsA,winsA/n,winsB,winsB/n))
def simNGames(n,proA,proB):
winsA , winsB = 0 , 0
for i in range(n):
scoreA,scoreB = simOneGame(proA,proB)
if scoreA > scoreB :
winsA += 1
else:
winsB += 1
return winsA,winsB
def simOneGame(proA,proB):
scoreA,scoreB = 0,0
serving = "A"#A先发球
while not gameOver(scoreA,scoreB):
if serving == "A":
if random() < proA:
scoreA += 1
else:
serving = "B"
else:
if random() < proB:
scoreB += 1
else:
serving = "A"
return scoreA,scoreB
def gameOver(a,b):
return a==15 or b==15
def main():
printIntro()
proA,proB,n = getInputs()
winsA,winsB = simNGames(n,proA,proB)
printSummary(winsA,winsB)
main()