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()
運行截圖: