python面向物件的繼承和多型,學生資料處理
題目
定義Student類,包括name、dob、age、gender和score屬性,包括top3方法用來返回學生的最大的3個成績(可重複)、sanitize方法用來將負的分數變為正的分數,負的分數可能是輸入錯誤。宣告stu_list物件組數用於儲存所有的學生物件。最後輸出所有的學生資訊包括姓名、生日、年齡、性別、最高的3個分數。
資料如下:
stu1.txt 孫同學,2020-5-21,20,‘男’,77,56,77,76,92,58,-91,84,69,-91
stu2.txt 趙同學,2020-11-3,24,‘女’,65,68,72,95,-81,71,86,91,57,91
stu4.txt 李同學,2021-8-10,29,‘男’,92,54,85,71,-91,68,77,68,95,95
sumlist–我把所有檔案按順序放一個txt了,方便建立物件
第一題的輸出結果如下,供參考:
分析:第一步建立類,定義建構函式,top函式等。第二步寫讀取檔案的函式,邊讀取邊新建物件。
編寫輸出函式。
#新建一個空列表,方便裝物件
stu_list = []
class Student:
#新建學生類,第一個函式是建構函式,獲取name等屬性
def __init__ (self, name, dob, age, gender, score):
self.name = name
self.dob = dob
self.age = age
self.gender = gender
self.score = score
#top函式比較複雜,用來輸出最高的三個成績。
def top3(self):
#讀取檔案時已經全部處理為列表了,所以直接for遍歷,每次都用sanitize函式統一格式,隨後用sorted函式排序
#sorted預設輸出從小到大,所以輸出倒三就是最高的三次成績,注意,這裡沒有用set轉集合,所以資料可以重複
return sorted([self.sanitize(t) for t in self.score])[-3:]
#sanitize函式把負分轉換為正,正分則直接輸出,注意,列表裡儲存的是字串格式的score,得先轉int才能比較
def sanitize(self, score):
score = int(score)
if score < 0:
return -score
else:
return score
#鐘頭好戲來了,為避免多次程式碼重複,並且為了提高程式碼的可拓展性
#從檔案逐行讀取資料,並建立物件,先用,分段為列表。然後pop挨個彈出即可。新建的物件append給提前準備的空列表
def creat(filename):
with open(filename,'r',encoding="utf-8") as f:
line = f.readline()
while line :
templ = line.strip().split(',')
stu_list.append(Student(templ.pop(0), templ.pop(0), templ.pop(0), templ.pop(0), templ))
line = f.readline()
creat('sumlist.txt')
#多次輸出打包起來,方便後面迴圈執行
def print_student(student):
print(f'姓名:{student.name} 生日:{student.dob} 年齡:{student.age} 性別:{student.gender} 分數:{student.top3()}')
#一共四個資料迴圈四次即可0,1,2,3
for i in range(0, 4):
print_student(stu_list[i])
**
第二題
**
資料格式如下:
stu5.txt 特長同學,2020-10-5,20,‘男’,180,87,98,77,76,92,58,-76,84,69,-47
stu6.txt 特長同學,2020-10-6,20,‘女’,230,76,48,82,88,92,58,-91,84,69,-68
定義Spostudent、Artstudent為Student的子類,在子類的屬性裡面新增了spe為特長分數。Spostudent包括的top3方法返回的是最低的3個得分(可重複),Artstudent包括top3方法返回的是最高的3個得分(可重複),最後使用多型的方式輸出2個特長同學的姓名、生日、年齡、性別、分數、特長分。
第二題的輸出結果如下,供參考:
這題主要考繼承和多型
先繼承倆子類,然後其中一個要重寫函式,另一個不變。
最後呼叫給父類編寫的函式給倆子類,實現多型。(即執行子類的同名函式)
思路:先編寫父類,然後繼承的子類。最後執行,較為簡單
def get_coach_data(filename):#新建兩個不同的物件,所以只能一個一個來,不能像上面那樣
with open(filename) as f:
line = f.readline()
return line.strip().split(',')
class Spostudent(Student):#繼承父類,建構函式用父類的,在自己加一個spe即可
def __init__(self,name,dob,age,gender,spe,score):
Student.__init__(self,name,dob,age,gender,score)
self.spe=spe
def top3(self):#這個類要求最低的三個成績,所以輸出排序完的前三個就可以
return sorted([self.sanitize(t) for t in self.score])[:3]
class Artstudent(Student):#基本不變,就加個spe
def __init__(self,name,dob,age,gender,spe,score):
Student.__init__(self,name,dob,age,gender,score)
self.spe=spe
spe1=get_coach_data('work/stu5.txt')
spe2=get_coach_data('work/stu6.txt')
stu1=Spostudent(spe1.pop(0),spe1.pop(0),spe1.pop(0),spe1.pop(0),spe1.pop(0),spe1)
stu2=Artstudent(spe2.pop(0),spe2.pop(0),spe2.pop(0),spe2.pop(0),spe2.pop(0),spe2)
def print_student(student):#編寫輸出函式,此處注意,top3函式會按照我們的意願執行,在呼叫時直接呼叫即可
print(f'姓名:{student.name} 生日:{student.dob} 年齡:{student.age} 性別:{student.gender} 分數:{student.top3()} 特長分:{student.spe}')
print_student(stu1)
print_student(stu2)
#兩者的輸出剛好相反,這就是多型
#stu1是呼叫重寫過的top3輸出最低成績
#stu2是直接呼叫父類的top3函式
#之所以可以這麼用是因為兩者都是繼承Student類,所以他們可以用父類的函式,或自己重寫的同名函式
Student類兩個程式碼段都是一個,想要執行第二段程式碼的話直接把類複製過來就可以