1. 程式人生 > >6.程式設計方法學

6.程式設計方法學

一、例項13:體育競技分析

1.1 問題分析

體育競技分析

  • 需求:毫釐是多少?如何科學分析體育競技比賽?
  • 輸入:球員的水平
  • 輸出:可預測的比賽成績

體育競技分析:模擬N場比賽

  • 計算思維:抽象 + 自動化
  • 模擬:抽象比賽過程 + 自動化執行N場比賽
  • 當N越大時,比賽結果分析會越科學

比賽規則

  • 雙人擊球比賽:A & B,回合制,5局3勝
  • 開始時一方先發球,直至判分,接下來勝者發球
  • 球員只能在發球局得分,15分勝一局

1.2 自頂向下和自底向上

自頂向下(設計): 解決複雜問題的有效方法

將一個總問題表達為若干個小問題組成的形式,使用同樣方法進一步分解小問題,直至小問題可以用計算機簡單明瞭的解決。

自底向上(執行): 逐步組建複雜系統的有效測試方法

分單元測試,逐步組裝,按照自頂向下相反的路徑操作,直至系統各部分以組裝的思路都經過測試和驗證。

1.3 "體育競技分析"例項講解

程式總體框架及步驟

步驟1:列印程式的介紹性資訊。                   #printInfo()       

步驟2:獲得程式執行引數:proA, proB, n。        #printInfo()

步驟3:利用球員A和B的能力值,模擬n局比賽。      #simNGames()

步驟4:輸出球員A和B獲勝比賽的場次及概率。       #printSummary()
  • 第一階段:程式總體框架及步驟

image

def main():
    printIntro()
    probA,proB,n=getInputs()
    winsA,winsB=simNGames(n,proA,proB)
    printSummary(winsA,winsB)
    
    
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("競技分析開始,共模擬{}場比賽".format(n))
    print("選手A獲勝{}場比賽,佔比{:0.1%}".format(winsA, winsA / n))
    print("選手B獲勝{}場比賽,佔比{:0.1%}".format(winsB, winsB / n))

  • 第二階段:步驟3 模擬N局比賽

image

def simNGames(n, probA, probB):
    winsA, winsB = 0, 0
    for i in range(n):
        scoreA, scoreB = simOneGame(probA, probB)
        if scoreA > scoreB:
            winsA += 1
        else:
            winsB += 1
    return winsA, winsB
  • 第三階段:根據分數判斷局的結束

image

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 = "B"
    return scoreA, scoreB


def gameOver(a, b):
    return a == 15 or b == 15

image

1.4 舉一反三

理解自頂向下和自底向上

  • 理解自頂向下的設計思維:分而治之
  • 理解自底向上的執行思維:模組化整合
  • 自頂向下是“系統”思維的簡化

應用問題的擴充套件

  • 擴充套件比賽引數,增加對更多能力對比情況的判斷
  • 擴充套件比賽設計,增加對真實比賽結果的預測
  • 擴充套件分析邏輯,反向推理,用勝率推算能力?

1.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("競技分析開始,共模擬{}場比賽".format(n))
    print("選手A獲勝{}場比賽,佔比{:0.1%}".format(winsA, winsA / n))
    print("選手B獲勝{}場比賽,佔比{:0.1%}".format(winsB, winsB / n))


def simNGames(n, probA, probB):
    winsA, winsB = 0, 0
    for i in range(n):
        scoreA, scoreB = simOneGame(probA, probB)
        if scoreA > scoreB:
            winsA += 1
        else:
            winsB += 1
    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 = "B"
    return scoreA, scoreB


def gameOver(a, b):
    return a == 15 or b == 15


def main():
    printIntro()
    probA, probB, n = getInputs()
    winsA, winsB = simNGames(n, probA, probB)
    printSummary(winsA, winsB)


main()

二、Python程式設計思維

  • 計算思維與程式設計
  • 計算生態與Python語言
  • 使用者體驗與軟體產品
  • 基本的程式設計模式

2.1 計算思維與程式設計

  • 計算思維:(Computational Thinking):計算思維是基於計算機的思維方式

    第3種人類思維特徵

    • 邏輯思維:推理和演繹,數學為代表,A->B B->C A->C
    • 實證思維:實驗和驗證,物理為代表,引力波<-實驗
    • 計算思維:設計和構造,計算機為代表,漢諾塔遞迴

    抽象和自動化

    抽象問題的計算過程,利用計算機自動化求解

    • 計算思維基於計算機強大的算力及海量資料
    • 抽象計算過程,關注設計和構造,而非因果
    • 以計算機程式設計為實現的主要手段

image image image image image

  • 計算思維與程式設計

程式設計是將計算思維變成現實的手段

image

2.2 計算生態與Python語言

從開源運動說起…

  • 自由軟體時代到來
    • 1983, Richard Stallman啟動GNU專案
    • 1989, GNU通用許可協議誕生
  • 開源生態逐步建立
    • 1991, Linus Torvalds釋出了Linux核心
    • 1998, 網景瀏覽器開源,產生了Mozilla

image

開源思想深入演化和發展,形成了計算生態

    計算生態以開源專案為組織形式,充分利用“共識原則”和“社會利他”組織人員,
在競爭發展、相互依存和迅速更迭中完成資訊科技的更新換代,形成了技術的自我演化路徑

沒有頂層設計、以功能為單位、具備三個特點

  • 競爭發展
  • 相互依存
  • 迅速更迭

計算生態與Python語言

  • 以開源專案為代表的大量第三方庫

      Python語言提供 >13萬個第三方庫
    
  • 庫的建設經過野蠻生長和自然選擇

      同一個功能,Python語言2個以上第三方庫
    
  • 庫之間相互關聯使用,依存發展

      Python庫間廣泛聯絡,逐級封裝
    
  • 社群龐大,新技術更迭迅速

      AlphaGo深度學習演算法採用Python語言開源
    

API != 生態

計算生態的價值

創新:跟隨創新、整合創新、原始創新

  • 加速科技類應用創新的重要支撐
  • 發展科技產品商業價值的重要模式
  • 國家科技體系安全和穩固的基礎

計算生態的運用

刀耕火種 -> 站在巨人的肩膀上

  • 程式設計的起點不是演算法而是系統
  • 程式設計如同搭積木,利用計算生態為主要模式
  • 程式設計的目標是快速解決問題

計算生態

2.3 使用者體驗與軟體產品

  • 使用者體驗

    實現功能 -> 關注體驗

    • 使用者體驗指使用者對產品建立的主觀感受和認識
    • 關心功能實現,更要關心使用者體驗,才能做出好產品
    • 程式設計只是手段,不是目的,程式最終為人類服務
  • 提高使用者體驗的方法

    方法1:進度展示

    • 如果程式需要計算時間,可能產生等待,請增加進度展示
    • 如果程式有若干步驟,需要提示使用者,請增加進度展示
    • 如果程式可能存在大量次數的迴圈,請增加進度展示

    方法2:異常處理

    • 當獲得使用者輸入,對合規性需要檢查,需要異常處理
    • 當讀寫檔案時,對結果進行判斷,需要異常處理
    • 當進行輸入輸出時,對運算結果進行判斷,需要異常處理

    其他類方法

    • 列印輸出:特定位置,輸出程式執行的過程資訊
    • 日誌檔案:對程式異常及使用者使用進行定期記錄
    • 幫助資訊:給使用者多種方式提供幫助資訊
  • 軟體程式 -> 軟體產品

    使用者體驗是程式到產品的關鍵環節

2.4 基本的程式設計模式

  • 從IPO開始…

    • I:Input 輸入,程式的輸入
    • P:Process 處理,程式的主要邏輯
    • O:Output 輸出,程式的輸出
    • 確定IPO:明確計算部分及功能邊界
    • 編寫程式:將計算求解的設計變成現實
    • 除錯程式:確保程式按照正確邏輯能夠正確執行
  • 自頂向下設計

    • I:Input 輸入,程式的輸入
    • P:Process 處理,程式的主要邏輯
    • O:Output 輸出,程式的輸出
  • 模組化設計

    • 通過函式或物件封裝將程式劃分為模組及模組間的表達
    • 具體包括:主程式、子程式和子程式間關係
    • 分而治之:一種分而治之、分層抽象、體系化的設計思想
    • 緊耦合:兩個部分之間交流很多,無法獨立存在
    • 鬆耦合:兩個部分之間交流較少,可以獨立存在
    • 模組內部緊耦合、模組之間鬆耦合
  • 配置化設計

    image

    • 引擎+配置:程式執行和配置分離,將可選引數配置化
    • 將程式開發變成配置檔案編寫,擴充套件功能而不修改程式
    • 關鍵在於介面設計,清晰明瞭、靈活可擴充套件

2.5 應用開發的四個步驟

image

  • 1 產品定義:對應用需求充分理解和明確定義

    產品定義,而不僅是功能定義,要考慮商業模式

  • 2 系統架構:以系統方式思考產品的技術實現

    系統架構,關注資料流、模組化、體系架構

  • 3 設計與實現:結合架構完成關鍵設計及系統實現

    結合可擴充套件性、靈活性等進行設計優化

  • 4 使用者體驗:從使用者角度思考應用效果

    使用者至上,體驗優先,以使用者為中心

三、Python第三方庫安裝

  • 看見更大的Python世界
  • 第三方庫的pip安裝方法
  • 第三方庫的整合安裝方法
  • 第三方庫的檔案安裝方法

3.1 看見更大的Python世界

3.1.1 Python社群
  • PyPI: Python Package Index
  • PSF維護的展示全球Python計算生態的主站
  • 學會檢索並利用PyPI,找到合適的第三方庫開發程式

三種方法

  • 方法1(主要方法): 使用pip命令
  • 方法2: 整合安裝方法
  • 方法3: 檔案安裝方法

3.2 第三方庫的pip安裝方法

#安裝指定的第三方庫
pip install <第三方庫名>

#使用-U標籤更新已安裝的指定第三方庫
pip install –U <第三方庫名>    

#解除安裝指定的第三方庫
pip uninstall <第三方庫名>

#下載但不安裝指定的第三方庫
pip download <第三方庫名>

#列出某個指定第三方庫的詳細資訊
pip show <第三方庫名>

#根據關鍵詞在名稱和介紹中搜索第三方庫
pip search <關鍵詞>

#列出當前系統已經安裝的第三方庫
pip list

主要方法,適合99%以上情況

  • 適合Windows、Mac和Linux等作業系統
  • 未來獲取第三方庫的方式,目前的主要方式
  • 適合99%以上情況,需要聯網安裝

3.3 第三方庫的整合安裝方法

整合安裝:結合特定Python開發工具的批量安裝

  • 支援近800個第三方庫
  • 包含多個主流工具
  • 適合資料計算領域開發

3.4 第三方庫的檔案安裝方法

為什麼有些第三方庫用pip可以下載,但無法安裝?

  • 某些第三方庫pip下載後,需要編譯再安裝
  • 如果作業系統沒有編譯環境,則能下載但不能安裝
例項:安裝wordcloud庫
- 步驟1:在UCI頁面上搜索wordcloud
- 步驟2:下載對應版本的檔案
- 步驟3:使用pip install <檔名>安裝