Make python ask questions from strings - python

I want to make python ask questions to the user - from random variables in lists.
It needs to ask the question requiring an input from the user.
This is my code so far:
import time
import random
question = "0"
score = "0"
name = input("What is your full name?")
print ("Hello " + name, "welcome to The Arithmetic Quiz")
time.sleep(2)
numbers = list(range(1, 50))
operators = ["+", "-", "*"]
numbers1 = list(range(1,10))
print(str(random.choice(numbers)) + random.choice(operators) + str(random.choice(numbers1)))`
How would I make the last line of code ask a question and get an input from the user?
Also how would I make it so that python says whether this is correct when I do not know what python will ask?

The answer is already in your code.
user_input = input(str(random.choice(numbers)) + random.choice(operators) + str(random.choice(numbers)) + "? ") should work.
It gets a sample random number from numbers, gets a random operator from operators, gets another random number from numbers, and stores the input to the variable user_input.
To get Python to check your answer, store the randomly generated arguments inside variables and check them. (If there is a better way of doing this, I would appreciate it if someone pointed it out to me).
operand1 = random.choice(numbers)
operand2 = random.choice(numbers)
operator = random.choice(operators)
if operator == '+':
answer = operand1 + operand2
elif operator == '-':
answer = operand1 - operand2
else:
answer = operand1 * operand2
user_input = input(str(operand1) + operator + str(operand2) + "? ")
if str(answer) == user_input:
print('Correct!')
else:
print('Wrong!')
EDIT: #mhawke's answer has a better way of storing and manipulating the operands. Instead of storing the operators in a list, store them in a dict and map them to their corresponding operator function as so:
import operator
operators = {"+": operator.add, "-": operator.sub, "*": operator.mul}
operand1 = random.choice(numbers)
operand2 = random.choice(numbers)
op = random.choice(operators)
expected_answer = op(operand1, operand2)
Documentation for operator.

For the second part of your question, how to determine whether the user entered the correct answer, you can store the randomly selected values and evaluate the resulting expression. Then compare that to the user's value:
import operator
operators = {"+": operator.add, "-": operator.sub, "*": operator.mul}
operand1 = random.choice(numbers)
operand2 = random.choice(numbers1)
op = random.choice(operators)
expected_answer = op(operand1, operand2)
user_answer = input('{} {} {} = ?: '.format(operand1, op, operand2)
if int(user_answer) == expected_answer:
print('Correct!')
else:
print('Wrong. The correct answer is {}'.format(expected_answer)
The operators are stored in a dictionary. The operator tokens (+, -, *) are the keys in this dictionary, and the values are functions from the operator module that perform the operations. Using a dictionary like this is very flexible because if you wanted to support a new operator, e.g. division, you can just add it to the operators dictionary:
operators = {"+": operator.add, "-": operator.sub, "*": operator.mul, '/': operators.div}

Related

Input Loop - Dictionary Lookup and Recursion Calculator in Python

brand new at Python, and been experimenting with various calculator code methods in Python.
I found the following code:
from operator import pow, truediv, mul, add, sub
operators = {
'+': add,
'-': sub,
'*': mul,
'/': truediv
}
def calculate(s):
if s.isdigit():
return float(s)
for c in operators.keys():
left, operator, right = s.partition(c)
if operator in operators:
return operators[operator](calculate(left), calculate(right))
calc = input("Type calculation:\n")
print("Answer: " + str(eval(calc)))
and I'm just wondering how one would formulate an input loop for this one.
from operator import pow, truediv, mul, add, sub
operators = {
'+': add,
'-': sub,
'*': mul,
'/': truediv
}
def calculate(s):
if s.isdigit():
return float(s)
for c in operators.keys():
left, operator, right = s.partition(c)
if operator in operators:
return operators[operator](calculate(left), calculate(right))
cont = 'y'
while cont.lower() == 'y':
calc = input("Type calculation:\n")
print("Answer: " + str(eval(calc)))
cont = input("Do you want to continue? (y/n)")
It would be good to add more validations to the code... like ensuring that only one operator exists and that there are numbers on either side of the operator inside the calc function.
Also, you are importing power but don't have a symbol for it. Can use '^' if you haven't already? It is easier than using '**' which python uses.
The script will ask you continuosly for operation to compute as follows:
while True:
calc = input("Type calculation (C to exit):\n")
if calc.upper().strip() == "C":
break
print("Answer: " + str(eval(calc)))
Note that, as it is, the code is extremely fragile, given that anything which cannot be reconducted to a number operator number pattern (or "C"), will need to be treated. You could use pattern matching to check if the operation is valid before passing to eval first, and manage bad cases as you wish.

How to make a python calculator with that can add , subtract , multiply , divide , powers and modulo on more more than two numbers

i'm quite new at Python and I wondered how to make a calculator that i can add, subtract, multiply, divide and other operators on more than two numbers . I would be thankful if you gave me an explanation. I'm questioning because I have in my mind an awful and inefficient method of doing this , that being adding more elif tags for more operators and more numbers
TL:DR (i guess) :
i thinked about making a calculator made with python that has options for more operator and numbers ( but i don't know how to make a simpler one :
i.e.:30 + 30 * 30.
67.874 / 20.
69 + 69 + 69 + 69 + 69 + 69.
30 ** ( i think this is a power operator ) 2.
etc.
I can help you if you didin't understand what i want , you can question me
this is my normal calculator without input of more than two numbers and one operator
def add(x, y):
return x + y
def subtract(x, y):
return x - y
def multiply(x, y):
return x * y
def divide(x, y):
return x / y
num1 = float(input("Enter a number :"))
op = input("Enter your selected operator :")
num2 = float(input("Enter another number :"))
if op == "+":
print(num1, "+", num2, "=", add(num1, num2))
elif op == "-":
print(num1, "-", num2, "=", subtract(num1, num2))
elif op == "*":
print(num1, "*", num2, "=", multiply(num1, num2))
elif op == "/":
print(num1, "/", num2, "=", divide(num1, num2))
else:
print("Invalid input")
I know this comment/answer code isn't having indenting , but stack woudn't let me post with indenting and the file itself does have indenting so idk
result = None
operand = None
operator = None
wait_for_number = True
while True:
if operator == '=':
print(f"Result: {result}")
break
elif wait_for_number == True:
while True:
try:
operand = float(input("Enter number: "))
except ValueError:
print("Oops! It is not a number. Try again.")
else:
if result == None:
result = operand
else:
if operator == '+':
result = result + operand
elif operator == '-':
result = result - operand
elif operator == '*':
result = result * operand
elif operator == '/':
result = result / operand
break
wait_for_number = False
else:
while True:
operator = input("Enter one of operators +, -, *, /, =: ")
if operator in ('+', '-', '*', '/', '='):
break
else:
print("Oops! It is not a valid operator. Try again.")
wait_for_number = True
your question isn’t clear enough, but if I got it right than this should work. Important to note: using the eval() function is not a good practice since it can be really dangerous if the inputs are not coming from you. Here are some of the dangers of it: https://nedbatchelder.com/blog/201206/eval_really_is_dangerous.html
The code:
# the function takes an operator as a string like: “*” and multiple numbers thanks to the * (args) operator.
def calculate(operator, *numbers):
result = numbers[0]
#the for cycle goes through all numbers except the first
for number in range(1, len(numbers)):
#the eval() function makes it possible to python to interpret strings as a code part
result = eval(f"{result} {operator} {str(numbers[i])}")
print(result)
Here is the code without eval().
import operator
# the function takes an operator as a string like: “*” and multiple numbers thanks to the * (args) operator.
def calculate(op, *numbers):
# binding each operator to its string counterpart
operators = {
"+": operator.add,
"-": operator.sub,
"*": operator.mul,
"/": operator.truediv
}
result = numbers[0]
#the for cycle goes through all numbers except the first
for number in range(1, len(numbers)):
# carrying out the operation, using the dictionary above
result = operators[op](result, numbers[number])
print(result)

Need help making this Calculator in Python3

import operator
num1 = float(input("Enter first number: "))
operation = ("")
ops = {
"+" : operator.add,
"_" : operator.add,
"*" : operator.mul,
"/" : operator.div
}
while operation != ops:
operation = input("Enter operator: ")
print("false entry")
num2 = float(input("Enter second number:"))
result = (float(num1) + ops + float(num2))
print(result)
I'm trying to make the operator, if the input is not a operator, repeat and ask to retype is until it is equal to one of the operations listed in the dictionary.
I only started coding like 4 days ago and don't really know what the problem is. I'd be happy if anyone could help me.
Nice try! There are a few problems here...
In ops, you should change the second key/value pair to include subtraction, maybe you are looking for something like this:
ops = {
"+" : operator.add,
"-" : operator.sub,
"*" : operator.mul,
"/" : operator.div
}
When asking for the operator, you must check if operator is in ops keys. You are now checking if operator is equal to ops dictionary. As pointed out by #Ayam It could be something like this:
operation = input("Enter operator: ")
while operation not in ops:
print("false entry")
operation = input("Enter operator: ")
Finally, there is a problem when making the calculation. Once you have the operation and you are sure it is in ops keys, you can use the value (in this case, a function) linked to that key:
result = ops[operation](num1, num2)
print('result is', result)
Hope this helps! Keep learning! :)
You are close! Try this:
operation = input("Enter operator: ")
while operation not in ops:
print("false entry")
operation = input("Enter operator: ")
What goes wrong in your code is that the operation variable is compared to the dictionary called ops. By checking 'operator in ops' you check if operator corresponds to one of the keys of ops.
try this:
import operator
num1 = float(input("Enter first number: "))
operation = ("")
ops = {
"+" : operator.add,
"_" : operator.add,
"*" : operator.mul,
"/" : operator.truediv
}
while operation not in ops:
operation = input("Enter operator: ")
if(operation not in ops):
print("false entry")
num2 = float(input("Enter second number:"))
result = (ops.get(operation)(float(num1),float(num2)))
print(result)
Few changes:
while operation != ops: is comparing a string to a whole dict so extract the keys out first and then compare
while operation not in ops:
You only print "False entry" if operation is not valid so:
if(operation not in ops):
print("false entry")
Why are you adding the dict and the 2 values here
result = (float(num1) + ops + float(num2))
You want to use the operator function. The value part of the dict so you have to extract it with dict.get(key). Also the operator functions requires both the argument so do this:
`result = (ops.get(operation)(float(num1),float(num2)))`
Example:
ops.get("+")(2,2) returns operator.add(2,2) = 4
import operator
num1 = float(input("Enter first number: "))
ops = {"+" : operator.add, "_" : operator.add,"*" : operator.mul,"/" : operator.truediv}
operation = input("Enter operator: ")
while True:
if operation not in ops:
print("Wrong input")
operation=input("Enter operator: ")
else:
break
num2 = float(input("Enter second number:"))
result = ops[operation](num1, num2)
print('result is', result)

Python Invalid Syntax on simple Maths Program

I am trying to create a random maths question quiz but the colon comes up as invalid syntax. Is it due to the operator I can not use the colon? If I take it out it is also seen as invalid syntax.
This is the code to create the 'correct_answer' variable so if the users in putted answer is correct or incorrect it lets them know. If the whole code is needed (which I'm sure it won't be as this is probably something really stupid i'm missing) I can post it.
if operator==+:
correct_answer=random_number1+number2
elif operator==-:
correct_answer=random_number1-number2
else:
correct_answer=random_number1*number2
FULL CODE:
import random
name=raw_input("Hi what's your name?")
print "Alrighty lets go, "+name+"!"
for i in range(10):
operator_list=('+','-','x')
operator=random.choice(operator_list)
random_number1=random.randint(1,12)
random_number2=random.randint(1,10)
question=1
print random_number1, operator, random_number2
if operator==+:
correct_answer=random_number1+number2
elif operator==-:
correct_answer=random_number1-number2
else:
correct_answer=random_number1*number2
answer = eval(str(int(raw_input("What is the answer?"))))
if answer==correct_answer:
print "Great job!"
else:
print"Unlucky pal! It was " +correct_answer+ "
question+1
I'm assuming that + and - are strings. If so, you need quotes around them. It's also good practice to space out your code to make it more legible.
if operator == '+':
correct_answer = random_number1 + number2
elif operator == '-':
correct_answer = random_number1 - number2
else:
correct_answer = random_number1 * number2
ANSWER: All that was needed were speech marks around the operator.
if operator == "+":
correct_answer=random_number1+number2
elif operator == "-":
correct_answer=random_number1-number2
else:
correct_answer=random_number1*number2
Ans:
When you wrote + and - , python took it as a real for integer operator and gave it an error because there were no numbers. Adding " " will define it as a string and should not give a error.
Corrected version:
if operator == "+":
correct_answer=random_number1+number2
elif operator == "-":
correct_answer=random_number1-number2
else:
correct_answer=random_number1*number2

How to do a calculation on Python with a random operator

I am making a maths test where each question will be either adding, multiplying or subtracting randomly chosen numbers. My operator will be chosen at random, however I cannot work out how to calculate with the operator. My problem is here:
answer = input()
if answer ==(number1,operator,number2):
print('Correct')
How can I make it so the operator is used in a calculation. For example, if the random numbers were two and five, and the random operator was '+', how would I code my program so that it would end up actually doing the calculation and getting an answer, so in this case it would be:
answer =input()
if answer == 10:
print('Correct')
Basically, how can I do a calculation to check to see if the answer is actually correct?
My full code is below.
import random
score = 0 #score of user
questions = 0 #number of questions asked
operator = ["+","-","*"]
number1 = random.randint(1,20)
number2 = random.randint(1,20)
print("You have now reached the next level!This is a test of your addition and subtraction")
print("You will now be asked ten random questions")
while questions<10: #while I have asked less than ten questions
operator = random.choice(operator)
question = '{} {} {}'.format(number1, operator, number2)
print("What is " + str(number1) +str(operator) +str(number2), "?")
answer = input()
if answer ==(number1,operator,number2):
print("You are correct")
score =score+1
else:
print("incorrect")
Sorry if I have been unclear, thanks in advance
Use functions in a dictionary:
operator_functions = {
'+': lambda a, b: a + b,
'-': lambda a, b: a - b,
'*': lambda a, b: a * b,
'/': lambda a, b: a / b,
}
Now you can map an operator in a string to a function:
operator_functions[operator](number1, number2)
There are even ready-made functions for this is the operator module:
import operator
operator_functions = {
'+': operator.add,
'-': operator.sub,
'*': operator.mul,
'/': operator.truediv,
}
Note that you need to be careful about using variable names! You used operator first to create a list of operators, then also use it to store the one operator you picked with random.choice(), replacing the list:
operator = random.choice(operator)
Use separate names here:
operators = ["+","-","*"]
# ...
picked_operator = random.choice(operators)
You are looking for the eval function. eval will take a string with math operators and compute the answer. In your final if statement check it like this...
if answer == eval(question):
import operator
import random
operators = {
"+": operator.add,
"-": operator.sub,
"/": operator.truediv,
"*": operator.mul
}
y = float(input("Enter number: "))
z = float(input("Enter number: "))
x = random.choice(operators.keys())
print (operators[x](y, z))
Use the operator lib, creating a dict with operators as keys and the methods as values.
from operator import add, mul, sub
import random
score = 0 # score of user
questions = 0 # number of questions asked
operators = {"+": add, "-": sub, "*": mul}
print("You have now reached the next level!This is a test of your addition and subtraction")
print("You will now be asked ten random questions")
# create list of dict keys to pass to random.choice
keys = list(operators)
# use range
for _ in range(10):
number1 = random.randint(1, 20)
number2 = random.randint(1, 20)
operator = random.choice(keys)
# cast answer to int, operators[operator]will be either add, mul or sub
# which we then call on number1 and number2
answer = int(input("What is {} {} {}?".format(number1,operator, number2)))
if answer == (operators[operator](number1, number2)):
print("You are correct")
score += 1
else:
print("incorrect")
You need to cast answer to int a string could never be equal to an int.
In the code random.choice(keys) will pick one of the three dicts keys * - or +, we do a lookup on the dict with operators[operator] i.e operators["*"] returns mul we can then call mul(n1,n2) on the two random numbers.
You also need to move the number1 = random.randint(1, 20).. inside the while loop or you will end up asking the same questions and you can pass the string to input, you don't need to print.
For your specific case, instead of making the dictionary, I would just create a list of tuples with the operator string representation and the operator builtin function:
import operator
import random
operators = [('+', operator.add), ('-', operator.sub), ('*', operator.mul)]
for i in range(10):
a = random.randint(1, 20)
b = random.randint(1, 20)
op, fn = random.choice(operators)
print("{} {} {} = {}".format(a, op, b, fn(a, b)))
14 * 4 = 56
6 + 12 = 18
11 + 11 = 22
7 - 9 = -2
9 - 4 = 5
17 * 5 = 85
19 - 13 = 6
9 - 4 = 5
20 * 20 = 400
5 * 3 = 15
Random.choice on your list will return a tuple that you can unpack into the operator str representation and the function that you can call.
import operator
import random
score = 0
operators = [('+', operator.add), ('-', operator.sub), ('*', operator.mul)]
for i in range(10):
a = random.randint(1, 20)
b = random.randint(1, 20)
op, fn = random.choice(operators)
prompt = "What is {} {} {}?\n".format(a, op, b)
if int(input(prompt)) == fn(a, b):
score += 1
print("You are correct")
else:
print("incorrect")
print("Score: {}".format(score))

Categories

Resources