本周是培训的第三周,新知识点逐渐多了起来,程序的代码量和复杂度远胜之前,不过也能明显的感觉到个人逻辑思维的提升、代码编写愈发的熟练,本周涉及的知识点主要如下所示:
- 函数
-
名字(同变量命名)
-
参数、默认值、可变参数(args, 组装成元组)、关键字参数(kwargs,组装成字典)、命名关键字参数(号后的参数在传参的时候必须有参数名)
-
返回值(单个、多个亦可)
-
嵌套定义(与C、C++等高级编程语言不同,可以在一个函数里定义另一个函数)
-
高阶函数 f(g(x))
-
lambda函数(匿名函数)、【闭包、偏函数、柯里化】
-
decorator - 装饰器 / 包装器(通过装饰器修饰函数,让函数在执行过程中可以做更多额外的操作)
- 类和对象
面向对象三大特性:封装,继承,多态
静态方法与类方法(以判断三角形三条边设置是否合理为例)
- 静态方法
@staticmethod
def is_valid(a, b, c):
return a + b > c and a + c > b and b + c > a - 类方法(消息依旧是发给类 可以用cls做更多的事)
@classmethod
def is_valid(cls, a, b, c):
print(cls)
print(type(cls))
return a + b > c and a + c > b and b + c > a
抽象类的定义
from abc import ABCMeta, abstractclassmethod
class GameObject(object, metaclass=ABCMeta):
def init(self, pos=(0,0), color=BLACK_COLOR):
self._pos = pos
self._color = color
@abstractclassmethod
def draw(self, screen): # 抽象方法,规范子类行为
pass
属性访问器与修改器(以奥特曼打小怪兽中的属性hp为例)
- 属性访问器
@property
def hp(self):
return self._hp
-属性修改器
@hp.setter
def hp(self, hp):
self._hp = hp if hp > 0 else 0
类与类、对象与对象之间的关系
- has-a --> 普通关联 - 聚合(强关联) - 合成(不可分割)(从左到右由弱到强)
- use-a --> 依赖关系
- is-a --> 继承关系
程序设计原则
- 高内聚:函数(类)只做一件事件(单一职责原则)
- 低耦合:代码块之间不能产生强关联关系,不要和特定的运行环境紧密耦合在一起
,迪米特法则(最少知识原则)
面向对象原则
- 单一职责原则(Single Responsibility Principle, SRP)
- 开闭原则(Open Close Principle, OCP)(对扩展开放,对修改关闭)
- 依赖倒置原则(Dependence Inversion Principle, DIP)(模块间的依赖通过抽象发生,实现类之间不发生直接的依赖关系,其依赖关系是通过接口或抽象类产生的)
- 里氏替换原则(Liskov Substitution Principle, LSP)(子类替换父类)
- 接口隔离原则(Interface Segregation Principles, ISP)(接口隔离原则的目的是系统解开耦合,从而容易重构、更改和重新部署 客户端不应该依赖它不需要的接口)
- 合成聚合复用原则(能使用强关联的地方就不要使用继承)
- 迪米特法则(Law of Demeter, LOD)(最少知识原则)
- 异常机制
- 即处理程序在运行过程中出现的意外状况的手段,因为不是所有的问题都能够在写程序调试程序的时候就能发现,代码如下所示:
try:
# 把可能出状况(在执行时有风险)的代码放到try代码块保护起来
pass
except IOError:
# 如果try中出现了状况就通过except来捕获错误(异常)进行对应的处理
print("读写文件发生错误!")
except FileNotFoundError:
# except可以写多个分别用于处理不同的异常状况
pass
else:
# 如果没有出状况那么可以把无风险的代码放到else中执行
pass
finally:
# 不管程序正常还是异常最后这里的代码一定会实现
# 此处是最好的释放外部资源的位置,因为这里的代码总是会执行
pass
- Json
- 即 javascript object notation (js对象表达式 有格式,半结构化的纯文本),用于传输字典、列表数据
json写操作(字典-->字符串)
try:
with open("data.json","w",encoding="utf-8") as fs:
json.dump(mydict, fs) # mydict 为一字典
except IOError as e:
print(e)
json读操作(字符串-->字典)
try:
with open("data.json","r",encoding="utf-8") as fs:
thy_dict = json.load(fs) # 读字典
print(type(thy_dict))
print(thy_dict)
print(thy_dict["name"])
except IOError as e:
print(e)
print("处理结束!")
除了基础知识的讲解,本周侧重运用面向对象的思想来解决实际问题,笔者也在紧跟课堂讲解进度的同时,对练习项目中待解决的问题进行了独立思考,并给出了自己的实现,下面就实现要点简要的做一分享:
1. 21点
要点:
1)玩家先摸牌,计算机后摸牌(计算机分稳健性(超过16分不再摸牌)和鲁莽型(超过18分不再摸牌))
2)每次摸牌前提示是否摸牌,摸牌后自动记录点数并显示牌面
3)最终的结果分为:a. 玩家和计算机的点数和均超过21点,两方均爆,平局
b. 玩家爆了,计算机未爆,计算机胜
c. 计算机爆了,玩家未爆,玩家胜
d. 计算机和玩家都未爆,且玩家的点数和大于计算机,
玩家胜
e. 计算机和玩家都未爆,且玩家的点数和小于计算机,
计算机胜
f. 计算机和玩家都未爆,且玩家的点数和等于计算机,
平局
2. 五子棋
要点:
1)胜负裁决:以最后下的一颗棋子的坐标为基准,通过判断垂直,水平,主对角线,斜对角线四个方向来判断输赢,每个方向读取10颗棋的信息,若有连续5颗及以上为同色棋,则判定为赢。 以水平方向为例,倘若当前的棋子为黑棋,先从右至左依次扫描该棋左边的五颗棋,被扫描的棋子为黑棋,则计数器加一,否则停止扫描。然后从左至右扫描该棋右边的五颗棋,处理方式同上。最终计数器的累计计数大于等于五,则可判定为赢
2)若胜负已分,在屏幕上显示结果,除非开启新局,否则不允许再次下棋:
a) 显示结果:判定为赢后,加入文字显示语句即可,具体如下:
ZiTiDuiXiang = pygame.font.SysFont('SimHei', 32)
WenBenKuangDuiXiang = ZiTiDuiXiang.render("Black win! once again(y/n)" if is_black else "White win! once again(y/n)", True, [0,0,0])
KuangDuiXiang = WenBenKuangDuiXiang.get_rect()
KuangDuiXiang.center = (300, 300)
screen.blit(WenBenKuangDuiXiang, KuangDuiXiang)
pygame.display.update()
b) 开启新局前停止下棋:增加标记flag=1, 置于鼠标单击判断语句处,若胜负已分,则修改flag=0,此时单击鼠标便失效
c) 开启新局或结束游戏:增加按键事件判断,若按下y键,表明重新开局,修改flag = 1,同时重置棋面,如果按下其他键,则修改running = False,停止处理事件库中的事件,并执行到pygame.quit()语句,关闭游戏界面
3. 大球吃小球
要点:
1)吃球操作:增加方法eat(self, other) self代表指定球自身,而other代表球列表,注意,只有列表中的元素个数大于等于2时才可进行吃球操作。顺序扫描球列表中的元素,如果被扫描的球的半径小于指定球,且两个球的球心距离小于半径之和,则执行指定球吃被扫描球的操作,具体来说,先将两球的面积相加,以此为基准计算出一个新半径并赋给指定球,最后从球列表中移除被扫描球,结束本次吃球操作。如果被扫描球的半径大于指定球,且两个球的球心距离小于半径之和,则操作与上述相反
2)防止产生球的横向或纵向速度为0:执行下列代码即可:
while sy == 0 or sx == 0:
sx, sy = randint(-10,10), randint(-10,10)
4. 贪吃蛇
要点:
1)判断蛇是否吃到了自己:若吃到自己,也只能吃第四个节点以后的节点,所以从第五个节点开始遍历,若被遍历到的节点与头节点的坐标相同,则表明蛇吃到了自己,修改蛇的_is_alive属性为False即可
2)吃食物计数:设置一个专门计数的变量即可,至于计数的显示,具体可参照五子棋的文字显示方法。注意每局结束后计数要清零
3)食物的产生位置不能位于蛇身上:产生一个食物坐标,循环与蛇节点的每一个坐标进行比较,没有相同的则成功,否则重新产生一个食物坐标
下周将迎来网络编程的学习及前一阶段的考核,感觉并不慌,因为最终想做一个涉及机器学习、数据分析的大项目用作毕设,希望老师在后期课程的讲解过程中穿插推荐一些机器学习的自学方法及目前该领域的一些切实可行的创新点,笔者希望能提早为毕设做准备,以免到时手足无措
网友评论