程序设计方法学
Python程序设计思维
计算思维与程序设计
计算思维
第三种人类思维的特征
-
逻辑思维:推理和演绎,以数学为代表。如:A→B,B→C,则有A→C。
-
实证思维:实验和验证,物理为代表。如:物理学家提出引力波的概念,但需要大量实验来验证引力波的存在。
-
计算思维:设计和构造,计算机为代表。如:汉诺塔递归。
抽象和自动化
-
计算思维:Computation Thinking。
-
抽象问题的计算过程,利用计算机自动化求解。
-
计算思维是基于计算机的计算方式。
抽象问题的计算过程,利用计算机自动化求解
-
计算思维基于计算机强大的算例及海量数据
-
抽象计算过程,关注设计和构造,而非因果
-
以计算机程序设计为主要实现手段
编程是将计算思维变成现实的手段
天气预报:
原先,我们来靠实证思维和逻辑思维来猜后面的天气。
现在,计算机有MM5@超算模型,这个模型把地球化成好多方块,分成一格一格的,把天气模型按照以前的顺序往后面推。
量化思维:
以前,不用计算机的时候,分析股票涨跌,根据经验,往后判断涨跌。这是实证思维和逻辑思维。
现在,有计算机时,通过机器学习的方式,预测未来涨跌,利用计算机完成未来交易。
程序设计
示例一:求1+2+…+100的和
数学思维:高斯小时候这样弄:1+100=101,2+99=101,……这样的循环有50次,则有:首项加末项,然后乘项数除以二。
计算思维呢?用Python语言来做,此项代码可以写为:
s = 0
for i in range(1, 100):
s += i
这是计算思维,是现代人的方法。
示例二:求圆周率的计算
数学思维:利用计算圆周率的公式
计算思维:我们用正方形,中间画一个内切圆,用random()方式向整个正方形撒很多点,最后用点迹,大约计算出π的大小。
示例三:汉诺塔问题
数学思维:利用推导公式 2^n - 1
计算思维:一个个放,不断尝试
count = 0
def hanoi(n, src, dst, mid):
global count
if n == 1:
print("{}:{}->{}".format(1,src,dst))
count += 1
else:
hanoi(n-1, src, mid, dst)
print("{}:{}->{}".format(n,src,dst))
count += 1
hanoi(n-1, mid, dst, src)
>>> hanoi(3, "A", "C", "B")
>>> print(count)
1:A->C
2:A->B
1:C->B
3:A->C
1:B->A
2:B->C
1:A->C
7
计算生态与Python语言
计算生态的应用
刀耕火种 变为 站在巨人的肩膀上
-
编程的起点不是算法而是系统
-
编程如同搭积木,利用生态计算为主要模式
-
编程目标是快速解决问题
优质的计算生态学习网站
用户体验与软件产品
用户体验是软件程序到软件产品的关键环节
软件程序 → 软件产品
程序设计模式
从IPO开始…
首先确定IPO,明确计算功能和功能边界;
然后编写程序,将计算求解的设计变成现实;
最后调试程序,确保程序按照正确逻辑能够正确运行。
-
I:Input 输入,程序的输入
-
P:Process 处理,程序的主要逻辑
-
O:Output 输出,程序的输出
基本的程序设计模式
模块化设计
通过函数封装或对象封装程序划分为模块间的表达
具体包括:主程序,子程序和子程序间关系
分而治之:一种分而治之、分层抽象、体系化的设计思想
-
紧耦合:两个部分之间交流很多,无法独立存在
-
松耦合:两个部分之间交流较少,可以独立存在
-
模块内部紧耦合,模块之间松耦合
配置化设计
-
引擎+配置:程序执行 和 配置分离,将可选参数配置化
-
将程序开发变成配置文件编写,扩展功能 而不修改程序
-
关键在于接口设计,清晰明了、灵活性可靠
应用开发的四个步骤
从应用需求到软件产品
-
产品定义:对应用需求充分理解和明确定义
产品定义,而不仅是功能定义,要考虑商业模式
-
系统架构:以系统方式思考产品的技术实现
系统架构,关注数据流,模块化、体系结构
-
设计与实现:结合架构完成关键设计及系统实现
结合可扩展性、灵活性等进行设计优化
-
用户体验:从用户角度思考应用效果
用户至上,体验优先,以用户为中心
体育竞技分析
程序设计方法
自顶向下设计
解决复杂问题的有效方法
- 将一个总问题表达为若干个小问题组成的形式
- 使用同样方法进一步分解小问题
- 直至,小问题可以用计算机简单明了的解决
自底向上设计
逐步组建复杂系统的有效测试方法
- 分单元测试,逐步组装
- 按找自顶向下相反的路径操作
- 直至,系统各部分以组装的思路都经过测试和验证
问题分析
失之毫厘,谬之千里
- 需求:毫厘是多少?如何科学分析体育竞技比赛?
- 输入:球员的水平
- 输出:可预测的比赛成绩
如何实现
模拟N场比赛
- 计算思维:抽象+自动化
- 模拟:抽象比赛过程+自动化执行N场比赛
- 当N越大时,比赛结果分析会越科学
抽象一种比赛规则
- 双人击球比赛:A&B,回合制,5局3胜
- 开始时一方先发球,直至判分,接下来胜者发球
- 球员只能在发球局得分,15分胜一局
程序总体框架及步骤
- 步骤1:打印程序的介绍性信息式
- 步骤2:获得程序运行参数 (球员A、B的能力,进行了多少场比赛)
- 步骤3:利用球员A和B的能力值,模拟n局比赛
- 步骤4:输出球员A和B获胜比赛的场次及概率
- 每个步骤可定义一个函数依次为printInfo()、getInputs()、simNGames()、printSummary()
实例解析
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 gameOver(a,b): #得满15分获胜,跳出循环
return a==15 or b==15
def simOneGame(probA,probB):
scoreA,scoreB=0,0
serving="A" #设定每场比赛总是球员A先发球
while not gameOver(scoreA,scoreB):
if serving=="A":
if random()<probA: #random()生成随机小数
scoreA+=1
else:
serving="B"
else:
if random()<probB:
scoreB+=1.
else:
serving="A"
return scoreA,scoreB
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 main():
printIntro()
probA,probB,n=getInputs()
winsA,winsB=simNGames(n,probA,probB)
printSummary(winsA,winsB)
main()
举一反三
- 扩展比赛参数,增加对更多能力对比情况的判断
- 扩展比赛设计,增加对真实比赛结果的预测
- 扩展分析逻辑,反向推理,用胜率推算能力?