Laveen
Laveen

Reputation: 15

Program gives unexpected output -- why?

I am writing a program which will test arithmetic skills. It is supposed to generate random questions, and give a random operation. Here is my code:

import random

score = 0
counter = 0
ops = ['+', '-', '*', '/']

def question():
    num1 = random.randint(0,10)
    num2 = random.randint(1,10) #Starts from 1 to avoid zerodivision error
    operation = random.choice(ops)
    question = float(input(f"What is {num1} {operation} {num2}?: "))
    global answer
    answer = eval(str(num1) + operation + str(num2))
    global counter
    counter = counter + 1


def points():
    while counter < 10:
        question()
        if question == answer:
            print("\nCorrect!\n")
            global score
            score = score + 1
        else:
            print(f"\nWrong! The answer is {answer}\n")


points()

print(f"\nYou got {score} out of {counter}")

But it gives this output:

What is 9 + 3?: 12
Wrong! The answer is 12

It is supposed to say correct if the input matches the answer, and count a score, and print the score out of ten at the end.

Please help me fix this.

Upvotes: 1

Views: 103

Answers (2)

elcaro
elcaro

Reputation: 2297

Your question has already been answered by Josh Karpel, but I just thought I'd point out another issue with division.

Division will always result in a float instead of an int, so if the user says 4 / 2 is 2... the script will say the answer is wrong, because it's doing a stringy comparison of "2" with "2.0". That's why in Josh's version, he converts the user answer to a float. This way the answers are compared numerically.

Additionally, the script is currently capable of asking things like What is 4 / 7 ? which is difficult for a person to answer. One work around would be to randomise num2 until it is evenly divisible by num1.

def question():
    num1 = random.randint(0, 10)
    num2 = random.randint(1, 10)
    operation = random.choice(ops)
    if operation == '/':
        while num1 % num2 != 0:
            num2 = random.randint(1, 10)
    # do eval

Upvotes: 1

Josh Karpel
Josh Karpel

Reputation: 2145

The problem is in

if question == answer:

In that line, question is a reference to the function question() that you defined earlier. Since answer is some int holding the answer to the question, the == is always False. You never actually find out what the user typed in.

To fix that, do something like this:

def question():
    num1 = random.randint(0,10)
    num2 = random.randint(1,10) #Starts from 1 to avoid zerodivision error
    operation = random.choice(ops)
    user_answer = float(input(f"What is {num1} {operation} {num2}?: "))
    global answer
    answer = eval(str(num1) + operation + str(num2))
    global counter
    counter = counter + 1

    return user_answer

def points():
    while counter < 10:
        user_answer = question()
        if user_answer == answer:
            print("\nCorrect!\n")
            global score
            score = score + 1
        else:
            print(f"\nWrong! The answer is {answer}\n")

I've changed the name to make it more clear what's going on.


As an addendum, I would highly, highly recommend not using global variables. They are almost never necessary and generally confuse the issue. For example, I think that

def question():
    num1 = random.randint(0,10)
    num2 = random.randint(1,10) #Starts from 1 to avoid zerodivision error
    operation = random.choice(ops)

    user_answer = float(input(f"What is {num1} {operation} {num2}?: "))
    real_answer = eval(str(num1) + operation + str(num2))

    return user_answer, real_answer

def points():
    score = 0
    for questions_asked in range(1, 11):
        user_answer, real_answer = question()
        if user_answer == real_answer:
            print("\nCorrect!\n")
            score += 1
        else:
            print(f"\nWrong! The answer is {answer}\n")

This makes it much easier to understand the program flow.

Upvotes: 3

Related Questions