1自顶向下的设计方法:
以一个总问题开始,试图把它表达为很多小问题组成的解决方案。再用同样的技术依次攻破每个小问题,最终问题变得非常小,以至于可以很容易解决。然后只需把所有的碎片组合起来,就可以得到一个程序。
顶层设计:自顶向下设计中最重要的是顶层设计。 以体育竞技分析为例,可以从问题的IPO描述开始。大多数程序都可以简单将IPO 描述直接用到程序结构设计中,体育竞技分析从用户得到模拟参数模拟比赛,最后输出结果。
步骤1 输出一些介绍信息,针对提升用户体验十分有益。
顶层设计一般不写出具体代码,仅给出函数定义,其中,printIntro()函数打印一些必要的说明
步骤2 获得用户输入。
通过函数将输入语句及输入格式等细节封装或隐藏,只需要假设程序如果调用了getInputs()函数即可获取变量 probA, probB 和 n 的值。这个函数必须为主程序返回这些值,截止第2步
步骤3 需要使用probA、probB 模拟n场比赛。 此时,可以采用解决步骤2的类似方法,设计一个simNGames()函数来模拟n场比赛,并返回结果。按照体育竞技问题的要求,该函数需要模拟比赛,并获得球员A 和球员B 赢得比赛的结果。
步骤4 输出结果,设计思想类似,仍然只规划功能和函数
因此,原问题被划分为了4 个独立的函数:printIntro(),getInputs(),simNGames()和printSummary()。分解过程让程序员在这一步不必关心具体细节而专心考虑程序的结构设计。
第 n 层设计
def simNGames(n,probA,porbB): winsA,winsB=0,0 for i in range(n): scoreA,scoreB=simOneGame(porbA,porbB) if scoreA>scoreB: winsA+=1 else: winsB+=1 reture winsA,winsB
simNGames()函数是整个函数的核心,其基本思路是模拟n场比赛,并跟踪记录每个球员赢得了多少比赛。
下面·是·羽毛球·实例·
比赛规则·
1. 21 分制,3局2胜为佳
2. 每球得分制
3. 每回合中,取胜的一方加 1 分
4. 当双方均为 20 分时,领先对方 2 分的一方赢得该局比赛
5. 当双方均为 29 分时,先取得 30 分的一方赢得该局比赛
6. 一局比赛的获胜方在下一局率先发球
def simOneGame(probA,porbB): scoreA,score=0,0 serving="A" while not gameOver(scoreA,scoreB): if serving =="A": if random()<porbA: scoreA+=1 else: serving="B" else: if random()<probB: scoreB+=1 else: serving="A" return scoreA,scoreB
整个程序如下
from random import random def printInfo(): print("这个程序模拟两个选手A和B的羽毛球竞技比赛") print("程序需要两个选手的能力值0-1")
def getInput(): a = eval(input("请输入选手A的能力值(0-1):")) b = eval(input("请输入选手B的能力值(0-1):")) m=eval(input("比赛的局数:")) n = eval(input("模拟比赛的场次:")) return a,b,m,n 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 simNGames(m,n,probA,probB): winsA,winsB = 0,0 wa,wb=0,0 for i in range(n): for i in range(m): scoreA,scoreB = simOneGame(probA,probB) if scoreA > scoreB: wa += 1 else: wb += 1 if wa==2: winsA+=1 wa,wb=0,0 break if wb==2: winsB+=1 wa,wb=0,0 break return winsA,winsB def simOneGame(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 gameOver(a,b): if(a>=20 or b>=20): if(abs(a-b)==2 and a<=29 and b<=29): return True else: return a==30 or b==30 else: return False def main(): printInfo() probA,probB,m,n = getInput() winsA,winsB = simNGames(m,n,probA,probB) printSummary(winsA,winsB) main()
运行截图: