第8周文件和数据的格式和处理-Python语言程序设计(学习笔记
文章原创,最近更新:2018-05-4
1.课前复习
2.实例13:体育竞技分析
3.python程序设计思维
4.python第三方库安装
5.所有的代码汇总
原链接 语言程序设计北京理工大学
1.课前复习
2.实例13:体育竞技分析
2.1"体育竞技分析"问题分析
以上就是体育竞技分析问题.
如何用计算机分析体育竞技的问题呢?简单的说,在计算机领域里,强调一种思维叫计算思维,要求用抽象和自动化的计算思维分析问题.可以模拟不同的选手在n场不同的赛场的结果.去预测最终的胜负结果.
抽象出通用的比赛的规则,以下比赛规则,对羽毛球,乒乓球,网球都有对应的规则.
1.2自顶向下和自底向上
简单的说,是将一个复杂的大问题,通过几个层次的分解,变成若干个非常明确可以解决的小问题.以及小问题之间的相互关系.这样的分析方法就叫自顶向下.
自顶向下是一种程序设计,简称自顶向下设计.自顶向下也可以运用在任何的领域.以改善居住条件这样的大问题,来举一个例子:
怎么改善居住条件呢?
-
修马路,种树,盖楼,这是第一步将改善条件分解成了一个具体的问题.
-
种树很好解决,那怎么盖楼呢?进一步将盖楼变成一个问题.针对盖楼这件事,我们思考要将楼要盖在什么样的位置上,进一步组织楼的设计和施工,在这个阶段,楼房的基本设计方式就有了.
-
下一步中盖楼有建筑工人,有建筑材料,有相关的组织和监理.进一步分解下去,会完成盖楼的动作.
自顶向下从改善需求到每一步的实施,形成了不同的分解链条.这就是自顶向下设计的过程.
与自定向下对应,有自底向上的执行.它指的是逐步组建复杂系统,并且能够进行有效测试的方法.
简单的说,对一个软件系统,我们对每一个单元进行分单元测试,并将测试好的单元进行组合,再进行测试,再组合,再进行测试,逐步组装成复杂系统.
按照自顶下先的相反方向进行操作,直到系统的各部分与组装的思想,经过测试和验证,变成系统有效的部分结果.
以改善居住条件为例,具体实施每个操作环节的时候,比如采购到了建筑材料,有建筑工人对相关的楼进行建造,建造之后要单独的对楼进行测试,对开发模块进行整合和测试,最终形成了一栋大楼.这个大楼是一栋移动楼,对每个区域的大楼都是以这样的方式构造出来.就形成了一个环境的整体改善,进一步改善了我们的居住条件.
1.3"体育竞技分析"实例讲解
体育竞技分析问题是根据球员的不同能力值模拟n场比赛,并且分析获胜次数的一个过程.
- 打印程序的介绍性信息:程序运行后,有介绍性信息,会给用户带来更好的体验.并且让用户知道程序的作用.
- 获得程序运行参数:从用户那里获得运动员A和运动员B的能力值,以及模拟比赛的场次数量.
- 利用球员A和B的能力值,模拟n局比赛.
- 输出球员A和B获胜比赛的场次及概率.
这四个步骤可以分别对应4个函数,这4个函数是根据步骤定义出来的.
这4个函数是我们的自定义函数,那么程序的总体框架与这四个函数就构成了第一阶段的关系.
简单的说将体育竞技分析问题,看成是主函数main(),将这个函数分成了4个步骤,分别对应了4个子函数.这是第一阶段自顶向下的分解,可以将这样的组合形成一段代码.
首先,形成main()函数,在这里将main()函数程序执行之后的步骤.
-
第一步先调用printIntro(),打印调用信息.
-
第二步将probA,probB,n获得球员A,B的能力值,以及模拟的场数N.这里调用的是getInputs()函数.
-
第三步调用simNGames()函数,将获得的参数输入到参数中,获得A跟B的比赛场次.
-
第四步用printSummary()函数将获得比赛场次结果打印出来.
第一阶段通过main函数的分解,设计了4个函数,将一个体育竞技分析问题,变成了一系列的操作,这样的分解是相对模块化的分解,任何编写程序的人都可以在这个层次理解这样的设计,接下来看一下每个函数是否可以逐一实现它?
首先看到的是printIntro()函数,无非是打印介绍内容的函数.提高用户体验.
打印介绍性内容,提高用户体验.
将用户的输入转换为数字,用a,b,n分别返回一个元组类型对应三个输入.
A,B获胜的场次之和,就是总的获胜场次.A获胜的概率是A获胜的场次/总的获胜场次.同理B.这个函数的实现也非常简单.
这一函数相对比较难点,步骤3是重点.
-
方法
-
模拟n次比赛获得的结果,相当于n次模拟1局比赛.这一步将模拟n局比赛当成是一个总问题,将它分解,分解成一个新的问题,模拟一局比赛,并且循环n次.
-
可以构造模拟一局比赛的函数叫simoneGame(),只要获得选手A和选手B的能力值,并且返回这一局比赛他们分数就可以了.
-
模拟n次比赛需要调用n次模拟1局比赛,然后将这样的结果进行整合.
-
-
步骤:
-
首先设置A,B获胜场次变量,winsA,winsB,然后用for i in range(n)来循环n次.每次调用simoneGame()函数来调用一场比赛.
-
模拟之后在一场中,如果A的分数大于B的分数,A的获胜次数+1,否则B的获胜次数+1.就可以获得模拟n次比赛的效果.
-
在竞技比赛中,如果一方获得15分,那么这局比赛结束.每次A,B进行比较的时候,只要分数超过特定的值,就能判断比赛结束.
在模拟一场的比赛当中,进一步分析一局比赛的功能模块.我们这里定义一个函数叫gameover(),是判断一局比赛结束的标准.
简单的说我们又将模拟一局比赛当成一次大问题,进一步分析,判断比赛结束这件事可以封装成一个小模块,它是一个独立的问题.
- 方法分析:
-
在模拟比赛中,双方根据能力值,互相得分.到底进行了多少个回合呢?我们也无法计算,所以使用while循环.
-
在判断条件中,只要当前的循环不结,那么选手就要进行一定的相关操作,从而使用了while not gameover()
-
比赛不结束的情况下,我们进行如下操作:
- 步骤:
- serving表示选手A先发球.
- 如果选手A先发球,用random()函数随机生成一个变量.如果这个变量在A能力的范围之内,A获得一分,用这样的方式随机表达A能力与A获得分数直接的关系.
- 如果随机函数超出了A能力的范围,我们认为当前的发球局B换为B,那么serving就会变成B.
- 同理B,用随机函数判断B能力的范围,这局判断A赢了还是B赢了.
- 最终我们将一局比赛当gameover()之后的当前分数返回这个函数的调用函数
- gameover()这个函数应该怎么判断呢?gameover()是当前A和B球员当前的分数,如果A或B的分数等于15分,那么比赛就结束了.那么就可以return A=15 or B=15.
通过第三阶段的分析,已经能够模拟一场比赛可以判断gameover这样的条件用程序进行明确的表达.
回顾程序:
体育竞技分析问题,可以分为四个步骤来表达,打印信息,获得用户输入,模拟n场比赛,打印输出.
模拟n场比赛可以进一步分解成模拟一场比赛,模拟一场比赛可以进一步分解成判断比赛结束条件,其他部分可以用程序来完成.
可以将体育竞技这样的大问题,逐步分成一个又一个的确定的,可以用程序表达的功能模块,这就是自顶向下设计.
假设A的能力值是0.45,B的能力值是0.50,相差只有0.05的能力
能力相差0.05,那么胜负的能力是否也相差那么多呢?
体育竞技分析反应非常深刻的道理,当两个人在竞争某个问题的时候,两个人或许只有微小的差距,竞争的结果会有非常大的悬殊的不同.
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 simNGgmes(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
def main():
printIntro()
probA,probB,n=getInputs()
winsA,winsB=simNGgmes(n,probA,probB)
printSummary(winsA,winsB)
main()
1.4"体育竞技分析"举一反三
在工程开发或者设计当中,有系统思维非常重要,自顶向下就是系统思维的一种体现.
2.python程序设计思维
2.1单元开篇
2.2计算思维与程序设计
从以上例子可以看出,逻辑思维注重数学推理,形成公式获得结果.而计算思维更多是模拟计算的过程,无论是模拟求和,还是汉诺塔的递归,还是模拟圆周率的撒点,用计算机来完成大量的运算.
这些都是小例子,我们看一下庞大的数据.
现在的气象部门利用超级计算机来演算出未来的天气情况.演算天气需要一个模型,MM5模型,将地球分割成很小的区域,根据布局在地球上的传感器,采集每个区域的温度以及气象的变化和数值,将数据输入到计算机当中,经过迭代,和数学的演算,去预测未来按照这样的天气,后面产生小区域的天气状况.这是计算思维.
量化分析师股市非常常用的一种办法.中国的股市以及美国的股市60%的交易都是由计算机完成的.
计算思维非常有用.
2.3计算生态与python语言
自由软件指的是软件产品不再像工业产品一样,通过商业来分发和销售,通过互联网和免费的拷贝和使用,来进行分发,让更多人能用得起和用得上软件.
从1991年到1998年,开源是个普遍的方式.
- 大教堂模式:认为软件是高大上的,软件应该是由精英开发,提供用户使用的.
- 集市模式:任何人都可以贡献开发的,贡献之后这个软件服务于大众.是开源运动的主要模式.
以早年的爬虫为例,就有很多爬虫的库.
更种库有竞争发展的压力,库之间是互相关联,依存发展.比如数据分析的numpy,在处理大数据的时候,可以达到C语言达到相当的效率,numpy的底层就是C语言编写的,而接口是python语言,而numpy搭建好了非常高效的处理能力,像pandas等库是基于numpy编写的上层功能.在python语言了,库之间的相互依存非常普遍.
API是应用程序接口,与生态是不同的.API是通过一个人或一个组织顶层设计而成的.API是经过设计的产物,不是野蛮生产发展出来的产物,它与生态并不相同.
2.4用户体验与及软件产品
可以用进度条的展示,让用户跟程序建立链接.
学会了异常处理,捕获异常情况.
输入输出计算时,除数是否为0.
2.5基本的程序设计模式
一个复杂的问题,分解成若干个简单的问题,简单的问题可以进一步分解成更加简单的问题.直到所有的小模块确定的完成.这就是自顶向下的设计.
自动轨迹绘制,将数据与程序分离开,功能部分是以程序引擎的方式实现,而具体的轨迹是以数据配置的文件来实现.这样就把一个程序变成程序引擎+配置文件的方式.这就是配置化设计,
关键在于设计接口,接口是否清晰明了,可扩展,这是更高级别的思路.
并且要考虑优化设计,使整体的功能实现变成非常合理,高效
2.6单元小结
3.python第三方库安装
3.1单元开篇
这一小节可以学到任何第三方库的的安装和使用.
3.2看见更大的python世界
python社区:网址是https://pypi.org/
在这里可以搜索任何主题的第三方库.
blockchain是区块链的英文名称.
3.3第三方库的pip安装方法
这个命令行是操作系统的命令行,而不是IDLE之间的交互环境.
pip -h 可以打印出命令的帮助信息.
比如pip search blockchain
3.4第三方库的集成安装方法
3.5第三方库的文件安装方法
以下的截图是回答:可以直接下载编译后的版本用于安装吗?
http://www.lfd.uci.edu/~gohlke/pythonlibs/
这个网页是由加州大学一名教授维护的网页,在windows操作系统上,一批可以下载但需要编译再安装的第三方库直接编译后的版本.
如果用pip安装第三方库,可以完整下载,但是操作系统不具备编译环境,可以用这样的网页提供的信息来安装第三方库.
3.6单元小结
4.所有的代码汇总
#MatchAnalysis.py
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 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 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 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 main():
printIntro()
probA, probB, n = getInputs()
winsA, winsB = simNGames(n, probA, probB)
printSummary(winsA, winsB)
main()