0

I'm making a maths quiz for a school project and one of the requirements is to do error handling. I want my code to be able to detect when the user enters nothing or when the user enters something that's not number, but I don't know where to put it. I have tried to put it under the an entry but it didn't work, if anyone knows where to put it, please tell me, thanks.

from tkinter import *
import random
p = 0
asked = []


class Starting:
    def __init__(self, master):
        self.frame = Frame(master, padx=200, pady=200)
        self.frame.grid()
        self.title = Label(self.frame, text="Multi-level Maths Quiz",
                           font=("Helvetica", "20", "bold"))
        self.title.grid(row=0, padx=30, pady=30)
        self.usern = Label(self.frame,text="Please enter a username", font=("16"))
        self.usern.grid(row=1, padx=20, pady=20)
        self.userentry = Entry(self.frame, width=50)
        self.userentry.grid(row=2)
        self.usercont = Button(self.frame, text="Continue", command=self.clear1)
        self.usercont.grid(row=3)

    def clear1(self):
        self.frame.destroy()
        Question1(root)


class Question1:
    def __init__ (self, master):
        global answer
        randomiser()
        self.master = master
        self.user_choice = StringVar()
        self.user_choice.set("")
        self.frame = Frame(master, padx=200, pady=200)
        self.frame.grid()
        self.q = Label(self.frame, text="What is {} + {} ?".format(x, y))
        self.q.grid(row=0)
        self.ans = Entry(self.frame, width=50, textvariable=self.user_choice)
        self.ans.grid(row=1)
        answer = x+y
        self.sub = Button(self.frame, text="submit", command=lambda:[self.correct(), randomiser()])
        self.sub.grid(row=3)

    def q2(self, master):
        randomiser()
        global answer
        self.master = master
        self.frame = Frame(master, padx=200, pady=200)
        self.frame.grid()
        self.user_choice = StringVar()
        self.user_choice.set("")
        self.q = Label(self.frame, text="What is {} x {} ?".format(x, y))
        self.q.grid(row=0)
        self.ans = Entry(self.frame, width=50, textvariable=self.user_choice)
        self.ans.grid(row=1)
        answer = x*y
        self.sub = Button(self.frame, text="submit", command=lambda:[self.correct(), randomiser()])
        self.sub.grid(row=3)

    def q3(self, master):
        randomiser()
        global answer
        self.master = master
        self.frame = Frame(master, padx=200, pady=200)
        self.frame.grid()
        self.user_choice = StringVar()
        self.user_choice.set("")
        self.q = Label(self.frame, text="What is {} / {} ?".format(x, y))
        self.q.grid(row=0)
        self.ans = Entry(self.frame, width=50, textvariable=self.user_choice)
        self.ans.grid(row=1)
        answer = x/y
        self.sub = Button(self.frame, text="submit", command=lambda:[self.correct(), randomiser()])
        self.sub.grid(row=3)

    def correct(self):
        global p
        if int(self.user_choice.get()) == answer:
            cor = Label(self.frame,text="Correct!")
            cor.grid(row=5, pady=20)
            p += 1
            self.sub.destroy()
            nex = Button(self.frame, text="Next", command=self.necs)
            nex.grid(row=4)
        else:
            inc = Label(self.frame,text="incorrect, the correct answer is {}".format(answer))
            inc.grid(row=5, pady=20)
            self.sub.destroy()
            nex = Button(self.frame, text="Next", command=self.necs)
            nex.grid(row=4)

        def necs(self):
            self.frame.destroy()
            if p<2:
                Question1(self.master)
            elif 2<=p<4:
                self.q2(root)
            elif 4<=p<6:
                self.q3(root)


def randomiser():
    global x, y
    x = random.randint(5, 12)
    y = random.randint(5, 12)


if __name__ == "__main__":
   root = Tk()
   root.title = ("Maths Quiz")
   instance = Starting(root)
   root.mainloop()
Mark Lin
  • 89
  • 6
Mark Lin
  • 103
  • 8
  • 3
    Use at where the input is to be converted to numbers. – acw1668 Jun 17 '20 at 01:15
  • Off-topic tip: You can create ***and*** initialize a `StringVar` in one statement with something like `my_var = tk.StringVar(value='initial value')`. – martineau Jun 17 '20 at 01:53

2 Answers2

1

You could put it in the correct() method as shown:

    def correct(self):
        global p
        try:
            choice = int(self.user_choice.get())
        except ValueError:
            choice = None

        if choice == answer:
            cor = Label(self.frame,text="Correct!")
            cor.grid(row=5, pady=20)
            p += 1
            self.sub.destroy()
            nex = Button(self.frame, text="Next", command=self.necs)
            nex.grid(row=4)
        else:
            inc = Label(self.frame,text="incorrect, the correct answer is {}".format(answer))
            inc.grid(row=5, pady=20)
            self.sub.destroy()
            nex = Button(self.frame, text="Next", command=self.necs)
            nex.grid(row=4)
martineau
  • 119,623
  • 25
  • 170
  • 301
0

For general error handling, I always have something like this in all functions:

def randomiser():
    try:
        global x, y
        x = random.randint(5, 12)
        y = random.randint(5, 12)
    except Exception as e:
        print(e)

For just checking the error around the entry, wouldn't this be here:

self.ans = Entry(self.frame, width=50, textvariable=self.user_choice)

See here for fancier stuff:

How to print an exception in Python?

Martineau's answer is better.

asylumax
  • 781
  • 1
  • 8
  • 34