Home > Software engineering >  Python Tkinter Quiz Project Validation Issue
Python Tkinter Quiz Project Validation Issue

Time:10-10

I am making a quiz program using the Python GUI interface. When the start button is selected, a random question is generated. User will next select true of false and then select the submit button.

How do I do this ?: I need to check the user attempt against the answer and display either ‘Question X is correct’ or ‘Question X is incorrect! in the Scrolled Text below’.

import tkinter as tk 
from tkinter import ttk, Label, scrolledtext, IntVar, Radiobutton   
import random

class Python_Quiz:
    def __init__(self):
        self._win = tk.Tk() # call the constructor to create the top level container
        self._win.resizable(False, False) # prevent it from being 
                                    # resized at both width and height 
        # self._window Title
        self._win.title("Python Quiz - Try Out This Quiz") # give it a title
        self._win.geometry("400x450")     # give it an initial width and height


        # Button
        actionFrame = ttk.Frame(self._win)
        actionFrame.pack()

        # Start Button
        self._start_btn = ttk.Button(actionFrame, text="Start")        
        self._start_btn.pack()                
        self._start_btn.bind('<Button-1>', self.start_btn_event) 

        # Use StringVar to Change the Label Text
        self._myLabel_text = tk.StringVar()
        self._myLabel_text.set("Question will appear here")

        # Creating Question will appear here Label Widget
        self._myLabel = Label(self._win, textvariable=self._myLabel_text)
        # Show self._wing it onto the screen
        self._myLabel.pack()

        # Radio Button

        radioFrame = ttk.Frame(self._win)

        self._radValue = tk.IntVar() # integer variable for value of 
                            # selected radio button
                            # default value is 1     

        radioFrame.pack()

        self.i = IntVar() #Basically Links Any Radiobutton With The Variable=i.

        # Use StringVar to Change the Option 1 Radio Button Text
        self._option_1_text = tk.StringVar()
        self._option_1_text.set("Option 1")

        # Option 1 Radio Button
        self._option_1_rdbtn = Radiobutton(radioFrame, textvariable=self._option_1_text, variable=self.i, value=1)         


        # Use StringVar to Change the Option 2 Radio Button Text
        self._option_2_text = tk.StringVar()
        self._option_2_text.set("Option 2")
    
        # Option 2 Radio Button
        self._option_2_rdbtn = Radiobutton(radioFrame, textvariable=self._option_2_text, variable=self.i, value=2)          

        self._option_1_rdbtn.pack() 
        self._option_2_rdbtn.pack()       

        actionFrame_2 = ttk.Frame(self._win)
        actionFrame_2.pack()
 
        # Submit Button
        self._submit_btn = ttk.Button(actionFrame_2, text="Submit") 
        self._submit_btn.config(state = tk.DISABLED) # prevent clicking      
        self._submit_btn.grid(column=0, row=0)

        # Next Button       
        self._next_btn = ttk.Button(actionFrame_2, text="Next")   
        self._next_btn.config(state = tk.DISABLED) # prevent clicking
        self._next_btn.grid(column=1, row=0)

        # Scrolled Text
        outputFrame = ttk.Frame(self._win)
        outputFrame.pack()

        scrol_w  = 50
        scrol_h  =  5

        self._scrol_stxt = scrolledtext.ScrolledText(outputFrame, 
        width=scrol_w, height=scrol_h, font=("Helvetica", 15) ,  wrap=tk.WORD)
        self._scrol_stxt.config(state = tk.DISABLED) # prevent editing
        self._scrol_stxt.pack()

        self._win.mainloop()


    def start_btn_event(self, event):
        self._scrol_stxt.config(state = tk.NORMAL) # prevent editing
        # self._scrol_stxt.insert(tk.INSERT, """ Select answer and click Submit """)
        self._scrol_stxt.insert(tk.INSERT,
"""\
Select answer and click Submit
""")
        self._scrol_stxt.config(state = tk.DISABLED) # prevent editing

        self._submit_btn.config(state = tk.NORMAL)
        self._submit_btn.bind('<Button-1>', self.submit_event_handler)
        self._myLabel_text.set(f"Q1. {random.choice(Random_Questions)}")
        # self._myLabel_text.set(f"Q1. String type is immutable")
        # self._myLabel_text.set(f"Q1. {Question_1}")

        self._option_1_text.set("True")
        self._option_2_text.set("False")

        print("The Start Button Works")

        self._start_btn.config(state = tk.DISABLED)

        self._option_1_rdbtn.bind('<Button-1>', self.selection_event)
        self._option_2_rdbtn.bind('<Button-1>', self.selection_event)


    def submit_event_handler(self, event):
        
        print("The Submit Button Works")
        if (self.i.get() ==0):
            self._scrol_stxt.config(state = tk.NORMAL) # prevent editing
            self._scrol_stxt.insert(tk.INSERT,
"""\
Please select answer for Question 1
""")
            self._scrol_stxt.config(state = tk.DISABLED) # prevent editing
            self._next_btn.config(state = tk.DISABLED)
        else:
            self._next_btn.config(state = tk.NORMAL)

    def check_guess(self, event):
        """ check the user attempt against the answer and display either ‘Question X is correct’ or ‘Question X is incorrect!’. """


    def selection_event(self, event):
        selection = "You selected the option "   str(self.i.get())
        print(selection)

questionBank = [ 
    ['Variable names cannot start with digit', True], \
    ["x='1' 1 is a valid statement", False], \
    ['= and == can be used interchangeably', False], \
    ['logical operator and has higher precedence than or', True], \
    ['String type is immutable', True], \
    ['x,y = y, x swaps the values of x and y', True], \
    ['2=x is a valid statement', False], \
    ['Variable names can be 50 letters long', True]
]

Question_1 = questionBank[0][0]
Question_2 = questionBank[1][0]
Question_3 = questionBank[2][0]
Question_4 = questionBank[3][0]
Question_5 = questionBank[4][0]
Question_6 = questionBank[5][0]
Question_7 = questionBank[6][0]
Question_8 = questionBank[7][0]

Question_1_ANS = questionBank[0][1]
Question_2_ANS = questionBank[1][1]
Question_3_ANS = questionBank[2][1]
Question_4_ANS = questionBank[3][1]
Question_5_ANS = questionBank[4][1]
Question_6_ANS = questionBank[5][1]
Question_7_ANS = questionBank[6][1]
Question_8_ANS = questionBank[7][1]

Random_Questions = [Question_1, Question_2, Question_3, Question_4, Question_5, Question_6, Question_7, Question_8]

def main():
    Python_Quiz()

main()


Output:

enter image description here

Intended Output:

enter image description here

CodePudding user response:

Hi you can use a dictionary for the question and answers After which when you randomly select the question store a reference to the answer as well.

self._question, self._answer = random.choice(list(Questions.items()))

The working example is here

import tkinter as tk 
from tkinter import ttk, Label, scrolledtext, IntVar, Radiobutton   
import random

class Python_Quiz:
    def __init__(self):
        self._win = tk.Tk() # call the constructor to create the top level container
        self._win.resizable(False, False) # prevent it from being 
                                    # resized at both width and height 
        # self._window Title
        self._win.title("Python Quiz - Done By Shawn Yang") # give it a title
        self._win.geometry("400x450")     # give it an initial width and height


        # Button
        actionFrame = ttk.Frame(self._win)
        actionFrame.pack()

        # Start Button
        self._start_btn = ttk.Button(actionFrame, text="Start")        
        self._start_btn.pack()                
        self._start_btn.bind('<Button-1>', self.start_btn_event) 

        # Use StringVar to Change the Label Text
        self._myLabel_text = tk.StringVar()
        self._myLabel_text.set("Question will appear here")

        # Creating Question will appear here Label Widget
        self._myLabel = Label(self._win, textvariable=self._myLabel_text)
        # Show self._wing it onto the screen
        self._myLabel.pack()

        # Radio Button

        radioFrame = ttk.Frame(self._win)

        self._radValue = tk.IntVar() # integer variable for value of 
                            # selected radio button
                            # default value is 1     

        radioFrame.pack()

        self.i = IntVar() #Basically Links Any Radiobutton With The Variable=i.

        # Use StringVar to Change the Option 1 Radio Button Text
        self._option_1_text = tk.StringVar()
        self._option_1_text.set("Option 1")

        # Option 1 Radio Button
        self._option_1_rdbtn = Radiobutton(radioFrame, textvariable=self._option_1_text, variable=self.i, value=1)         


        # Use StringVar to Change the Option 2 Radio Button Text
        self._option_2_text = tk.StringVar()
        self._option_2_text.set("Option 2")
    
        # Option 2 Radio Button
        self._option_2_rdbtn = Radiobutton(radioFrame, textvariable=self._option_2_text, variable=self.i, value=2)          

        self._option_1_rdbtn.pack() 
        self._option_2_rdbtn.pack()       

        actionFrame_2 = ttk.Frame(self._win)
        actionFrame_2.pack()
 
        # Submit Button
        self._submit_btn = ttk.Button(actionFrame_2, text="Submit") 
        self._submit_btn.config(state = tk.DISABLED) # prevent clicking      
        self._submit_btn.grid(column=0, row=0)

        # Next Button       
        self._next_btn = ttk.Button(actionFrame_2, text="Next")   
        self._next_btn.config(state = tk.DISABLED) # prevent clicking
        self._next_btn.grid(column=1, row=0)

        # Scrolled Text
        outputFrame = ttk.Frame(self._win)
        outputFrame.pack()

        scrol_w  = 50
        scrol_h  =  5

        self._scrol_stxt = scrolledtext.ScrolledText(outputFrame, 
        width=scrol_w, height=scrol_h, font=("Helvetica", 15) ,  wrap=tk.WORD)
        self._scrol_stxt.config(state = tk.DISABLED)
        self._scrol_stxt.pack()

        self._win.mainloop()


    def start_btn_event(self, event):
        self._scrol_stxt.config(state = tk.NORMAL)
        self._scrol_stxt.insert(tk.INSERT,
"""\
Select answer and click Submit
""")
        self._scrol_stxt.config(state = tk.DISABLED)

        self._submit_btn.config(state = tk.NORMAL)
        self._submit_btn.bind('<Button-1>', self.submit_event_handler)

        self._question, self._answer = random.choice(list(Questions.items()))
        self._myLabel_text.set(f"Q1. {self._question}")

        self._option_1_text.set("True")
        self._option_2_text.set("False")

        print("The Start Button Works")

        self._start_btn.config(state = tk.DISABLED)

        self._option_1_rdbtn.bind('<Button-1>', self.selection_event)
        self._option_2_rdbtn.bind('<Button-1>', self.selection_event)


    def submit_event_handler(self, event):
        
        print("The Submit Button Works")
        if (self.i.get() == 0):
            self._scrol_stxt.config(state = tk.NORMAL)
            self._scrol_stxt.insert(tk.INSERT,
"""\
Please select answer for Question 1
""")
            self._scrol_stxt.config(state = tk.DISABLED) # prevent editing
            self._next_btn.config(state = tk.DISABLED)
            # get current question 's answer
        elif ((self.i.get() == 1 and self._answer == True) or (self.i.get() == 2 and self._answer == False)):
            print("CORRECT")
            self._scrol_stxt.config(state = tk.NORMAL)
            self._scrol_stxt.insert(tk.INSERT,
"""\
CORRECT
""")
            self._scrol_stxt.config(state = tk.DISABLED) # prevent editing
            self._next_btn.config(state = tk.NORMAL)
#         elif (self.i.get() == 2 and self._answer == False):
#             print("CORRECT")
#             self._scrol_stxt.config(state = tk.NORMAL)
#             self._scrol_stxt.insert(tk.INSERT,
# """\
# CORRECT
# """)
#             self._scrol_stxt.config(state = tk.DISABLED) # prevent editing
#             self._next_btn.config(state = tk.NORMAL)
        else:
            print("WRONG")
            self._scrol_stxt.config(state = tk.NORMAL)
            self._scrol_stxt.insert(tk.INSERT,
"""\
WRONG
""")
            self._scrol_stxt.config(state = tk.DISABLED) # prevent editing
            self._next_btn.config(state = tk.NORMAL)

    # def is_answer_correct(self):
    #     if (self.i.get() == 1 and self._answer == True):
    #         return True
    #     else:
    #         return False

    # def check_guess(self, event):
    #     """ check the user attempt against the answer and display either ‘Question X is correct’ or ‘Question X is incorrect!’. """

    def selection_event(self, event):
        selection = "You selected the option "   str(self.i.get())
        print(selection)

questionBank = [ 
    ['Variable names cannot start with digit', True], \
    ["x='1' 1 is a valid statement", False], \
    ['= and == can be used interchangeably', False], \
    ['logical operator and has higher precedence than or', True], \
    ['String type is immutable', True], \
    ['x,y = y, x swaps the values of x and y', True], \
    ['2=x is a valid statement', False], \
    ['Variable names can be 50 letters long', True]
]

Question_1 = questionBank[0][0]
Question_2 = questionBank[1][0]
Question_3 = questionBank[2][0]
Question_4 = questionBank[3][0]
Question_5 = questionBank[4][0]
Question_6 = questionBank[5][0]
Question_7 = questionBank[6][0]
Question_8 = questionBank[7][0]

Question_1_ANS = questionBank[0][1]
Question_2_ANS = questionBank[1][1]
Question_3_ANS = questionBank[2][1]
Question_4_ANS = questionBank[3][1]
Question_5_ANS = questionBank[4][1]
Question_6_ANS = questionBank[5][1]
Question_7_ANS = questionBank[6][1]
Question_8_ANS = questionBank[7][1]

Questions = {
    Question_1: Question_1_ANS, 
    Question_2: Question_2_ANS, 
    Question_3: Question_3_ANS, 
    Question_4: Question_4_ANS, 
    Question_5: Question_5_ANS, 
    Question_6: Question_6_ANS, 
    Question_7: Question_7_ANS, 
    Question_8: Question_8_ANS 
}

def main():
    Python_Quiz()

main()

  • Related