0

I'm trying to compare the input of an Entry box to the actual answer. This is one of my first python projects and I'm still very confused and to be honest I don't even know how to start asking the question.

The user will click either the addition or subtraction button. A string will appear asking "What does 4 + 5 equal?" The numbers are generated randomly.

I then insert an Entry box using the tkinter library. I don't know how to get() the input and compare it to the sum or difference of the actual numbers.

I was trying to follow this video but I've failed using other methods as well. FYI, I was focusing on the addition method mostly so if you test, that with addition first.

from tkinter import Entry
import tkinter as tk
import random as rand

root = tk.Tk()
root.geometry("450x450+500+300")
root.title("Let's play Math!")

welcomeLabel = tk.Label(text="LET'S PLAY MATH!").pack()
startLabel = tk.Label(text='Select a math operation to start').pack()

def addition():
    a = rand.randrange(1,10,1)
    b = rand.randrange(1,10,1)
    global Answer
    Answer = a + b

    tk.Label(text="What does " + str(a) + " + " + str(b) + " equal? ").place(x=0, y=125)
    global myAnswer
    myAnswer = Entry().place(x=300, y= 125)

def checkAnswer():
    entry = myAnswer.get()

    while int(entry) != Answer:
        if int(entry) != Answer:
            tk.Label(text="Let's try again.").pack()
        elif int(entry) == Answer:
            tk.Label(text="Hooray!").pack()


addBtn = tk.Button(text="Addition", command=addition).place(x=100, y = 60)
subBtn = tk.Button(text="Subtraction", command=subtraction).place(x=200, y=60)
checkBtn = tk.Button(text="Check Answer", command=checkAnswer).place(x=300, y = 150)

tk.mainloop()
Nahuatl_C137
  • 132
  • 1
  • 13
  • 1
    You should narrow down your code to the actual question you're asking. Please refer to [mcve]. – Nae Jan 19 '18 at 21:01
  • There are multiple things wrong with the code. But I think you're generally on the right track, except what's the purpose of `while myAnswer != Answer:`? The label you've created _will_ be shown after the very first time an answer is wrong anyway, so no need for a while loop there, rather there are other problems. – Nae Jan 19 '18 at 21:07
  • Ok, I've eliminated the part where I'm subtracting as I'd not yet done much work on it. If I take out anything else, it will be difficult to understand what I'm referencing. – Nahuatl_C137 Jan 19 '18 at 21:07
  • No, you can take out much more else, in fact you _should_. Otherwise this the question for: _"How can I create A GUI for a Math Quiz?"_. Which is too-broad as far as stackoverflow is concerned and will probably be closed. – Nae Jan 19 '18 at 21:09
  • 1
    `myAnswer` is a local variable defined in the `addition()` function, so you can't reference it in the `checkAnswer()` function since it doesn't exist there. You could make it a `global` variable to get around this. – martineau Jan 19 '18 at 21:20
  • @martineau Ok, let me add those on there. I'll update the question. – Nahuatl_C137 Jan 19 '18 at 21:39

3 Answers3

2

All you need to do to fix your issue is separate the creation of your Entry() object from the placing of it:

def addition():
    a = rand.randrange(1,10,1)
    b = rand.randrange(1,10,1)
    global Answer
    Answer = int(a + b)

    tk.Label(text="What does " + str(a) + " + " + str(b) + " equal? ").place(x=0, y=125)
    global myAnswer
    myAnswer = Entry()
    myAnswer.place(x=300, y= 125)

Entry() returns the entry object, which has a get() method. However, when you chain .place(), you return its result instead, which is None. Therefore you never actually store the Entry object in your variable.

Also, it is a good idea to ensure that Answer is an int as well.

jack6e
  • 1,512
  • 10
  • 12
0

to get the value of the answer do answer = myanswer.get() or any other variable name. To compare it to the correct answer do

if int(answer) == correctAnswer:
   #the code

is that what you were asking?

Hippolippo
  • 803
  • 1
  • 5
  • 28
  • That's one of the mistakes in the code. The part with `intAnswer`, which can be defined as `intAnswer = int(myAnswer.get())` in one of the many solutions. Except the code rather tries to compare an entry widget to an Integer. – Nae Jan 19 '18 at 21:15
  • @Nae I was not trying to do int(Answer). According to the video on the original answer, I had to create yet another variable and i didn't know what to call it. – Nahuatl_C137 Jan 19 '18 at 21:17
  • so you made this question asking what to call your variable? – Hippolippo Jan 19 '18 at 21:20
  • @Nahuatl_19650 Be that as it may, the `Answer = a + b` returns an `int` and `myAnswer.get()` returns a `str`. If you want to compare them you need to convert one or the other in the most simplistic of the solutions. – Nae Jan 19 '18 at 21:20
  • That is why I had that there Nahuatl_19650 – Hippolippo Jan 19 '18 at 21:21
  • I'm trying to figure out how to retrieve the input, and compare to the sum of the two variables. – Nahuatl_C137 Jan 19 '18 at 21:23
  • It says how to get the input in my answer – Hippolippo Jan 19 '18 at 21:27
  • @Nahuatl_19650 Did this tell you what you needed to know? If not **please specify** in the question and please tell me you did so. – Hippolippo Jan 19 '18 at 21:29
  • if it did tell you what you needed, press the little check button next to the star – Hippolippo Jan 19 '18 at 21:29
  • @Hippolippo I tried using your method and I'm still not getting the expected "try again" or "hooray" message. I'll update the code above. – Nahuatl_C137 Jan 19 '18 at 21:31
  • 1
    @Nahuatl_19650 the get function works, the reason you are not getting your message is because your check answer command isn't hooked up. That is a derpy thing to do :) – Hippolippo Jan 19 '18 at 21:35
  • You're right, let me add the command. However, Now I get a 'NoneType' object has no attribute 'get'. – Nahuatl_C137 Jan 19 '18 at 21:37
  • take out that textvar thing. – Hippolippo Jan 19 '18 at 21:38
  • Nothing yet. It's given the error on answer = Answer.get(). Now updated to entry = myAnswer.get() - 'NoneType' Object has no attribute 'get'. – Nahuatl_C137 Jan 19 '18 at 21:44
  • maybe use `.grid()` or `.pack()` instead or `.place()` It normally works for me and I don't really use `.place()` – Hippolippo Jan 19 '18 at 21:51
  • @Hippolippo Changing the layout manager has nothing to do with that error. It is simply because `myAnswer` is not an `Entry` object. It is the `return`ed object of method `place` used on `myanswer` object, which is `None`. See https://stackoverflow.com/q/21592630/7032856. – Nae Jan 19 '18 at 22:09
  • @Nae I realized that mid-reading your comment, I have no idea why I didn't notice that – Hippolippo Jan 19 '18 at 22:11
0

Consider this and below is an example that responds to whether or not the number entered to answer is "Correct!" or "False!" when the user clicks on answer_btn:

import tkinter as tk
import random as rand

def is_correct():
    global answer, check
    if answer.get() == str(a + b):
        check['text'] = "Correct!"
    else:
        check['text'] = "False!"

def restart():
    global question, check
    random_nums()
    question['text'] = "{}+{}".format(a, b)
    check['text'] = "Please answer the question!"

def random_nums():
    global a, b
    a = rand.randrange(1, 10, 1)
    b = rand.randrange(1, 10, 1)

root = tk.Tk()

#create widgets
question = tk.Label(root)
answer = tk.Entry(root, width=3, justify='center')
check = tk.Label(root)
tk.Button(root, text="Check", command=is_correct).pack()
tk.Button(root, text="New question", command=restart).pack()

#layout widgets
question.pack()
answer.pack()
check.pack()

restart()
root.mainloop()
Nae
  • 14,209
  • 7
  • 52
  • 79