我正在为学校数学课程编写一个简单的数学程序,孩子们在程序中输入姓名,然后程序会询问10个简单的数学问题。
- 在程序结束后,孩子们分别按班级区分,姓名和分数将被存储在不同的文本文件中。
- 我目前遇到的一些问题如下:
- 我不确定是否有更好的方法来实现这个功能。
- 如果同一个孩子再次参加测试,如何将分数与之前分数取平均值?
- 如果孩子取得了更高的分数,如何使孩子的分数覆盖之前分数?(此处与平均分在不同的文本文件中)
- 我想要创建一个排行榜,最高分的孩子在顶部,最低分的孩子在底部。
- 当在排行榜上显示时,我希望它看起来像这样:
- 威廉-威尔逊 - 10
- 日向宁宁 - 9
- 等等。
- 我已经搜索了很多地方,但似乎找不到答案。如果有人能分享他们的知识,那就太好了。非常感谢!
- 以下是我尚未完成的代码。我是Python新手。
- 我需要在排行榜上添加额外的信息:平均分、最高分以及每个学生最高分对应测试的字母顺序。
- 解决方案
- 为了解决您在Python中将信息添加到包含姓名和分数的文本文件的问题,我提供了一套完善的解决方案,其中包含详细的代码示例和说明:
- 定义一个
entry类来存储每个学生的姓名、总分、尝试次数和平均分等信息。 - 使用
find_entry函数在数据文件中查找学生的条目。 - 利用
play函数让学生参加测试并更新他们的分数。 - 运用
leaderboard函数生成并显示学生的排行榜。 - 添加
backup函数来定期备份数据文件,以防数据丢失。 - 通过
add_student函数向数据文件中添加新学生。 - 以下是如何实现上述解决方案的方法:
- 在Python环境中,复制并粘贴提供给您的代码。
- 确保将
directory_name变量的值替换为您希望存储数据文件的目录路径。 - 确保正确填写备份文件的存储位置。
- 运行Python程序。
- 按照程序中的提示操作,输入学生姓名、参加测试并查看排行榜。
以下是代码示例:
import time, random, operator
directory_name = r"C:\Users\YOU\yourDirectoryHere\"
#When you change the directory name, be SURE to include
#the double backslash at the end. (and keep the r)
datafile = open(directory_name + "scores.txt")
data = bytearray(datafile.read())
datafile.close()
backup_directory = directory_name
def backup():
#Note: I didn't explain this function. It just randomly
#makes backups of the data file in case something unexpected happens.
global data, backup_directory
datafile = open(backup_directory + str(int(time.time())) + '.txt', 'w')
datafile.write("Remove this timestamp, message, and newline before restoring this data %s\n" % time.asctime())
datafile.write(data)
datafile.close()
class entry():
def __init__(self, i):
#i is the location of the student's entry in the data.
global data
self.name = data[i:i + 30]
self.total = int(data[i + 30:i + 40])
self.attempts = int(data[i + 40:i + 49])
if self.attempts:
self.average = float(self.total) / self.attempts
else: self.average = 0.0
def __cmp__(self, other):
#BUGGED CODE return self.average - other.average
#FIXED BELOW
if self.average > other.average: return 1
elif self.average < other.average: return -1
else: return 0
def __str__(self):
return "%s | %2.2f" % (self.name, self.average)
def update_score(self, score, i):
global data, directory_name
self.total += score
self.attempts += 1
self.average = float(self.total) / self.attempts
data[i + 30: i + 40] = "%10i" % self.total
data[i + 40: i + 49] = "%9i" % self.attempts
datafile = open(directory_name + "scores.txt",'w')
datafile.write(data)
datafile.close()
if not random.randrange(5):
backup()
def find_entry(name):
global data
for i in xrange(0,len(data),50):
if data[i:i + 30] == "%30s" % name:
return i
print "Name not found. Please check the spelling of your name."
print "If you spelled your name correctly please ask your teacher for help."
return None
def question():
n1 = random.randint(1,9)
n2 = random.randint(1,9)
ops = {'+': operator.add, '-': operator.sub, 'x': operator.mul}
op = random.choice(ops.keys())
answer = raw_input("What is %i %s %i? " % (n1, op, n2))
try:
answer = int(answer)
if answer == ops[op](n1, n2):
print "Well done"
return 1
else:
print "incorrect, %i %s %i = %i" % (n1, op, n2, ops[op](n1,n2))
return 0
except:
print "'%s' does not appear to be a number." % answer
return 0
def play():
global data
entry_num = None
while entry_num == None:
entry_num = find_entry(raw_input("Please enter your name and surname initial (e.g. William G): "))
student_entry = entry(entry_num)
score = 0
for i in xrange(10):
score += question()
student_entry.update_score(score, entry_num)
print "Your score this time was %i / 10" % score
def leaderboard():
global data
entries = []
for i in xrange(0, len(data),50):
entries += [entry(i)]
entries.sort()
entries.reverse()
for i in entries:
print i
def add_student():
#This wasn't explained either. It just appends a properly formatted 50 character
#long entry to the bytearray, initialized with the inputted name and zeroes.
global data
while True:
student = raw_input("Add a student, press enter to quit: ")
if student:
cancel = raw_input("Confirm '%s'. Press enter to confirm, any key to cancel: " % student)
if not cancel:
data += bytearray("%30s%10i%9i\n" % (student,0,0))
else: print "cancelled"
else:
break
datafile = open(directory_name + "scores.txt",'w')
datafile.write(data)
datafile.close()
while True:
print """\
Welcome to Simple-Maths Questions program
Please type one of the following:
Play | Leaderboard | Exit"""
command = raw_input()
command = command.upper()
if command in "PLAY":
play()
elif command in "LEADERBOARD":
leaderboard()
elif command in "EXIT":
break
elif command in "ADD NAME":
add_student()
else:
print "unknown command"
Note: I haven't exactly exhaustively bug tested this, so please do a bit of testing yourself to make sure this works.
NOTE 2: Amended cmp function; .sort behaved erratically with close floating pt. numbers.