#π Difficulty in Updating the correct value for a difficulty's completion status in a Python Quiz Gam
140 messages Β· Page 1 of 1 (latest)
@opaque cairn
Remember to:
- Ask your Python question, not if you can ask or if there's an expert who can help.
- Show a code sample as text (rather than a screenshot) and the error message, if you've got one.
- Explain what you expect to happen and what actually happens.
:warning: Do not pip install anything that isn't related to your question, especially if asked to over DMs.
class DifficultySelection(BaseFrame):
def __init__(self, parent, subject):
super().__init__(parent)
self.subject = subject
game_frame = parent.frames.get("game")
if game_frame:
self.completed = game_frame.completed.get(subject, {'Easy': False, 'Medium': False, 'Hard': False})
else:
self.completed = {'Easy': False, 'Medium': False, 'Hard': False}
self.create_widgets()
def create_widgets(self):
ttk.Label(self, text='Select Difficulty', justify="center").grid(row=0, column=2)
easy_completed = self.check_if_easy_completed()
mid_completed = self.check_if_mid_completed()
hard_completed = self.check_if_hard_completed()
ttk.Button(self, text='Easy', command=lambda: self.start_game('Easy'), padding=15).grid(row=1, column=2)
ttk.Button(self, text='Medium', command=lambda: self.start_game('Medium'), padding=15, state='normal' if easy_completed else 'disabled').grid(row=2, column=2)
ttk.Button(self, text='Hard', command=lambda: self.start_game('Hard'), padding=15, state='normal' if easy_completed and mid_completed else 'disabled').grid(row=3, column=2)
def check_if_easy_completed(self):
return self.completed['Easy']
def check_if_mid_completed(self):
return self.completed['Medium']
def check_if_hard_completed(self):
return self.completed['Hard']
def start_game(self, difficulty):
self.master.start_game(self.subject, difficulty)
def next_question(self):
self.current_question += 1
if self.current_question < len(self.question_set):
self.show_question()
else:
difficulty = self.master.frames["game"].difficulty
self.completed[difficulty] = True
messagebox.showinfo(f"Quiz Completed", f"Quiz Completed! Current Score: {self.scores[difficulty]}")
self.master.show_frame("menu")
I've been trying to figure out what it is exactly that is causing the program to not properly update the completion state of a difficulty in this python script
I've tried to troubleshoot it and the main problem seems to be that
even though the values get properly updated in this segment
the code over here resets it back to it's initial value of False
is game_frame suppoed to be the previous "game session"?
yes
so it's resetting because of this self.completed = game_frame.completed.get(subject, {'Easy': False, 'Medium': False, 'Hard': False})
I believe so, I've been trying to fix it on my own for the past 2 hours but I just can't seem to properly update it's value without breaking the program
ok what is that line supposed to do?
nvm i see
so the subject is supposed to give the difficulty
right?
yes
so if there's no "subject" difficulty in self.completed, it just resets it, which is whats happening
shouldn't self.completed = game_frame.completed just work?
-I haven't tried that yet;;
if your goal is to carry the difficulty status from the last question i think that should work
It worked but it also gave the completion status of the easy difficulty to the other subjects and not just the one specific subject the user took
oh okay, can you explain how the game works?
if every question or session has different subjects and youre using only one self.completed dict for every subject, then its normal that it updates for every subject
The game is basically a quiz game that allows the user to select one subject and the easy difficulty at the start. After completing the easy difficulty of one selected subject, the subsequent difficulty (medium) should then be unlocked for the user to take, then after completing both difficulties, it would then allow the user to take the hardest difficulty.
okay i see
so we need to store the completed status for each subject
self there is the game frame right?
if so, i'd turn the self.completed dict from {'Easy': False, 'Medium': False, 'Hard': False} into somthing like {"Subject1": {'Easy': False, 'Medium': False, 'Hard': False}, "Subject2": {'Easy': False, 'Medium': False, 'Hard': False}}
so now you have difficulty status for each subject
and now this would work self.completed = game_frame.completed.get(subject, {'Easy': False, 'Medium': False, 'Hard': False})
wait no
keep this
you'd then have to pass subject into each function that checks the difficulty is completed
def check_if_easy_completed(self, subject):
return self.completed[subject]['Easy']
or just use self.subject yeah
def check_if_easy_completed(self):
return self.completed[self.subject]['Easy']
Hmmm I see I see, alright. Let me try to implement the changes you've suggested to see if that would resolve the problem ^^
alright
After implementing the changes, I tried running the program
After completing the easy difficulty on the English subject, I got this error:
Exception in Tkinter callback
Traceback (most recent call last):
File "c:\Users\James\AppData\Local\Programs\Python\Python311\Lib\tkinter\__init__.py", line 1948, in __call__
return self.func(*args)
^^^^^^^^^^^^^^^^
File "c:\Users\James\OneDrive\Desktop\Finals Project 2\Test.py", line 52, in <lambda>
ttk.Button(self, text="English", padding=20, command=lambda: self.open_difficulty_selection('English')).grid(row=1, column=1)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "c:\Users\James\OneDrive\Desktop\Finals Project 2\Test.py", line 60, in open_difficulty_selection
self.master.frames["difficulty"] = DifficultySelection(self.master, subject)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "c:\Users\James\OneDrive\Desktop\Finals Project 2\Test.py", line 86, in __init__
self.create_widgets()
File "c:\Users\James\OneDrive\Desktop\Finals Project 2\Test.py", line 91, in create_widgets
easy_completed = self.check_if_easy_completed()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "c:\Users\James\OneDrive\Desktop\Finals Project 2\Test.py", line 100, in check_if_easy_completed
return self.completed[self.subject]['Easy']
~~~~~~~~~~~~~~^^^^^^^^^^^^^^
KeyError: 'English'
how does your code look now?
most likely you didn't add the subjects to your self.completed
class DifficultySelection(BaseFrame):
def __init__(self, parent, subject):
super().__init__(parent)
self.subject = subject
game_frame = parent.frames.get("game")
if game_frame:
self.completed = game_frame.completed
else:
self.completed = {
'English': {'Easy': False, 'Medium': False, 'Hard': False},
'Math': {'Easy': False, 'Medium': False, 'Hard': False},
'Filipino': {'Easy': False, 'Medium': False, 'Hard': False},
'Science': {'Easy': False, 'Medium': False, 'Hard': False},
'Social Sciences': {'Easy': False, 'Medium': False, 'Hard': False}
}
self.create_widgets()
def create_widgets(self):
ttk.Label(self, text='Select Difficulty', justify="center").grid(row=0, column=2)
easy_completed = self.check_if_easy_completed()
mid_completed = self.check_if_mid_completed()
hard_completed = self.check_if_hard_completed()
ttk.Button(self, text='Easy', command=lambda: self.start_game('Easy'), padding=15).grid(row=1, column=2)
ttk.Button(self, text='Medium', command=lambda: self.start_game('Medium'), padding=15, state='normal' if easy_completed else 'disabled').grid(row=2, column=2)
ttk.Button(self, text='Hard', command=lambda: self.start_game('Hard'), padding=15, state='normal' if (easy_completed and mid_completed) else 'disabled').grid(row=3, column=2)
def check_if_easy_completed(self):
return self.completed[self.subject]['Easy']
def check_if_mid_completed(self):
return self.completed[self.subject]['Medium']
def check_if_hard_completed(self):
return self.completed[self.subject]['Hard']
def start_game(self, difficulty):
self.master.start_game(self.subject, difficulty)
alrighty ^^
somehow 'English' is not in the dict, altho you put it there
!e
completed = {
'English': {'Easy': False, 'Medium': False, 'Hard': False},
'Math': {'Easy': False, 'Medium': False, 'Hard': False},
'Filipino': {'Easy': False, 'Medium': False, 'Hard': False},
'Science': {'Easy': False, 'Medium': False, 'Hard': False},
'Social Sciences': {'Easy': False, 'Medium': False, 'Hard': False}
}
print(completed['English']['Easy'])
@covert wasp :white_check_mark: Your 3.12 eval job has completed with return code 0.
False
this works
aaaaa
do you think it has something to do with this:
def start_game(self, subject, difficulty):
subject_index = {'English': 0, 'Math': 1, 'Science': 2, 'Filipino': 3, 'Social Sciences': 4}[subject]
difficulty_index = {'Easy': 0, 'Medium': 1, 'Hard': 2}[difficulty]
question_set = Quiz_Data[subject_index][difficulty_index]
game_frame = Game(self, question_set)
game_frame.difficulty = difficulty
self.frames["game"] = game_frame
self.show_frame("game")
or this
def __init__(self, parent):
super().__init__(parent)
ttk.Label(self, text="Select Subject", justify="center", padding=20).grid(row=0, column=1)
ttk.Button(self, text="English", padding=20, command=lambda: self.open_difficulty_selection('English')).grid(row=1, column=1)
ttk.Button(self, text="Math", padding=20, command=lambda: self.open_difficulty_selection('Math')).grid(row=2, column=1)
ttk.Button(self, text="Filipino", padding=20, command=lambda: self.open_difficulty_selection('Filipino')).grid(row=3, column=1)
ttk.Button(self, text="Science", padding=20, command=lambda: self.open_difficulty_selection('Science')).grid(row=4, column=1)
ttk.Button(self, text="Social Sciences", padding=20, command=lambda: self.open_difficulty_selection('Social Sciences')).grid(row=5, column=1)
ttk.Button(self, text="Back", padding=20, command=lambda: parent.show_frame("menu")).grid(row=6, column=1)
maybe
if any of those messes with self.completed
or with self.subject
can you put a print(self.completed) in check_if_easy_completed(self) and run it again?
to see what it has
alright, one second
{'English': {'Easy': False, 'Medium': False, 'Hard': False}, 'Math': {'Easy': False, 'Medium': False, 'Hard': False}, 'Filipino': {'Easy': False, 'Medium': False, 'Hard': False}, 'Science': {'Easy': False, 'Medium': False, 'Hard': False}, 'Social Sciences': {'Easy': False, 'Medium': False, 'Hard': False}}
{'Easy': True, 'Medium': False, 'Hard': False}
do a print(self.subject) there too
English
{'English': {'Easy': False, 'Medium': False, 'Hard': False}, 'Math': {'Easy': False, 'Medium': False, 'Hard': False}, 'Filipino': {'Easy': False, 'Medium': False, 'Hard': False}, 'Science': {'Easy': False, 'Medium': False, 'Hard': False}, 'Social Sciences': {'Easy': False, 'Medium': False, 'Hard': False}}
Any landing page please
landing page .?.
Yes
well, self.completed[self.subject][βEasyβ] gives a KeyError
altho english is literally there in self.completed
I mean redirect pages that I can use for my marketing
and self.subject is βEnglishβ
I'm sorry, I'm unfamiliar with the term, I'm pretty new to programming
yeah qwq
could it have something to do with how I get my data for the quiz
import tkinter as tk
from tkinter import messagebox, ttk
from QuizData import Quiz_Data
English = [English_Easy, English_Mid, English_Hard]
Math = [Math_Easy, Math_Mid, Math_Hard]
Science = [Science_Easy, Science_Mid, Science_Hard]
Filipino = [Filipino_Easy, Filipino_Mid, Filipino_Hard]
Social_Sciences = [Social_Sciences_Easy, Social_Sciences_Mid, Social_Sciences_Hard]
Quiz_Data = [English, Math, Science, Filipino, Social_Sciences]
is self.subject a string?
apparently it is
where are you calling your DifficultySelection object?
class Main(BaseFrame):
def __init__(self, parent):
super().__init__(parent)
ttk.Label(self, text="Select Subject", justify="center", padding=20).grid(row=0, column=1)
ttk.Button(self, text="English", padding=20, command=lambda: self.open_difficulty_selection('English')).grid(row=1, column=1)
ttk.Button(self, text="Math", padding=20, command=lambda: self.open_difficulty_selection('Math')).grid(row=2, column=1)
ttk.Button(self, text="Filipino", padding=20, command=lambda: self.open_difficulty_selection('Filipino')).grid(row=3, column=1)
ttk.Button(self, text="Science", padding=20, command=lambda: self.open_difficulty_selection('Science')).grid(row=4, column=1)
ttk.Button(self, text="Social Sciences", padding=20, command=lambda: self.open_difficulty_selection('Social Sciences')).grid(row=5, column=1)
ttk.Button(self, text="Back", padding=20, command=lambda: parent.show_frame("menu")).grid(row=6, column=1)
def open_difficulty_selection(self, subject):
self.master.frames["difficulty"] = DifficultySelection(self.master, subject)
self.master.show_frame("difficulty")
is it still giving you the error?
if you run it
because it really shouldn't be giving the error
yes
English
{'English': {'Easy': False, 'Medium': False, 'Hard': False}, 'Math': {'Easy': False, 'Medium': False, 'Hard': False}, 'Filipino': {'Easy': False, 'Medium': False, 'Hard': False}, 'Science': {'Easy': False, 'Medium': False, 'Hard': False}, 'Social Sciences': {'Easy': False, 'Medium': False, 'Hard': False}}
English
{'Easy': True, 'Medium': False, 'Hard': False}
Exception in Tkinter callback
Traceback (most recent call last):
File "c:\Users\James\AppData\Local\Programs\Python\Python311\Lib\tkinter\__init__.py", line 1948, in __call__
return self.func(*args)
^^^^^^^^^^^^^^^^
File "c:\Users\James\OneDrive\Desktop\Finals Project 2\Test.py", line 52, in <lambda>
ttk.Button(self, text="English", padding=20, command=lambda: self.open_difficulty_selection('English')).grid(row=1, column=1)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "c:\Users\James\OneDrive\Desktop\Finals Project 2\Test.py", line 60, in open_difficulty_selection
self.master.frames["difficulty"] = DifficultySelection(self.master, subject)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "c:\Users\James\OneDrive\Desktop\Finals Project 2\Test.py", line 86, in __init__
self.create_widgets()
File "c:\Users\James\OneDrive\Desktop\Finals Project 2\Test.py", line 91, in create_widgets
easy_completed = self.check_if_easy_completed()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "c:\Users\James\OneDrive\Desktop\Finals Project 2\Test.py", line 102, in check_if_easy_completed
return self.completed[self.subject]['Easy']
~~~~~~~~~~~~~~^^^^^^^^^^^^^^
KeyError: 'English'
oh
it gives me the error after the first run it makes
def next_question(self):
self.current_question += 1
if self.current_question < len(self.question_set):
self.show_question()
else:
difficulty = self.master.frames["game"].difficulty
self.completed[difficulty] = True
messagebox.showinfo(f"Quiz Completed", f"Quiz Completed! Current Score: {self.scores[difficulty]}")
self.master.show_frame("menu")
self.completed[difficulty] = True should be self.completed[self.subject][difficulty] = True
now every time you edit the difficulty completion status, youll need to say in which subject it updates
any other occurrences of self.completed in your code?
yes, i need to change all of them right?
yeah
should I remove it?
If your code is too long to fit in a codeblock in Discord, you can paste your code here:
https://paste.pythondiscord.com/
After pasting your code, save it by clicking the Paste! button in the bottom left, or by pressing CTRL + S. After doing that, you will be navigated to the new paste's page. Copy the URL and post it here so others can see it.
like this?
class Game(BaseFrame):
def __init__(self, parent, question_set):
super().__init__(parent)
self.question_set = question_set
self.current_question = 0
self.scores = {'Easy': 0, 'Medium': 0, 'Hard': 0}
self.completed = {'Easy': False, 'Medium': False, 'Hard': False} #<<<< This one ?
self.create_widgets()
ok
so
yeah i think doing
self.completed = {
'English': {'Easy': False, 'Medium': False, 'Hard': False},
'Math': {'Easy': False, 'Medium': False, 'Hard': False},
'Filipino': {'Easy': False, 'Medium': False, 'Hard': False},
'Science': {'Easy': False, 'Medium': False, 'Hard': False},
'Social Sciences': {'Easy': False, 'Medium': False, 'Hard': False}
}
in there should work
the Game() is called once right?
yes
I've implemented the change you've said, it's now giving me a different error message π :
Exception in Tkinter callback
Traceback (most recent call last):
File "c:\Users\James\AppData\Local\Programs\Python\Python311\Lib\tkinter\__init__.py", line 1948, in __call__
return self.func(*args)
^^^^^^^^^^^^^^^^
File "c:\Users\James\OneDrive\Desktop\Finals Project 2\Test.py", line 181, in next_question
self.completed[self.subject][difficulty] = True
^^^^^^^^^^^^
AttributeError: 'Game' object has no attribute 'subject'
well you need to get the subject
that it is in rn
add a subject attribute to your Game object
and declare it in the start_game function
so now you can access the subject of the questions in your Game Object
I don't think I'm doing it right, my brain is a bit mushy, would you mind showing me how?
well, you need to pass it in the init function of course
def __init__(self, parent, subject, question_set):
then IN your start_game function
def start_game(self, subject, difficulty):
subject_index = {'English': 0, 'Math': 1, 'Science': 2, 'Filipino': 3, 'Social Sciences': 4}[subject]
difficulty_index = {'Easy': 0, 'Medium': 1, 'Hard': 2}[difficulty]
question_set = Quiz_Data[subject_index][difficulty_index]
game_frame = Game(self, subject, question_set)
game_frame.difficulty = difficulty
self.frames["game"] = game_frame
self.show_frame("game")
you add subject in the Game() call
because that is how objects and functions work in python
Did I do it correctly?
well
the parameters you passed need to be in the same order as theyre specified in init
Ah I think I get what you mean, so like this?
yep
I ran it and I got another error;;
Exception in Tkinter callback
Traceback (most recent call last):
File "c:\Users\James\AppData\Local\Programs\Python\Python311\Lib\tkinter\__init__.py", line 1948, in __call__
return self.func(*args)
^^^^^^^^^^^^^^^^
File "c:\Users\James\OneDrive\Desktop\Finals Project 2\Test 2.py", line 95, in <lambda>
ttk.Button(self, text='Easy', command=lambda: self.start_game('Easy'), padding=15).grid(row=1, column=2)
^^^^^^^^^^^^^^^^^^^^^^^
TypeError: DifficultySelection.start_game() missing 1 required positional argument: 'difficulty'
undo what you did in that start_game function here ig
wait
one minute
yeah do that
def start_game(self, difficulty):
self.master.start_game(self.subject, difficulty)```
keep it like this
Alrighty
Exception in Tkinter callback
Traceback (most recent call last):
File "c:\Users\James\AppData\Local\Programs\Python\Python311\Lib\tkinter\__init__.py", line 1948, in __call__
return self.func(*args)
^^^^^^^^^^^^^^^^
File "c:\Users\James\OneDrive\Desktop\Finals Project 2\Test 2.py", line 95, in <lambda>
ttk.Button(self, text='Easy', command=lambda: self.start_game('Easy'), padding=15).grid(row=1, column=2)
^^^^^^^^^^^^^^^^^^^^^^^
File "c:\Users\James\OneDrive\Desktop\Finals Project 2\Test 2.py", line 111, in start_game
self.master.start_game(self.subject, difficulty)
File "c:\Users\James\OneDrive\Desktop\Finals Project 2\Test 2.py", line 25, in start_game
game_frame = Game(self, question_set)
^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: Game.__init__() missing 1 required positional argument: 'question_set'
T~T
yeah you need to add the subject to your Game() call
OH MY GOD YES
IT FINALLY WORKS
THANK YOU SO MUCH FOR BEING PATIENT WITH HELPING ME!!
This help channel has been closed and it's no longer possible to send messages here. If your question wasn't answered, feel free to create a new post in #1035199133436354600. To maximize your chances of getting a response, check out this guide on asking good questions.