- 需求:毫厘是多少?如何科学分析体育竞技比赛?
- 输入:球员的水平
- 输出:可预测的比赛成绩
- 计算思维:抽象+自动化
- 模拟:抽象比赛过程+自动化执行N场比赛
- 当N越大时,比赛结果分析会越科学
- 双人击球比赛:A&B,回合制,5局3胜
- 开始时一方先发球,直至判分,接下来胜者发球
- 球员只能在发球局得分,15分胜一局
- 步骤1:打印程序的介绍性信息式
printInfo()
- 步骤2:获得程序运行参数:proA,proB,n
getInputs
- 步骤3:利用球员A和B的能力值,模拟n局比赛
simNGames
- 步骤4:输出球员A和B获胜比赛的场次及概率
printSummary()
def main():
printIntro()
probA,probB,n=getInputs()
winsA,winsB=simNGames(n,probA,probB)
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))
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="A"
return scoreA,scoreB
def gameOver(a,b):
return a==15 or b==15
#代码如下:
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):
return a==15 or b==15
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 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()
#输出结果
这个程序模拟两个选手A和B的某种竞技比赛
程序运行需要A和B的能力值(以0到1之间的小数表示)
请输入选手A的能力值(0-1):0.45
请输入选手B的能力值(0-1):0.50
模拟比赛的场次:100
竞技分析开始,共模拟100场比赛
选手A获胜35场比赛,占比35.0%
选手B获胜65场比赛,占比65.0%
>>>
- 理解自顶向下的设计思维:分而治之
- 理解自底向上的执行思维:模块化集成
- 扩展比赛参数,增加对更多能力对比情况的判断
- 扩展比赛设计,增加对真实比赛结果的预测
-扩展分析逻辑,反向推理,用胜率推算能力?
- 逻辑思维:推理和演绎,数学为代表,A → \rightarrow →B B → \rightarrow →C A → \rightarrow →C
- 实证思维:实验和验证,物理为代表,引力波 ← \leftarrow ←实验
- 计算思维:设计和构造,计算机为代表,汉诺塔递归
- 计算思维:Computational Thinking
- 抽象问题的计算过程,利用计算机自动化求解
- 计算思维是基于计算机的思维方式
- S = ( a 1 + a n ) n 2 S=\frac{(a_1+a_n)n}{2} S=2(a1+an)n逻辑思维(数学家高斯的玩法)
#计算思维(现代人玩法)
s=0
for i in range(1,101):
s+=i
#计算思维
count=0
def hanoi(n,src,dst,mid):
...(略)
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
- 之前(实证思维+逻辑思维):经验+猜
- 现在(计算思维):MM5模型@超算
- 计算思维基于计算机强大的算力及海量数据
- 抽象计算过程,关注设计和构造,而非因果
- 以计算机程序设计为实现的主要手段
- 1983,Richard Stallman启动GNU项目 (大教堂模式)
- 1989,GNU通用许可协议诞生,自由软件时代到来
- 1991,Linus Torvalds发布了Linux内核 (集市模式)
- 1998,网景浏览器开源,产生了Mozilla,开源生态逐步建立
- 计算生态以开源项目为组织形式,充分利用"共识原则"和"社会利他"组织人员,在竞争发展,相互依存和迅速更迭中完成信息技术的更新换代,形成了技术的自我演化路径。
- 竞争发展
- 相互依存
- 迅速更迭
- 以开源项目为代表的大量第三方库
Python语言提供 > 13万个第三方库- 库的建设经过野蛮生长和自然选择
同一个功能,Python语言2个以上第三方库- 库之间相互关联使用,依存发展
Python库间广泛联系,逐级封装- 社区庞大,新技术更迭迅速
AlphaGo深度学习算法采用Python语言开源API ! = 生态
- 加速科技类应用创新的重要支撑
- 发展科技产品商业价值的重要模式
- 国家科技体系安全和稳固的基础
- 编程的起点不是算法而是系统
- 编程如同搭积木,利用计算生态为主要模式
- 编程的目的是快速解决问题
h t t p : / / p y t h o n 123. i o http://python123.io http://python123.io
- 用户体验指用户对产品建立的主观感受和认识
- 关心功能实现,更要关心用户体验,才能做出好产品
- 编程只是手段,不是目的,程序最终为人类服务
- 如果程序需要计算时间,可能产生等待,请增加进度展示
- 如果程序有若干步骤,需要提示用户,请增加进度展示
- 如果程序可能存在大量次数的循环,请增加进度展示
- 当获得用户输入,对合规性需要检查,需要异常处理
- 当读写文件时,对结果进行判断,需要异常处理
- 当进行输入输出时,对运算结果进行判断,需要异常处理
- 打印输出:特定位置,输出程序运行的过程信息
-日志文件:对程序异常及用户使用进行定期记录- 帮助信息:给用户多种方式提供帮助信息
- 用户体验是程序到产品的关键环节
- 确定IPO:明确计算部分及功能边界
- 编写程序:将计算求解的设计变成现实
- 调试程序:确保程序按照正确逻辑能够正确运行
- 通过函数或对象封装将程序划分为模块及模块间的表达
具体包括:主程序,子程序和子程序间关系
分而治之:一种分而治之,分层抽象,体系化的设计思想- 紧耦合:两个部分之间交流很多,无法独立存在
- 松耦合:两个部分之间交流较少,可以独立存在
- 模块内部紧耦合,模块之间松耦合
- 程序引擎+配置文件
- 引擎+配置:程序执行和配置分离,将可选参数配置化
- 将程序开发变成配置文件编写,扩展功能而不修改程序
- 关键在于接口设计,清晰明了,灵活可扩展
- 1 产品定义:对应用需求充分理解和明确定义
产品定义,而不仅是功能定义,要考虑商业模式- 2 系统架构:以系统方式思考产品的技术实现
系统架构,关注数据流,模块化,体系架构- 3 设计与实现:结合架构完成关键设计及系统实现
结合可扩展性,灵活性等进行设计优化- 4 用户体验:从用户角度思考应用效果
用户至上,体验优先,以用户为中心
https://pypi.org/
PyPI
PyPI:Python Package Index
- PSF维护的维护的展示全球Python计算生态的主站
- 学会检索利用PyPI,找到合适的第三方库开发程序
- 第1步:在pypi.org搜索blockchain
- 第2步:挑选适合开发目标的第三方库作为基础
- 第3步:完成自己需要的功能
- 方法1(主要方法):使用pip命令
- 方法2:集成安装方法
- 方法3:文件安装方法
D:\>pip -h
Usage:
pip <command> [options]
Commands:
install Install packages.
download Download packages.
uninstal Uninstall packages.
freeze Output installed packages in requirements format.
list List installed packages.
show Show information about installed packages
check Verify installed packages have compatible dependencies.
search Search PyPI for packages.
wheel Build wheels from your requirements
help Show help for commands
D:\>pip install <第三方库名>
安装指定的第三方库D:\>pip install -U <第三方库名>
使用-U标签更新已安装的指定第三方库D:\>pip uninstall <第三方库名>
卸载指定的第三方库D:\>pip show <第三方库名>
列出某个指定第三方库的详细信息D:\>pip search <关键词>
根据关键词在名称和介绍中搜索第三方库D:\>pip list
列出当前系统已经安装的第三方库
- 适合Windows、Mac和Linux等操作系统
- 未来获取第三方库的方式,目前的主要方式
Anaconda https://www.continuum.io
- 支持近800个第三方库
- 包含多个主流工具
- 适合数据计算领域开发
- 某些第三方库pip下载后,需要编译再安装
- 如果操作系统没有编译环境,则能下载但不能安装
- 可以直接下载编译后的版本用于安装吗?
http://www.lfd.uci.edu/~gohlke/pythonlibs/
- UCI
- 步骤1:在UCI页面上搜索wordcloud
- 步骤2:下载对应版本的文件
- 步骤3:使用pip install <文件名> 安装
- os库是Python标准库、包含几百个函数
- 常用路径操作、进程管理、环境参数等几类
- 路径操作:os.path子库,处理文件路径及信息
- 进程管理:启动系统中其他程序
- 环境参数:获得系统软硬件信息等环境参数
import os.path
import os.path as op
补充:
函数:os.path.getsize(path)
描述:返回path对应文件的大小,以字节为单位
>>>os.path.getsize("D:/PYE/file.txt")
180768
import os
os.system("C:\\Windows\\System32\\calc.exe")
>>>
0
import os
os.system("C:\\Windows\\System32\\mspaint.exe\
D:\\PYECourse\\grwordcloud.png")\
>>>
0
函数:os.getlogin()
描述:获得当前系统登录用户名称
>>>os.getlogin()
'Tian Song'
函数:os.cpu_count()
描述:获得当前系统的CPU数量
>>>os.cpu_count()
8
- 需求:批量安装第三方库需要人工干预,能否自动安装?
- 自动执行pip逐一根据安装需求安装
- 如何自动自行一个程序?例如:pip?
库名:Jieba
用途:中文分词
pip安装指令:pip install jieba
库名:Beautiful Soup
用途:HTML和XML解析器
pip安装指令:pip install beautifulsoup4
库名:Wheel
用途:Python第三方库文件打包工具
pip安装指令:pip install wheel
库名:PyInstaller
用途:打包Python源文件为可执行文件
pip安装指令:pip install pyinstaller
库名:Django
用途:Python最流行的Web开发框架
pip安装指令:pip install django
import os
libs={
"numpy","matplotlib","pillow","sklearn","requests",\
"jieba","beautifulsoup4","wheel","networkx","sympy",\"pyinstaller","django","flask","werobot","pyqt5"\
"pandas","pyopengl","pypdf2","docopt","pygame"}
try:
for lib in libs:
os.system("pip install"+lib)
print("Successful")
expect:
print("Failed Somehow")
- 编写各类自动化运行程序的脚本,调用已有程序
- 扩展应用:安装更多第三方库,增加配置文件
- 扩展异常检测:捕获更多异常类型,程序更稳定友好
第一题 英文字符的鲁棒输入
题目描述:获得用户的任何可能输入,将其中的英文字符进行打印输出,程序不出现错误。
输入示例:*&^123abc0e
输出示例:abce
代码如下:
alpha = []
for i in range(26):
alpha.append(chr(ord('a') + i))
alpha.append(chr(ord('A') + i))
s = input()
for c in s:
if c in alpha:
print(c, end="")
第二题 数字的鲁棒输入
题目描述:获得用户输入的一个数字,可能是浮点数或复数,如果是整数仅接收十进制形式,且只能是数字。对输入数字进行平方运算,输出结果。
题目要求:(1)无论用户输入何种内容,程序无错误;(2)如果输入有误,请输出"输入有误"。
输入示例:1+2j
输出示例:(-3+4j)
输入示例:abd
输出示例:输入有误
代码如下:
s = input()
try:
if complex(s) == complex(eval(s)):
print(eval(s)**2)
except:
print("输入有误")