本周是培訓的第三周褒搔,新知識點逐漸多了起來夷磕,程序的代碼量和復雜度遠勝之前,不過也能明顯的感覺到個人邏輯思維的提升亏拉、代碼編寫愈發(fā)的熟練扣蜻,本周涉及的知識點主要如下所示:
- 函數(shù)
名字(同變量命名)
參數(shù)、默認值及塘、可變參數(shù)(args, 組裝成元組)莽使、關鍵字參數(shù)(kwargs,組裝成字典)笙僚、命名關鍵字參數(shù)(號后的參數(shù)在傳參的時候必須有參數(shù)名)
返回值(單個芳肌、多個亦可)
嵌套定義(與C、C++等高級編程語言不同肋层,可以在一個函數(shù)里定義另一個函數(shù))
高階函數(shù) f(g(x))
lambda函數(shù)(匿名函數(shù))亿笤、【閉包、偏函數(shù)槽驶、柯里化】
decorator - 裝飾器 / 包裝器(通過裝飾器修飾函數(shù)责嚷,讓函數(shù)在執(zhí)行過程中可以做更多額外的操作)
- 類和對象
面向對象三大特性:封裝,繼承掂铐,多態(tài)
靜態(tài)方法與類方法(以判斷三角形三條邊設置是否合理為例)
- 靜態(tài)方法
@staticmethod
def is_valid(a, b, c):
return a + b > c and a + c > b and b + c > a - 類方法(消息依舊是發(fā)給類 可以用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): # 抽象方法罕拂,規(guī)范子類行為
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 --> 普通關聯(lián) - 聚合(強關聯(lián)) - 合成(不可分割)(從左到右由弱到強)
- use-a --> 依賴關系
- is-a --> 繼承關系
程序設計原則
- 高內聚:函數(shù)(類)只做一件事件(單一職責原則)
- 低耦合:代碼塊之間不能產生強關聯(lián)關系全陨,不要和特定的運行環(huán)境緊密耦合在一起
爆班,迪米特法則(最少知識原則)
面向對象原則
- 單一職責原則(Single Responsibility Principle, SRP)
- 開閉原則(Open Close Principle, OCP)(對擴展開放,對修改關閉)
- 依賴倒置原則(Dependence Inversion Principle, DIP)(模塊間的依賴通過抽象發(fā)生辱姨,實現(xiàn)類之間不發(fā)生直接的依賴關系柿菩,其依賴關系是通過接口或抽象類產生的)
- 里氏替換原則(Liskov Substitution Principle, LSP)(子類替換父類)
- 接口隔離原則(Interface Segregation Principles, ISP)(接口隔離原則的目的是系統(tǒng)解開耦合,從而容易重構雨涛、更改和重新部署 客戶端不應該依賴它不需要的接口)
- 合成聚合復用原則(能使用強關聯(lián)的地方就不要使用繼承)
- 迪米特法則(Law of Demeter, LOD)(最少知識原則)
- 異常機制
- 即處理程序在運行過程中出現(xiàn)的意外狀況的手段枢舶,因為不是所有的問題都能夠在寫程序調試程序的時候就能發(fā)現(xiàn),代碼如下所示:
try:
# 把可能出狀況(在執(zhí)行時有風險)的代碼放到try代碼塊保護起來
pass
except IOError:
# 如果try中出現(xiàn)了狀況就通過except來捕獲錯誤(異常)進行對應的處理
print("讀寫文件發(fā)生錯誤替久!")
except FileNotFoundError:
# except可以寫多個分別用于處理不同的異常狀況
pass
else:
# 如果沒有出狀況那么可以把無風險的代碼放到else中執(zhí)行
pass
finally:
# 不管程序正常還是異常最后這里的代碼一定會實現(xiàn)
# 此處是最好的釋放外部資源的位置凉泄,因為這里的代碼總是會執(zhí)行
pass
- Json
- 即 javascript object notation (js對象表達式 有格式,半結構化的純文本)蚯根,用于傳輸字典后众、列表數(shù)據
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("處理結束!")
除了基礎知識的講解,本周側重運用面向對象的思想來解決實際問題蒂誉,筆者也在緊跟課堂講解進度的同時教藻,對練習項目中待解決的問題進行了獨立思考,并給出了自己的實現(xiàn)右锨,下面就實現(xiàn)要點簡要的做一分享:
1. 21點
要點:
1)玩家先摸牌括堤,計算機后摸牌(計算機分穩(wěn)健性(超過16分不再摸牌)和魯莽型(超過18分不再摸牌))
2)每次摸牌前提示是否摸牌,摸牌后自動記錄點數(shù)并顯示牌面
3)最終的結果分為:a. 玩家和計算機的點數(shù)和均超過21點绍移,兩方均爆痊臭,平局
b. 玩家爆了,計算機未爆登夫,計算機勝
c. 計算機爆了,玩家未爆允趟,玩家勝
d. 計算機和玩家都未爆恼策,且玩家的點數(shù)和大于計算機,
玩家勝
e. 計算機和玩家都未爆潮剪,且玩家的點數(shù)和小于計算機涣楷,
計算機勝
f. 計算機和玩家都未爆,且玩家的點數(shù)和等于計算機抗碰,
平局
2. 五子棋
要點:
1)勝負裁決:以最后下的一顆棋子的坐標為基準狮斗,通過判斷垂直,水平,主對角線,斜對角線四個方向來判斷輸贏,每個方向讀取10顆棋的信息弧蝇,若有連續(xù)5顆及以上為同色棋碳褒,則判定為贏。 以水平方向為例看疗,倘若當前的棋子為黑棋沙峻,先從右至左依次掃描該棋左邊的五顆棋,被掃描的棋子為黑棋两芳,則計數(shù)器加一摔寨,否則停止掃描。然后從左至右掃描該棋右邊的五顆棋怖辆,處理方式同上是复。最終計數(shù)器的累計計數(shù)大于等于五,則可判定為贏
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,停止處理事件庫中的事件脂凶,并執(zhí)行到pygame.quit()語句宪睹,關閉游戲界面
3. 大球吃小球
要點:
1)吃球操作:增加方法eat(self, other) self代表指定球自身,而other代表球列表蚕钦,注意亭病,只有列表中的元素個數(shù)大于等于2時才可進行吃球操作。順序掃描球列表中的元素嘶居,如果被掃描的球的半徑小于指定球罪帖,且兩個球的球心距離小于半徑之和,則執(zhí)行指定球吃被掃描球的操作邮屁,具體來說整袁,先將兩球的面積相加,以此為基準計算出一個新半徑并賦給指定球佑吝,最后從球列表中移除被掃描球坐昙,結束本次吃球操作。如果被掃描球的半徑大于指定球芋忿,且兩個球的球心距離小于半徑之和炸客,則操作與上述相反
2)防止產生球的橫向或縱向速度為0:執(zhí)行下列代碼即可:
while sy == 0 or sx == 0:
sx, sy = randint(-10,10), randint(-10,10)
4. 貪吃蛇
要點:
1)判斷蛇是否吃到了自己:若吃到自己,也只能吃第四個節(jié)點以后的節(jié)點盗飒,所以從第五個節(jié)點開始遍歷嚷量,若被遍歷到的節(jié)點與頭節(jié)點的坐標相同,則表明蛇吃到了自己逆趣,修改蛇的_is_alive屬性為False即可
2)吃食物計數(shù):設置一個專門計數(shù)的變量即可蝶溶,至于計數(shù)的顯示,具體可參照五子棋的文字顯示方法宣渗。注意每局結束后計數(shù)要清零
3)食物的產生位置不能位于蛇身上:產生一個食物坐標抖所,循環(huán)與蛇節(jié)點的每一個坐標進行比較,沒有相同的則成功痕囱,否則重新產生一個食物坐標
下周將迎來網絡編程的學習及前一階段的考核田轧,感覺并不慌,因為最終想做一個涉及機器學習鞍恢、數(shù)據分析的大項目用作畢設傻粘,希望老師在后期課程的講解過程中穿插推薦一些機器學習的自學方法及目前該領域的一些切實可行的創(chuàng)新點每窖,筆者希望能提早為畢設做準備,以免到時手足無措