首页 > 编程问答 >为什么我的测验应用程序代码无法正确重置?

为什么我的测验应用程序代码无法正确重置?

时间:2024-07-25 09:49:05浏览次数:6  
标签:python python-3.x tkinter ttkbootstrap

我正在尝试编写一个基本的测验应用程序。由于某种原因,当我前后移动时,小测验不会像我想象的那样重置。例如,如果我正在测验中途,如果我决定向前点击箭头然后再次返回,我的进度应该被重置。我有两个脚本,我向您展示一个是我的 main.py,另一个是 quizzes.py。还有我用于测验的 csv 文件的摘录。

问题、答案 爆炸,爆炸 姓氏,埃尔阿佩利多 会议, 会议 强度,la intensidad 包裹,el paquete 该提案,la propuesta 瓶子,拉博特拉 尸体,el cadaver 组合, 组合 那位女士,拉达玛 涟漪,拉昂达 塔,拉托雷 渴望,el afán 委员会 等等等等 不便, el inconveniente 水龙头,拉拉夫 占有, 姿势 候选人, el Candidato 煤气,煤气

import ttkbootstrap as tb
from quizzes import Quizzes


# main.py


class App(tb.Window):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, themename='superhero', **kwargs)
        self.title('App')
        self.geometry('400x300')

        container = tb.Frame(self)
        container.pack(side="top", fill="both", expand=True)

        self.frames = {}
        for F in (Quizzes):
            page_name = F.__name__
            frame = F(parent=container, controller=self)
            self.frames[page_name] = frame

            frame.pack(anchor='center')


if __name__ == "__main__":
    app = App()
    app.mainloop()
import itertools
import pandas as pd
import ttkbootstrap as tb
from PIL import Image
Image.CUBIC = Image.BICUBIC


# quizzes.py


class Quizzes(tb.Frame):
    def __init__(self, parent, controller):
        super().__init__(parent)
        self.controller = controller
        self.parent = parent

        self.question_length = 5

        # add meter
        self.quiz_meter = tb.Meter(self, amounttotal=self.question_length, textright='of',
                              subtext=f'{self.question_length} correct answers')
        self.quiz_meter.pack(anchor='center', pady=10)

        # add question label
        self.quiz_question = tb.Label(self, text='Question', font=('Helvetica', 22))
        self.quiz_question.pack(anchor='center', pady=10)

        # entry
        self.quiz_entry = tb.Entry(self, font=('Helvetica', 25), justify='center')
        self.quiz_entry.pack(anchor='center', pady=10)
        self.quiz_entry.bind('<Return>', self.enter_answer)

        # Quiz number label
        self.quiz_number = tb.Label(self, text=1, font=('Helvetica', 18))
        self.quiz_number.pack(anchor='center', pady=10)

        # establish button style
        self.btn_style = tb.Style()
        self.btn_style.configure('outline.TButton', font=('Helvetica', 18))

        # back button
        self.back_btn = tb.Button(self, text='<', command=self.back, style='outline.TButton')
        self.back_btn.pack(side='left', pady=10)

        # forward button
        self.forward_btn = tb.Button(self, text='>', command=self.forward, style='outline.TButton')
        self.forward_btn.pack(side='right', pady=10)

        # Main menu button
        self.main_menu_btn = tb.Button(self, text='Main Menu', command=self.main_menu, style='outline.TButton')
        self.main_menu_btn.pack(anchor='center', pady=10)

        # df
        self.df = pd.read_csv('csv files\\1000 Spanish Nouns.csv')

        # separate df into multiple parts
        self.quizzes = []
        for i in range(0, len(self.df), self.question_length):
            if i + self.question_length < len(self.df) + 1:
                dataframe = self.df.iloc[i:i + self.question_length]
                lst = [tuple(row) for row in dataframe.itertuples(index=False, name=None)]
                self.quizzes.append(lst)
            else:
                dataframe = self.df.iloc[i:]
                lst = [tuple(row) for row in dataframe.itertuples(index=False, name=None)]
                self.quizzes.append(lst)

        # establish first quiz to test on
        self.quiz_index = 0
        self.current_quiz = self.quizzes[self.quiz_index]

        # quiz cycle
        self.quiz_cycle = itertools.cycle(self.current_quiz)

        # Setup first question
        self.row = next(self.quiz_cycle)
        self.question = self.row[0]
        self.answer = self.row[1]

        self.quiz_question.config(text=self.question)

    def back(self):
        # Reset meter
        self.quiz_meter.configure(amountused=0)

        # enable entry
        self.quiz_entry.config(state='normal')

        # Set next quiz
        if self.quiz_index != 0:
            self.quiz_index -= 1
            self.current_quiz = self.quizzes[self.quiz_index]
            self.quiz_cycle = itertools.cycle(self.current_quiz)
        else:
            self.current_quiz = self.quizzes[self.quiz_index]
            self.quiz_cycle = itertools.cycle(self.current_quiz)

        # Load first question
        self.row = next(self.quiz_cycle)
        self.question = self.row[0]
        self.answer = self.row[1]

        self.quiz_question.config(text=self.question)

        # Set new quiz number
        self.quiz_number.config(text=self.quiz_index + 1)

    def forward(self):
        # Reset meter
        self.quiz_meter.configure(amountused=0)

        # enable entry
        self.quiz_entry.config(state='normal')

        # Set next quiz
        if self.quiz_index != len(self.quizzes) - 1:
            self.quiz_index += 1
            self.current_quiz = self.quizzes[self.quiz_index]
            self.quiz_cycle = itertools.cycle(self.current_quiz)
        else:
            self.current_quiz = self.quizzes[self.quiz_index]
            self.quiz_cycle = itertools.cycle(self.current_quiz)

        # Load first question
        self.row = next(self.quiz_cycle)
        self.question = self.row[0]
        self.answer = self.row[1]

        self.quiz_question.config(text=self.question)

        # Set new quiz number
        self.quiz_number.config(text=self.quiz_index + 1)

        print(self.current_quiz)

    def main_menu(self):
        pass

    def enter_answer(self, event):
        # Check answer
        if self.quiz_entry.get() == self.answer:
            self.quiz_meter.configure(bootstyle='success')
            self.parent.after(400, self.reset_meter)
            self.quiz_meter.configure(amountused=self.quiz_meter.amountusedvar.get() + 1)

            # if last question is correct disable quiz
            if self.quiz_meter.amountusedvar.get() == self.question_length:
                self.quiz_question.config(text='Completed!')
                self.quiz_entry.delete(0, tb.END)
                self.quiz_entry.config(state='disabled')
                return

            self.current_quiz.remove(self.row)
            self.quiz_cycle = itertools.cycle(self.current_quiz)
            self.parent.after(400, self.next_question)
        else:
            self.quiz_meter.configure(bootstyle='danger')
            self.parent.after(2000, self.reset_meter)
            self.quiz_question.config(text=self.answer)
            self.parent.after(2000, self.next_question)

    def next_question(self):

        # Clear entry
        self.quiz_entry.delete(0, tb.END)

        # next question
        self.row = next(self.quiz_cycle)
        self.question = self.row[0]
        self.answer = self.row[1]

        self.quiz_question.config(text=self.question)

    def reset_meter(self):
        self.quiz_meter.configure(bootstyle="info")

代码中导致测验重置问题的原因是 forward back 函数的逻辑。问题在于,当使用 itertools.cycle 创建 self.quiz_cycle 时,正在创建一个迭代器,该迭代器在迭代完当前测验后循环回到测验的开头。这意味着,当前进或后退到新测验,然后又返回时, self.quiz_cycle 迭代器将从上一次停止的位置继续,而不是从测验的开头重新开始。

要解决此问题,需要在每次切换测验时重新创建 self.quiz_cycle 迭代器。可以通过将 self.quiz_cycle = itertools.cycle(self.current_quiz) 行移到 forward back 函数的调用 next(self.quiz_cycle) 之前来实现。

以下是更新后的 forward back 函数:

    def back(self):
        # Reset meter
        self.quiz_meter.configure(amountused=0)

        # enable entry
        self.quiz_entry.config(state='normal')

        # Set next quiz
        if self.quiz_index != 0:
            self.quiz_index -= 1
            self.current_quiz = self.quizzes[self.quiz_index]
        else:
            self.current_quiz = self.quizzes[self.quiz_index]

        # Reset quiz cycle
        self.quiz_cycle = itertools.cycle(self.current_quiz)

        # Load first question
        self.row = next(self.quiz_cycle)
        self.question = self.row[0]
        self.answer = self.row[1]

        self.quiz_question.config(text=self.question)

        # Set new quiz number
        self.quiz_number.config(text=self.quiz_index + 1)

    def forward(self):
        # Reset meter
        self.quiz_meter.configure(amountused=0)

        # enable entry
        self.quiz_entry.config(state='normal')

        # Set next quiz
        if self.quiz_index != len(self.quizzes) - 1:
            self.quiz_index += 1
            self.current_quiz = self.quizzes[self.quiz_index]
        else:
            self.current_quiz = self.quizzes[self.quiz_index]

        # Reset quiz cycle
        self.quiz_cycle = itertools.cycle(self.current_quiz)

        # Load first question
        self.row = next(self.quiz_cycle)
        self.question = self.row[0]
        self.answer = self.row[1]

        self.quiz_question.config(text=self.question)

        # Set new quiz number
        self.quiz_number.config(text=self.quiz_index + 1)

        print(self.current_quiz)

通过进行此更改,每次切换测验时,都会创建一个新的 self.quiz_cycle 迭代器,该迭代器从测验的开头开始,从而确保测验按预期重置。

标签:python,python-3.x,tkinter,ttkbootstrap
From: 78791180

相关文章

  • 如何在 Mac 上运行 Python 文件来读取 txt 文件并将其写入外部硬盘?
    我目前有一个充满了我想阅读的epub的文件夹,一个我已经阅读过并想再次阅读的epub的文件夹,以及一个相应的文件,其中每个文件都有epub文件的名称。问题是,这些文件夹仅位于我的外部硬盘上。我想要做的是让我的脚本解析这些文件夹中的epub列表,并在我的下载文件夹中创建最新的副......
  • 深入探索:使用Python进行网站数据加载逻辑分析与请求
    作为一名资深的Python程序员,我经常需要从网站中提取数据以供分析或进一步处理。这项任务涉及到对网站数据加载逻辑的深入分析,以及使用Python进行高效的网络请求。在本文中,我将分享如何分析网站的数据加载方式,并使用Python的requests库来模拟浏览器行为,获取所需的数据。网站......
  • 如何将 Python 列表添加到 Excel 中已有值的列的末尾?
    我目前正在尝试编写一个程序,将值附加到列表中,然后将这些值添加到Excel数据表中的列中。每次运行该程序时,我都希望在同一列的末尾添加更多值。所以我不确定如何解决这个问题,而且我在网上找到的其他答案也没有取得多大成功。以下是使用openpyxl库在Python中将......
  • 如何学习Python:糙快猛的大数据之路(学习地图)
    在这个AI和大数据主宰的时代,Python无疑是最炙手可热的编程语言之一。无论你是想转行还是提升技能,学习Python都是一个明智之选。但是,该如何开始呢?今天,让我们聊聊"糙快猛"的Python学习之道。什么是"糙快猛"学习法?"糙快猛"学习法,顾名思义,就是:糙:不追求完美,允许存......
  • Python 中 __get__ 方法的内部原理
    我正在摆弄描述符,结果碰壁了。我以为我可以像使用任何其他方法一样直接调用它,但显然,它似乎不一致或者我遗漏了一些东西。假设我有一个用作描述符的坐标类:|||还有一个Point类,它有2个坐标属性:classCoordinate:def__set_name__(self,owner,name):self._na......
  • 使用带有私钥的云前端生成签名 URL 的问题..使用 Python 3.7 为带有空格的 S3 对象生
    我在使用Python3.7为S3对象生成签名URL时遇到问题。具体来说,键中带有空格的对象的URL会导致“访问被拒绝”错误,而没有空格的对象的URL通常工作正常。但是,并非所有不带空格的对象都能正常工作,带空格的对象始终会失败。fromdatetimeimportdatetime,timedeltaimpo......
  • 有没有更好的方法来在存储库中的一组 python 程序之间共享公共代码
    当我想要快速、轻松地做许多不同的事情时,我会选择Python-即我总是会得到许多Python“程序”-例如一组脚本-或者如果我正在玩一些东西,一堆测试程序等-即始终是许多不同程序的松散集合。但是,我会分享某些内容。例如,如果我正在使用AI-我可能有30个左右完全不相......
  • 如何在Python中从两个不同长度的列表创建DataFrame,为第二个列表中的每个值重复第一个
    我是一个超级初学者,所以请耐心等待。我觉得这应该很容易,但我无法弄清楚。我不确定是否应该创建两个列表,然后将它们组合起来,或者是否有办法以这种方式直接创建DataFrame。我需要一列包含这些值:df=pd.DataFrame({'x1':np.linspace(-2.47,2.69,num=101)})然后我将值A......
  • Python multiprocessing.connection.Connection 的行为不符合规范
    根据python规范,recv()pythonConnection的方法,(从multiprocessing.Pipe()返回,当管道为空且管道的另一端关闭时抛出EOFError(这里参考:https://docs.python.org/3.9/library/multiprocessing.html#multiprocessing.connection.Connection.re......
  • 为什么在 tkinter 中的第二个窗口中使用 Tk() 而不是 Toplevel() 不允许我更新标签中
    首先,我是初学者,所以请不要指望这是专业的,但我需要帮助我想在我的新窗口中使用Tk()因为我要销毁主窗口并让第二个窗口运行时,当我使用它时,它不会让我的标签的文本变量更新,但通过使用toplevel()进行简单的更改就可以了,到底是怎么回事??Chatgpt没有帮助,他说了很多没有什么......