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.
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.
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
Related
The code is supposed to be a simple maths quiz, however, when I enter the correct answer, it says it's wrong. My code is:
import random
name = input("What is your name? ")
question = 0
correct = 0
while question < 10:
question = question + 1
number1 = random.randint(1, 50)
number2 = random.randint(1, 50)
print("What is", number1, "+", number2)
answer = number1 + number2
print(answer)
student = input()
if student == answer:
print("Correct! Well Done!")
correct = correct + 1
else:
print("Wrong!")
Any ideas?
You forgot to cast the user input to int, so replace student = input() with student = int(input()), as at the moment you are comparing str to int.
Assuming that you are using Python 3, you need to type cast input() to int() in order to compare it with answer which is an integer:
student = int(input())
Assuming python3. The following is not valid for python2, as input treats an integer input as integer.
input() in python2 evaluates the expression with eval() function after reading from stdin, thus returning an integer.
The problem relies on the fact you are comparing strings to answer that is an integer.
import random
name = input("What is your name? ")
question = 0
correct = 0
while question < 10:
question = question + 1
number1 = random.randint(1, 50)
number2 = random.randint(1, 50)
print("What is", number1, "+", number2)
answer = number1 + number2
print(answer)
student = input()
#Cast the input to an integer for comparison
if int(student) == answer:
print("Correct! Well Done!")
correct = correct + 1
else:
print("Wrong!")
As many have already said, you need to cast the user input to int, replace student = input()
Also, you can do question += 1, rather than question = question + 1. This can help speed you up.
I am learning python, and one of the exercises is to make a simple multiplication game, that carries on every time you answer correctly. Although I have made the game work, I would like to be able to count the number of tries so that when I've answered correctly a few times the loop/function should end. My problem is that at the end of the code, the function is called again, the number of tries goes back to what I originally set it, obviously. How could I go about this, so that I can count each loop, and end at a specified number of tries?:
def multiplication_game():
num1 = random.randrange(1,12)
num2 = random.randrange(1,12)
answer = num1 * num2
print('how much is %d times %d?' %(num1,num2))
attempt = int(input(": "))
while attempt != answer:
print("not correct")
attempt = int(input("try again: "))
if attempt == answer:
print("Correct!")
multiplication_game()
You could surround your call of multiplication_game() at the end with a loop. For example:
for i in range(5):
multiplication_game()
would allow you to play the game 5 times before the program ends. If you want to actually count which round you're on, you could create a variable to keep track, and increment that variable each time the game ends (you would put this inside the function definition).
I would use a for loop and break out of it:
attempt = int(input(": "))
for count in range(3):
if attempt == answer:
print("correct")
break
print("not correct")
attempt = int(input("try again: "))
else:
print("you did not guess the number")
Here's some documentation on else clauses for for loops if you want more details on how it works.
NB_MAX = 10 #Your max try
def multiplication_game():
num1 = random.randrange(1,12)
num2 = random.randrange(1,12)
answer = num1 * num2
i = 0
while i < NB_MAX:
print('how much is %d times %d?' %(num1,num2))
attempt = int(input(": "))
while attempt != answer:
print("not correct")
attempt = int(input("try again: "))
if attempt == answer:
print("Correct!")
i += 1
multiplication_game()
print("Hello, and welcome to the Maths quiz!/n")
#Asks user for name - 05/03/2015
name = input("What is your name?")
#This will import random to generate random functions
import random
#This is a variable for score
#It has been set to 0 at the start of the program
score = 0
#This creates an array containing the mathematical operators
#that this quiz will use
ops = ['+','-','*']
#A loop has been set for 0 - 10
for x in (0,10):
#This is variable has been set to the operator of the equation that
#uses the random function and will choose a random operator from the
#array containing the operators made earlier
op = random.choice(ops)
if op == '+':
left1 = random.randint(1,100)
right1 = random.randint(1,100)
print (str(left1) + op + str(right1))
answer = eval(str(left1) + op + str(right1))
guess = input("")
if guess == answer:
print("Correct!")
score += 1
else:
print ("Incorrect")
elif op == '-':
left2 = random.randint(1,100)
right2 = random.randint(1,100)
print (str(left2) + op + str(right2))
answer1 = eval(str(left2) + op + str(right2))
guess1 = int(input(""))
if answer1 == guess1:
print("Correct!")
score += 1
else:
print("Incorrect")
elif op == '*':
left3 = random.randint(1,100)
right3 = random.randint(1,100)
print (str(left3) + op + str(right3))
answer2 = eval(str(left3) + op + str(right3))
guess2 = input("")
if answer2 == guess2:
print("Correct!")
score += 1
else:
print("Incorrect")
else:
break
print (score)
When I do this, it generates a random quiz that only loops twice, even though I want it to loop 10 times. Also, it sometimes give the right answer and sometimes the wrong answer. For example:
Hello, and welcome to the Maths quiz!/n
What is your name?j
95*3
285
Incorrect
35-46
-11
Correct!
What I want for this to do is generate random arithmetic questions using the addition, subtraction and multiplication operators. Plus, for it to loop 10 times and give a score out of 10 at the end.
This
for x in (0,10):
...
runs the code (...) two times: one time with x set to 0, and a second time with x set to 10.
What you really want is this:
for x in range(10):
...
Then x will be 0, 1, ..., 9 and the code runs 10 times.
You are not always converting the input to an integer.
When op == '*' or op == '+', you try to compare against the string returned from input():
guess2 = input("")
String comparisons to numbers are never equal. For op == '-' you correctly convert the answer to an integer first:
guess1 = int(input(""))
Your loop is broken too; you are looping over a tuple containing two values:
for x in (0, 10):
rather than over a range:
for x in range(0, 10):
You'd be far better off avoiding so much repetition in your code; calculate the expression outcome and ask for the answer in one place; that way there are fewer places to make mistakes.
I heard eval was very bad practice in Python because of security issues.
So I was wondering if there is a way I could not use eval in this program.
for _ in range(10):
n1 = random.randint(1, 10)
n2 = random.randint(1, 10)
operator = random.choice("+-*")
question = (n1,operator,n2)
questionNo +=1
useranswer = input(question+" = ")
answer = eval(question)
if useranswer == str(answer):
correct += 1
print('Correct!Your score is, ", correct)
else:
print('Wrong Your score is, ", correct)
You could make a mapping from the symbol of the operator to an actual function that represents that operator:
import operator as op
operator_map = {"+":op.add, "-":op.sub, "*":op.mul}
then just change to
answer = operator_map[operator](n1, n2)
I am supposed to write a program in python that asks the user how many multiplication questions they want, and it randomly gives them questions with values from 1 to 10. Then it spits out the percentage they got correct. My code keeps repeating the same set of numbers and it also doesn't stop at the number the user asked for. Could you tell me what's wrong?
import random
import math
gamenumber = int(input("How many probems do you want?\n"))
num_1 = random.randint(1,10)
num_2 = random.randint(1,10)
def main():
random.seed()
count = 0
while count < gamenumber:
guess = int(input("What is " + str(num_1) + "x" + str(num_2) + "."))
answer = str(num_1*num_2)
correct = guess == answer
if guess == answer:
print("Correct!")
else wrong:
print("Sorry, the answer is", answer, ".")
result = correct/wrong
print("You got ", "%.1f"%result, "of the problems.")
main()
You only assign to num_1 and num_2 once. Their values never change; how can your numbers change? Furthermore, you don't increment count, so its original value is always compared against gamenumber.
You need to assign a new random number to your two variables and increment your counter.
You forgot to increment count in your loop and num_1 and num_2 don't get new values.
Problems you mentioned
My code keeps repeating the same set of numbers
This is no surprise, as you set your num_1 and num_2 (1) outside the main function and (2) outside the main while loop. A simple correction is:
while count < gamenumber:
num_1 = random.randint(1,10)
num_2 = random.randint(1,10)
My code doens't stop at the number asked for:
There again, no surprise, as you never increment the count counter: you always have count < gamenumber.
A simple correction is:
while count < gamenumber:
num_1 = random.randint(1,10)
num_2 = random.randint(1,10)
guess = int(input("What is " + str(num_1) + "x" + str(num_2) + "."))
answer = str(num_1*num_2)
count += 1
Here, the count += 1 means add 1 to count *in place*. You could also do count = count + 1 but it's a bit less efficient as you create a temporary variable (count + 1) that you don't really need.
Other problems
You never define wrong
You define gamenumber outside the function. While it's not an issue in this case, it'd be easier to use gamenumber as an argument of main, as it's the variable that drives the game.
Your result is defined in the loop. You probably want to increment a counter for each good answer and print the result after the main loop.
Your result is calculated as correct/wrong. While I'm sure you meant correct/gamenumber, you have to be extra careful: count and gamenumber are integers, and dividing integers is no the same as dividing floats. For example, 2/3 gives 0, but 2/float(3) gives 0.6666666. So, we'll have to use a float somewhere.
You want to print a percentage: your result should then be result=correct*100./gamenumber.
You don't want to gamenumber to be 0, otherwise your result will be undefined.
So, all in all, your main function should be
def main(gamenumber):
random.seed()
count = 0
correct = 0
while count < gamenumber:
num_1 = random.randint(1,10)
num_2 = random.randint(1,10)
guess = int(input("What is " + str(num_1) + "x" + str(num_2) + "."))
answer = str(num_1*num_2)
count += 1
if guess == answer:
correct += 1
print("Correct!")
else wrong:
print("Sorry, the answer is", answer, ".")
if gamenumber > 1:
result = correct * 100./gamenumber
print("You got ", "%.1f"%result, "of the problems.")
The most glaring issue to me is that you have an infinite loop; you don't increase count anywhere.
You're only generating the question numbers once, before you start looping. You need to generate num_1 and num_2 every time, before the user is asked a question.
You never actually update the count value after initializing it, so your loop will go on forever.
import random
import math
spelling of "problems" is wrong
gamenumber = int(input("How many probems do you want?\n"))
move these next two lines inside the loop
num_1 = random.randint(1,10)
num_2 = random.randint(1,10)
def main():
random.seed()
count = 0
while count < gamenumber:
You can use "What is {}x{}?".format(num1, num2) here.
guess = int(input("What is " + str(num_1) + "x" + str(num_2) + "."))
answer = str(num_1*num_2)
Is this supposed to count the correct answers? should be correct += guess == answer
correct = guess == answer
Do you mean to count the number of wrong answers? wrong += guess != answer
if guess == answer:
print("Correct!")
else wrong: is a syntax error else: #wrong perhaps?
else wrong:
print("Sorry, the answer is", answer, ".")
This isn't how to compute a percentage. You should use correct*100/gamenumber and dedent to match the print()
result = correct/wrong
print("You got ", "%.1f"%result, "of the problems.")
main()
Also you're not incrementing count anywhere. It's easier to just use
for count in range(gamenumber):
instead of the while loop
Python is a procedural language. It executes statements in your method body from top to bottom. This line:
num_1 = random.randint(1,10)
is an assignment statement. It does not equate num_1 with a random process for assessing its value; it evaluates an expression - by calling random.randint(1,10) - and assigns that value to num_1, once.
You must force another call to random.randint to obtain another random number, and you must have a statement assign a value to num_1 each time you want num_1's value to change.
Write a multiplication game program for kids. The program should give the player ten randomly generated multiplication questions to do. After each, the program should tell them whether they got it right or wrong and what the correct answer is
from random import randint
for i in range (1,11):
num1 = randint (1,10)
num2 = randint (1,10)
print ("Question",i,":",num1,"*",num2,"=", end = " ")
guess = int (input())
answer = num1*num2
if guess == answer:
print ("Right!")
else:
print ("Wrong. The answer is: ",answer)