一個剛?cè)隤ython坑的初學者类早,用python做學生管理系統(tǒng)的時候,在遇到排序的時候碰到了小插曲,讓我給她分析一下bug搏色,其實也很有趣。以下是她寫的代碼(這個代碼是我網(wǎng)上csdn找給她的券册,然后她自己按照任務規(guī)則修改了部分):
student_store = [] # 定義一個儲存學生信息的列表
def printMenu():
? ? """打印功能菜單"""
? ? print('=' * 30)
? ? print('學生信息管理系統(tǒng)')
? ? print('1.添加學生信息')
? ? print('2.刪除學生信息')
? ? print('3.修改學生信息')
? ? print('4.顯示所有學生信息')
? ? print('5.按學生語文成績高-低顯示學生信息')
? ? print('6.按學生數(shù)學成績高-低顯示學生信息')
? ? print('7.按學生英語成績高-低顯示學生信息')
? ? print('8.保存數(shù)據(jù)')
? ? print('0.退出系統(tǒng)')
? ? print('=' * 30)
def addInfo():
? ? """定義一個添加學生信息的函數(shù)"""
? ? newname = input('輸入新學生的名字:')
? ? newsex = input('輸入新學生的性別:')
? ? newnumber = input('輸入新學生的學號:')
? ? newchinese = input('請輸入語文成績:')
? ? newmath = input('請輸入數(shù)學成績:')
? ? newenglish = input('請輸入英語成績:')
? ? newInfo = {}
? ? newInfo['name'] = newname
? ? newInfo['sex'] = newsex
? ? newInfo['number'] = newnumber
? ? newInfo['chinese'] = newchinese
? ? newInfo['math'] = newmath
? ? newInfo['english'] = newenglish
? ? student_store.append(newInfo)
def delInfo():
? ? """定義一個刪除學生信息的函數(shù)"""
? ? delNum = int(input('請輸入要刪除的序號:')) - 1
? ? del student_store[delNum]
def modifystuInfo():
? ? """定義一個修改學生信息的函數(shù)"""
? ? stuId = int(input('請輸入要修改的學生序號:')) - 1
? ? newname = input('輸入修改后學生的名字:')
? ? newsex = input('輸入修改后學生的性別:')
? ? newnumber = input('輸入修改后學生的學號:')
? ? newchinese = input('輸入修改后學生的語文成績:')
? ? newmath = input('輸入修改后學生的數(shù)學成績:')
? ? newenglish = input('輸入修改后學生的英語成績:')
? ? student_store[stuId]['name'] = newname
? ? student_store[stuId]['sex'] = newsex
? ? student_store[stuId]['number'] = newnumber
? ? student_store[stuId]['chinese'] = newchinese
? ? student_store[stuId]['math'] = newmath
? ? student_store[stuId]['english'] = newenglish
def showstuInfo():
? ? """定義一個顯示所有學生信息的函數(shù)"""
? ? print('=' * 30)
? ? print('學生信息如下:')
? ? print('=' * 30)
? ? print("序號".center(4), "名字".center(8), "性別".center(8), "學號".center(8), "語文成績".center(8), "數(shù)學成績".center(8), "英語成績".center(8))
? ? i = 1
? ? for tempInfo in student_store:
? ? ? ? print('%d? %s? %s? %s %s %s %s' % (i, tempInfo['name'].center(14), tempInfo['sex'].center(4), tempInfo['number'].center(10), tempInfo['chinese'].center(10), tempInfo['math'].center(10), tempInfo['english'].center(10)))
? ? ? ? i += 1
# 成績排序
# 以下二個函數(shù)用于sorted排序频轿, key的表達式函數(shù)
def get_chinese(*l):
? ? for x in l:
? ? ? ? return x.get("chinese")
def get_math(*l):
? ? for x in l:
? ? ? ? return x.get("math")
def get_english(*l):
? ? for x in l:
? ? ? ? return x.get("english")
# 按學生語文成績高-低顯示學生信息
def chinese_reduce(student_store):
? ? print("按學生語文成績高-低顯示")
? ? mit = sorted(student_store, key=get_chinese)
? ? showstuInfo()
# 按學生數(shù)學成績高-低顯示學生信息
def math_reduce(student_store):
? ? print("按學生語文成績高-低顯示")
? ? mit = sorted(student_store, key=get_math)
? ? showstuInfo()
# 按學生英語成績高-低顯示學生信息
def english_reduce(student_store):
? ? print("按學生語文成績高-低顯示")
? ? mit = sorted(student_store, key=get_english)
? ? showstuInfo()
# 保存學生信息
def saveToFile():
? ? f = open('backup.data', 'w')
? ? f.write(str(student_store))
? ? f.close()
# 恢復數(shù)據(jù)
def recoverData():
? ? global student_store
? ? f = open('backup.data')
? ? content = f.read()
? ? student_store = eval(content)
? ? f.close()
# 定義主函數(shù),調(diào)用上面的子函數(shù)
def main():
? ? recoverData()
? ? while True:
? ? ? ? printMenu()? # 打印菜單
? ? ? ? key = int(input('請輸入您想選擇的功能:'))
? ? ? ? if key == 1:
? ? ? ? ? ? addInfo()? # 添加學生信息
? ? ? ? elif key == 2:
? ? ? ? ? ? delInfo()? # 刪除學生信息
? ? ? ? elif key == 3:
? ? ? ? ? ? modifystuInfo()? # 修改學生信息
? ? ? ? elif key == 4:
? ? ? ? ? ? showstuInfo()? # 查看學生所有信息
? ? ? ? elif key == 5:
? ? ? ? ? ? chinese_reduce(student_store)
? ? ? ? elif key == 6:
? ? ? ? ? ? math_reduce(student_store)
? ? ? ? elif key == 7:
? ? ? ? ? ? english_reduce(student_store)
? ? ? ? elif key == 8:
? ? ? ? ? ? saveToFile()? # 保存數(shù)據(jù)
? ? ? ? elif key == 0:? # 退出系統(tǒng)
? ? ? ? ? ? quitConfirm = input('您是要退出嗎烁焙?(Yes or No):')
? ? ? ? ? ? if quitConfirm == 'Yes':
? ? ? ? ? ? ? ? break? # 結(jié)束循環(huán)
? ? ? ? ? ? else:
? ? ? ? ? ? ? ? print('輸入有誤航邢,請重新輸入')
main()
她的代碼本身沒有問題,就是recoverData恢復數(shù)據(jù)的時候骄蝇,把數(shù)據(jù)加載到文檔里膳殷,她list里面結(jié)構(gòu)體的數(shù)據(jù)都是字符,造成sort排序的時候key的排序策略是錯的乞榨。
# 恢復數(shù)據(jù)
def recoverData():
? ? global student_store
? ? f = open('backup.data')
? ? content = f.read()
? ? student_store = eval(content)
? ? f.close()
這個操作出來的student_store全是字符串秽之,而我們排序是要求要用數(shù)值的。
所以她排序出來的都是錯的吃既,其實就是排序規(guī)則錯了
后面我給她改了代碼考榨,這個改的話再排序規(guī)則那邊
# 成績排序
# 以下二個函數(shù)用于sorted排序, key的表達式函數(shù)
def get_chinese(*l):
? ? for x in l:
? ? ? ? return int(x.get("chinese"))
def get_math(*l):
? ? for x in l:
? ? ? ? return int(x.get("math"))
def get_english(*l):
? ? for x in l:
? ? ? ? return int(x.get("english"))
核心在于返回的數(shù)據(jù)中都加了int類型鹦倚。
# 按學生語文成績高-低顯示學生信息
def chinese_reduce(student_store):
? ? print("按學生語文成績高-低顯示")
? ? mit = student_store.sort(key=get_chinese)
? ? showstuInfo()
# 按學生數(shù)學成績高-低顯示學生信息
def math_reduce(student_store):
? ? print("按學生語文成績高-低顯示")
? ? mit = student_store.sort(key=get_math)
? ? showstuInfo()
# 按學生英語成績高-低顯示學生信息
def english_reduce(student_store):
? ? print("按學生語文成績高-低顯示")
? ? mit = student_store.sort(key=get_english)
? ? showstuInfo()
以下簡單聊以下python中l(wèi)ist用法河质,接口用的是sort和sorted.
student_store.sort(key=get_english)
重點在于排序策略key,如果沒有制定策略,就會默認按照從小到大的順序。
sort用法如下
list.sort(cmp=None, key=None, reverse=False)
cmp--可選參數(shù)
key--用來進行比較的元素掀鹅,在這邊可作的文章比較多散休,能夠讓你代碼更優(yōu)雅一些
reverse--則是排序規(guī)則,True是降序乐尊,F(xiàn)alse是升序