如何在 python 3 中追加文件中的特定行?

how to append in a specific line in file in python 3?

我正在为我的计算机科学作业编写程序。我需要在小学做一个 3 类 的小测验。然后结果必须保存在文件中。我已经完成了这个程序,但下一个任务要求我让每个学生轮流 3 次并给出每个学生的平均值。
这是我用来将结果保存到文本文件中的代码:

def savetofile():
    result = result ="\n "+ namestudent.get() + "          "fscore.get()+"/4"
    messagebox.showinfo("results", "your results been saved successfuly")
    if int(year.get())==1:
        f = open('results C1.txt', 'a')
        f.write(result)
        f.close()
    if int(year.get())==2:
        f = open('results C2.txt', 'a')
        f.write(result)
        f.close()
    if int(year.get())==3:
        f = open('results C3.txt', 'a')
        f.write(result)
        f.close()

如何检查参加测验的新用户是否已经完成测验,如何在他们的名字前面添加该人的新结果,以及如何取他们 3 组的平均值分数。

首先,您在写入文件之前输出 your results been saved successfully,这是不正确的,因为文件写入可能会失败,因此最终无法成功完成。

然后按以下方式打开和关闭文件:

    f = open('results C1.txt', 'a')
    f.write(result)
    f.close()

这也是错误的,因为如果由于任何原因写入失败(如读取结果变量的异常),文件将无法正确关闭,并且输出可能不会刷新到它。

你应该这样做:

    with open('results C1.txt', 'a') as f:
        f.write(result)

它将负责正确打开、刷新和关闭文件。

那么下面一行是错误的:

result = result ="\n "+ namestudent.get() + "          "fscore.get()+"/4"

因为它在空格和得分结果之间遗漏了一个 +。你最好这样写(在末尾加上 \n 以避免第一行为空):

result = "{}          {}/4\n".format(namestudent.get(), fscore.get())

how can I check if the new user taking the quiz has already done the quiz or not?

为此,您需要执行以下算法:

# to open the file:
with open('results C1.txt', 'r') as results:
    # read the file
    for result in results:
        # split the line
        name, score = result.split("          ")
        if name == namestudent.get():
            # do something when the student exists

how can I add the new results of that person in front of their name also how can I take the average of their 3 sets of score?

那么我的建议是不要直接使用文件,而是打开所有乐谱的 "cache" 字典:

def load_scores():
    years_tuple_default = (None, None, None) # create a tuple with as many entries as there can be years
    student_scores = dict()
    with open('results C1.txt', 'r') as results:
        # read the file
        for result in results:
            # split the line
            name, score = result.split("          ")
            student_scores.setdefault(name, years_tuple_default)[0] = score

    with open('results C2.txt', 'r') as results:
        # read the file
        for result in results:
            # split the line
            name, score = result.split("          ")
            student_scores.setdefault(name, years_tuple_default)[1] = score

    with open('results C3.txt', 'r') as results:
        # read the file
        for result in results:
            # split the line
            name, score = result.split("          ")
            student_scores.setdefault(name, years_tuple_default)[2] = score

    return student_scores

然后,创建一个将缓存保存到文件中的函数:

def save_scores(student_scores):
    with open('results C1.txt', 'w') as results_y1:
        with open('results C2.txt', 'w') as results_y2:
            with open('results C3.txt', 'w') as results_y3:
                for student, scores in student_scores:
                    results_y1.write("{}          {}/4\n".format(student, scores[0]))
                    results_y2.write("{}          {}/4\n".format(student, scores[1]))
                    results_y3.write("{}          {}/4\n".format(student, scores[2]))
                print("Results saved!")

最后,针对该缓存进行操作:

def update_scores(student_scores, namestudent, fscore, year):
    if namestudent.get() not in student_scores.keys():
        # add the student entry
        student_scores.setdefault(namestudent.get(), (None, None, None))[int(year.get())-1] = fscore.get()
    else:
        # update the student year entry
        student_scores[int(year.get())-1] = fscore.get()

最终会得到一个看起来像这样的代码将它们放在一起:

student_scores = load_scores()

# do your stuff to get the namestudent/fscore/year data

update_scores(student_scores, namestudent, fscore, year)

# when all updates are done, you can alter the files

save_scores(student_scores)

总结一下:

  • 将您的算法拆分为函数,
  • 使用 with 语句
  • 保护您的文件处理
  • 读取文件一次以创建一个 "cache" 来处理,并在完成后立即保存结果

奖金创意

使用 class

从那里,为了更进一步,您可以创建一个 class,并将所有这些作为方法:

class StudentScores:
    def __init__(self):
        self._student_scores = dict()
    def load_scores(self):
        # TODO
    def save_scores(self):
        # TODO
    def update_score(self):
        # TODO

然后计算分数的平均值很简单愚蠢,它只是向 class 添加一个方法,原型看起来像:

class StudentScores:
    …
    def get_mean_scores(self, student):
        score_y1, score_y2, score_y3 = self._student_scores[student]
        score = # calculate the average of the three score
        return score

使用 with 语句

如果你想大放异彩,你可以使用 with statement:

class StudentScores:
    def __init__(self):
        self._student_scores = dict()
    def load_scores(self):
        # TODO
    def save_scores(self):
        # TODO
    def update_score(self):
        # TODO
    def __enter__(self):
        self.load_scores()
        return self
    def __exit__(self, type, value, traceback):
        self.save_scores()

然后你的代码会这样:

with StudentScores() as student_scores:
    # do your stuff to get the namestudent/fscore/year data
    update_scores(student_scores, namestudent, fscore, year)

总而言之,我将向您展示我如何设计一些东西来完成您的作业,而我并不是要代表您完成您的作业。我的目标是帮助您获得想法并学习有关软件设计和 python 的知识。有些事情可能超出您当前的水平(例如如何创建 with 语句),但随着您的学习,您将能够完全理解并应用我在这里告诉您的一切。

HTH