I am trying to code a basic quiz application. For some reason when I move forwards and back again the mini-quiz won’t reset like I think it should. For example if I’m midway through a quiz and if I decide to hit the arrow forwards then back again my progress should be reset. I have two scripts I’m showing you one is my main.py and the other is referred to as quizzes.py. There is also an excerpt of the csv file I’m using for the quiz.
Question,Answer
the explosion,la explosión
the last name,el apellido
the conference,la conferencia
the intensity,la intensidad
the package,el paquete
the proposal,la propuesta
the bottle,la botella
the corpse,el cadáver
the combination,la combinación
the lady,la dama
the ripple,la onda
the tower,la torre
the eagerness,el afán
the commission,la comisión
the etcetera,etcétera
the inconvenience,el inconveniente
the faucet,la llave
the possession,la posesión
the candidate,el candidato
the gas,el gas
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")