Python初学16——程序设计方法学

目录

一、计算思维(设计、构造)

二、计算生态(第三方库)

三、用户体验(进度展示、异常处理、其他)

四、基本的程序设计模式(IPO、自顶向下设计、模块化、配置化)

五、“体育竞技分析”实例


一、计算思维(设计、构造)

  • 逻辑思维:推理、公式和演绎
  • 实证思维:实验和验证
  • 计算思维:设计和构造。抽象问题的计算过程(设计),计算机自动化求解(编程)

二、计算生态(第三方库)

  • 1983,Richard Stallman启动GNU项目
  • 1989,GNU通过许可协议诞生,自由软件时代到来
  • 1991,Linus Torvalds发布Linux内核
  • 1998,网景浏览器开源,产生了Mozilla,开源生态逐步建立
  • ……

计算生态以开源项目为组织形式,利用“公式原则”和“社会利他”组织人员,在竞争发展、互相依存和迅速更迭中完成信息技术的更新换代,形成了技术的自我演化路径。

各界人士为Python语言提供了大量的第三方库,这些库之间有依存关系,并在迅速更迭;同一功能下,Python语言有两个以上的第三方库,这些库之间存在竞争关系。

推荐优质计算生态第三方库网站:https://python123.io

三、用户体验(进度展示、异常处理、其他)

  • 进度展示
  1. 程序运行需要长的计算时间
  2. 程序有若干步骤并需要提示用户
  3. 程序存在大量次数的循环
  • 异常处理
  1. 用户输入的合规性检查
  2. 读写文件结果的合规性检查
  3. 输入输出的运算结果的合规性检查
  • 其他
  1. 打印输出:打印程序运行的过程信息
  2. 日志文件:记录程序异常和用户使用
  3. 帮助信息:给用户提供帮助信息

应用开发四步骤:

  1. 产品定义:定义应用需求,包括产品的功能定义和商业模式等
  2. 系统架构:系统思考产品的技术实现,包括数据流、模块化、体系结构等
  3. 设计实现:完成关键设计及系统实现,包括灵活可扩展、优化等
  4. 用户体验:用户至上,体验优先

四、基本的程序设计模式(IPO、自顶向下设计、模块化、配置化)

  • IPO
  1. I:Input输入
  2. P:Process处理
  3. O:Output输出
  • 自顶向下设计
  • 模块化设计
  1. 模块内紧耦合:信息交流多,无法独立存在
  2. 模块间松耦合:信息交流少,可以独立存在
  • 配置化设计
  1. 程序引擎:功能实现部分
  2. 配置文件:具体的处理数据部分
  3. 接口:引擎与配置之间的接口清晰明了、灵活可扩展

五、“体育竞技分析”实例

需求:“高手过招,胜负只在毫厘之间”,如何科学分析体育竞技比赛?

方法:抽象比赛过程,自动化执行N场比赛(N越大,结果分析越科学)

比赛规则:1. 一对一,一场比赛5局3胜

                  2. 开始时一方先发球直至判分,接下来胜者发球

                  3. 球员只能在自己发球局中打赢才得分(在自己发球局中打输不得分不输分),15分胜一局

基本思路:1. 打印程序的介绍信息 printIntro()

                  2. 获得用户输入的两个球员能力值和模拟场次 getInputs()

                  3. 程序计算,模拟比赛 simNGames()

                          1. 循环N场比赛

                          2. 完成1场比赛 simOneGame()

                  4. 打印两个球员获胜比赛的场次和概率 printSummary()

import random, time
'''
    功能:  打印程序的介绍信息
    参数:  无
    返回值:无
'''
def printIntro():
    print("{:-^55}".format("本程序依据球员的能力值来模拟两个球员A和B之间的竞技比赛"))
    print("比赛规则如下:")
    print("1. 一对一,一场比赛5局3胜")
    print("2. 开始时一方先发球直至判分,接下来胜者发球")
    print("3. 球员只能在自己发球局中打赢才得分(在自己发球局中打输不得分不输分),15分胜一局")
    print("{:-^81}".format("-"))



'''
    功能:  获取用户输入的球员能力值和模拟场次数
    参数:  无
    返回值:球员A的能力值,球员B的能力值,模拟场次数
'''
def getInputs():
    A = eval(input("请输入球员A的能力值(0~1小数表示):"))
    B = eval(input("请输入球员B的能力值(0~1小数表示):"))
    N = eval(input("请输入模拟比赛的场次数:"))
    if 0<=A<=1 and 0<=B<=1 and N>=0:
        return A, B, N
    else:
        print("输入的数据有误!")
        return None



'''
    功能:  打印模拟竞技结果
    参数:  winsA:球员A的获胜场次
            winsB:球员B的获胜场次
    返回值:无
'''
def printSummary(winsA, winsB):
    n = winsA + winsB
    print("竞技分析结束,共模拟{}场比赛".format(n))
    print("球员A获胜{}场比赛,占比{:.2%}".format(winsA, winsA/n))
    print("球员B获胜{}场比赛,占比{:.2%}".format(winsB, winsB/n))



'''
    功能:  模拟1场比赛(1场=5局3胜)
    参数:  probA:球员A的能力值
            probB:球员B的能力值
    返回值:本场比赛胜出的选手"A"或"B"
'''
def simOneGame(probA, probB):
    game = {'A本场中胜利局数':0, 'B本场中胜利局数':0}  # 1场中两个球员胜利的局数
    score = {'A本局中的分数':0, 'B本局中的分数':0}    # 1局中两个球员的分数
    start = "A"                                     # 当次首发球手
    # 判断是否有球手本场比赛胜出
    while( game.get('A本场中胜利局数') != 3 and game.get('B本场中胜利局数') != 3 ):
        # 判断球员当次的分数,进行局数结算或继续本局比赛
        if score.get('A本局中的分数') == 15 or score.get('B本局中的分数') == 15:
            if score.get('A本局中的分数') == 15:
                game['A本场中胜利局数'] = game.get('A本场中胜利局数') + 1
            else:
                game['B本场中胜利局数'] = game.get('B本场中胜利局数') + 1
            score['A本局中的分数'] = 0
            score['B本局中的分数'] = 0
            continue
        # 继续进行本局比赛,进行本次分数结算
        if start == "A": # 当次A首发
            if random.random() < probA:
                score['A本局中的分数'] = score.get('A本局中的分数') + 1
            else: # A首发A输球,下一次B首发
                start = "B"
            continue
        else:           # 当次B首发
            if random.random() < probB:
                score['B本局中的分数'] = score.get('B本局中的分数') + 1
            else: # B首发B输球,下一次A首发
                start = "A"
            continue
    # 返回本场比赛胜出的选手
    if game.get('A本场中胜利局数') == 3:
        return "A"
    else:
        return "B"



'''
    功能:  模拟N场比赛
    参数:  probA:球员A的能力值
            probB:球员B的能力值
            N:模拟比赛场次
    返回值:winsA:球员A的获胜场次
            winsB:球员B的获胜场次
'''
def simNGames(probA, probB, N):
    winsA, winsB = 0, 0 # 两个球员胜利的总场数
    print("竞技分析开始")
    print("----")
    startTime = time.perf_counter()
    for i in range(N):  # 循环N场比赛
        # 进行1场比赛
        Player = simOneGame(probA, probB)
        # 胜利场次结算
        if Player == "A":
            winsA += 1
        else:
            winsB += 1
    print("模拟耗时{:.3f}秒".format(time.perf_counter()-startTime))
    return winsA, winsB



def main():
    printIntro()                               # 打印程序的介绍信息
    grobA, grobB, N = getInputs()              # 获取用户输入的球员能力值和模拟场次数
    winsA, winsB = simNGames(grobA, grobB, N)  # 模拟N场比赛
    printSummary(winsA, winsB)                 # 打印模拟竞技结果
main()
图5-1

总结:

  • 自顶向下设计
  1. 将总问题划分成若干个小问题的组合
  2. 进一步对各个小问题分析成更小的问题
  3. 直到最后的问题可以被计算机简单明了的解决
  • 自底向上执行
  1. 分单元模块测试
  2. 按照自顶向下相反的路径逐步组装测试
  3. 直到最后总问题的各部分都是测试验证通过的
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

觅道無涯-千知

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值