Python: How to prevent questions with negative answers being randomly generated - python

My task is to create a maths quiz for primary school children. this is what I have done so far:
import random
import math
def test():
num1=random.randint(1, 10)
num2=random.randint(1, 10)
ops = ['+', '-', '*']
operation = random.choice(ops)
num3=int(eval(str(num1) + operation + str(num2)))
print ("What is {} {} {}?".format(num1, operation, num2))
userAnswer= int(input("Your answer:"))
if userAnswer != num3:
print ("Incorrect. The right answer is {}".format(num3))
return False
else:
print ("correct")
return True
username=input("What is your name?")
print ("Welcome "+username+" to the Arithmetic quiz")
correctAnswers=0
for question_number in range(10):
if test():
correctAnswers +=1
print("{}: You got {} answers correct".format(username, correctAnswers))
What I now need to do is make my program only create questions with positive answers. e.g nothing like 3-10=-7
I've tried searching everywhere online but I cant find anything so I've turned to you guys for help. Any help will be appreciated :)

What I would recommend is:
#Random code...
if num1<num2:
num1, num2 = num2, num1
#Rest of program
So that 3 - 7 = -4 becomes 7 - 3 = 4
The reason I recommend doing this is that the answer would still be the same as the previous equation, just positive instead of negative, so you are still testing the same numbers.

Keep the larger number on the left of the expression, also use operator instead of eval:
from operator import add, sub, mul
def test():
num1 = random.randint(1, 10)
num2 = random.randint(1, 10)
d = {"+": add, "-": sub, "*": mul}
operation = random.choice(list(d)))
num1 = max(num1, num2)
num2 = min(num1, num2)
num3 = d[operation](num1, num2)
print("What is {} {} {}?".format(num1, operation, num2))
userAnswer = int(input("Your answer:"))
if userAnswer != num3:
print("Incorrect. The right answer is {}".format(num3))
return False
else:
print("correct")
return True
username = input("What is your name?")
print("Welcome {} to the Arithmetic quiz".format(username))
correctAnswers = sum(test() for question_number in range(10))
print("{}: You got {} answers correct".format(username, correctAnswers))
Or as #jonclements suggests sorting will also work:
num2, num1 = sorted([num1, num2])
On another note you should really be using a try/except to verify the user input and cast to an int otherwise the first value that cannot be cast to an int your program will crash.

You can choose the numbers such that num2 will be between 1 and num1 like:
num1=random.randint(1, 10)
num2=random.randint(1, num1)
or that num1 > num2:
n1=random.randint(1, 10)
n2=random.randint(1, 10)
num1 = max(n1,n2)
num2 = min(n1,n2)
i would go with the first option. no extra variables, no extra lines.

after the code that chooses the random numbers you can add this while loop:
while num3<0:
num1=random.randint(1, 10)
num2=random.randint(1, 10)
ops = ['+','-','*']
operation = random.choice(ops)
num3=int(eval(str(num1) + operation + str(num2)))
It will enter this loop every time the answer is negative. This will ensure that the answer is positive when the program quits the loop.

A change in one line should do it:
if num1 > num2:
num3=int(eval(str(num1) + operation + str(num2)))
else:
num3=int(eval(str(num2) + operation + str(num1)))

Related

Recursion output isn't printing

I'm new to python and trying to understand recursion. I'm trying to write a code where someone inputs 2 numbers (Num1, Num2). A calculation will take place until Num1 is greater than Num 2. The result of the calculation's final value should then be outputted.
This is my code:
def Recursive(Num1, Num2):
if Num1 > Num2:
return(10)
else:
if Num1 == Num2:
return(Num1)
else:
return(Num1+Recursive(Num1 * 2, Num2))
Num1=input("Enter number 1: ")
Num2=input("Enter number 2: ")
print("Final value: ", Recursive(Num1, Num2))
This is the output that comes out:
Enter number 1: 1
Enter number 2: 15
That's it. There's no output of my print statement. I'm confused as to what I'm doing wrong here and what I should do.
def Recursive(Num1, Num2):
if Num1 > Num2:
return 10
if Num1 == Num2:
return Num1
print(Num1, Num2)
return Num1 + Recursive(Num1 * 2, Num2)
Num1=int(input("Enter number 1: "))
Num2=int(input("Enter number 2: "))
print("Final value: ", Recursive(Num1, Num2))
This should be working code, the reason why your code was not working was because without the int in Num1 = int( input("") ) the program was reading the number as a string. As a result instead of getting 2 from Num1 * 2 when Num1 is 1 you got 11 as it was multiplying a string instead of an integer.
# Here is an example
a = input("Input a number: ")
b = int(input("input a number: "))
print(f"a is a:{type(a)}\n b is a:{type(b)}")
print(f"{a * 2}\n{b * 2}")
Copy the code above input the two numbers and it should give you a better understanding of what I just said.

Python programming question - numbers and integers and division

Divisible challenge
Write a program that asks the user for two numbers. The program should output whether the two numbers are exactly divisible by each other. If not, it should return the remainder. If the user enters a 0 the program should give an error message.
so far I've done this:
num1 = int(input("Enter a number: "))
num2 = int(input("Enter a number: "))
answer1 = num1/num2
answer2 = num2/num1
if num1/num2 == answer1(int) or num2/num1 == answer2(int):
print("Exactly divisible")
elif num1 == 0 or num2 == 0:
print("Error: you cannot divide by 0")
elif num1/num2 != answer1(int) or num2/num1 != answer2(int):
print("Not Exactly divisible")
please help...
I would approach this way
first check the zero case, in that case the code terminates faster
num1 = int(input("Enter a number: "))
num2 = int(input("Enter a number: "))
# answer1 = num1/num2
# answer2 = num2/num1
def divisible_by_each_other(num1, num2):
if (num1 == 0) or (num2==0):
print("Error do not enter 0")
#check divisibility
elif (num1%num2 == 0 ) or (num2%num1 == 0 ):
print("Exactly divisible")
else:
print("Not Exactly divisible")
high,low= max(num1,num2),min(num1,num2)
print("The remainder is ", high%low)
divisible_by_each_other(num1, num2)
answer1(int) is not the correct way to convert to an integer, it's int(answer1).
Since you already divided the numbers, you could use
if answer1 == int(answer1) or answer2 == int(answer2):
But you're making this much more complicated than it needs to be. Modulus is a simpler way to test divisibility.
if num1 % num2 == 0 or num2 % num1 == 0
You also should check if either of the numbers is zero before you try to use division or modulus. Otherwise, you'll get an error due to trying to divide by 0, which is what you're trying to prevent with this check.
If they're not divisible by each other, get the remainder of the larger divided by the smaller:
else:
return max(num1, num2) % min(num1, num2)
Here's the full, simplified code:
num1 = int(input("Enter a number: "))
num2 = int(input("Enter a number: "))
higher = max(num1, num2)
lower = min(num1, num2)
if num1 == 0 or num2 == 0:
print("Error: you cannot divide by 0")
elif higher % lower == 0
print("Exactly divisible")
else:
print(higher % lower)

Do i have to create nested loops or can i do it with the try function?

Can someone explain to me why is asks for an input the second time someone enters an operator and a number?
It is an calculator and i want to except the Valueerror the sedcond time but the code always repeats twice and doenst exit the try function.
Can someone please help me in the right direction?
import locale
## Defining the calculator functions
def add(num1, num2):
return num1 + num2
def subtract(num1, num2):
return num1 - num2
def multiply(num1, num2):
return num1 * num2
def divide(num1, num2):
return num1 / num2
## Asking for the first user input
while number_2 = None :
try:
operation, number_2 = input('''
Starting at zero
Please enter an operator and a number
Enter: ''').split()
continue
except ValueError:
print('Please put a space between the operator and the number!')
else:
break
##Making the input calculatable
number_1 = float(0)
number_2 = float(number_2)
## Calculating the outcome
i = 0
while i < 1:
if operation == '+':
number_1 = add(number_1, number_2)
print('Answer is: ', round(number_1, 4))
elif operation == '-':
number_1 = subtract(number_1, number_2)
print('Answer is: ', round(number_1, 4))
elif operation == '*':
number_1 = multiply(number_1, number_2)
print('Answer is: ', round(number_1, 4).format)
elif operation == '/':
number_1 = divide(number_1, number_2)
print('Answer is: ', round(number_1, 4))
else:
print("Invalid input")
## Asking for the second number
try:
operation, number_2 = input('''
Starting at the previous outcome
Please enter an operator and a number
Enter: ''').split()
except ValueError:
print('nee gap')
number_2 = float(number_2)
if operation == 'q':
break
enter image description here
You've written continue in the first try section, which means, if the condition is satisfied, it'll continue the loop again, and check for number_2 and if the input is correct, again it will continue the loop. So try deleting the continue statement, if the error is occured, it'll directly go to except section
Also, you've to write == to compare the values in while number_2 == None
And you've to define number_2 and operation before using it in while loop. It'll give you error that number_2 is not defined
result=0
while True:
a=input("Enter operator and number= ")
if len(a)>=2 and a[0] in ["+","-","*","/"]:
h=int(a[1::])
if a[0]=="+":
result+=h
elif a[0]=="-":
result-=h
elif a[0]=="*":
result*=h
elif a[0]=="/":
result/=h
else:
print("choose only from +-/*")
else:
print("invalid input")
ch=input("Enter more?")
if ch=='n':
break
print(f"The result is {result}")
Here, the user has to input both parameters as well as the number, I'm taking it as a string because you can traverse it later on and can seperate the operator and number. Initial result is 0. As the user puts the input, we'll traverse the string and seperate number and operator, (say "+9") operator will be <input>[0] and number will be int(<input>[1::]). Now we have seperated the numbers. Let's check for operator using if condition and calculate according. Hope this answer satisfies your aim, if not let me know your aim, I'll surely design a new one

Why doesn't my Python calculator print the results its functions return? [duplicate]

This question already has answers here:
Class return statement not printing any output
(1 answer)
Why doesn't Python print return values?
(3 answers)
Closed 3 years ago.
I am a beginner with Python and am trying to write my first calculator program. However, the test that I set up for it did not work. It asked me for the operation and the numbers, but it didn't print the result. Why not?
I have tried rewriting it in different ways, but it still doesn't work.
def add(num1, num2):
print(str(num1+num2))
def sub(num1, num2):
return str(num1-num2)
def mul(num1, num2):
return str(num1*num2)
def div(num1, num2):
return str(float(num1)/float(num2))
def main():
operation = input("What operation would you like to perform? add, sub, mul or div: ")
num1 = input("What is number 1? ")
num2 = input("What is number 2? ")
if (operation == 'add'):
add(num1, num2)
main()
I expected it to ask what the operation I wanted to perform was, then to ask what the numbers were, and then to print the result. Instead, it does all of those, except print the result. Please could somebody point out where I have gone wrong. NB: I only put in a case for 'add' because I was just testing it.
it does all of those, except print the result
The simplest answer is that it's because you didn't tell it to. Python only prints things out that you tell it to when you write print(<something>) in your code.
When you write add(num1, num2), it is computing the result, but then you aren't doing anything with that result. You could, for instance, do this:
answer = add(num1, num2)
print(answer)
This declares a variable to store the result, so that it isn't lost. And then prints it.
Beyond the immediate question you have about printing the result, you will find that the value you get from input() is a string, not a number. Your add() function will do num1 + num2 but since these are strings, it is actually concatenating (joining) them, like "3" + "4" = "34" which is not what you want.
You should make be sure to convert your inputs to numbers with int() or float(). And I would recommend not having the str() call inside add(). The print() function can print numbers just fine.
num1 = input("What is number 1? ")
input() returns a string, so you need to convert both inputs to int()s so they can have mathematical operations performed.
Here is a working example of your calculator:
def add(num1, num2):
return num1+num2
def sub(num1, num2):
return num1-num
def mul(num1, num2):
return num1*num2
def div(num1, num2):
return num1/num2
def main():
operation = raw_input("What operation would you like to perform? add, sub, mul or div: ")
num1 = float(input("What is number 1? "))
num2 = float(input("What is number 2? "))
if (operation == 'add'):
print(add(num1, num2))
elif (operation == 'sub'):
print(sub(num1, num2))
elif (operation == 'mul'):
print(mul(num1, num2))
elif (operation == 'div'):
print(div(num1, num2))
else:
print("Error: no such operation")
main()
Note: for your operation, you have to use raw_input instead of input.

Random Maths Program

thanks for taking time to read this.
I have to create a program that generates 10 random maths questions based around =, - and *. I have the program working but everytime I run it after the main program it prints "none" even though that's not in my program.Any help at all would be much appreciated. Thank you.
import random
print ("Welcome")
name=input("What's your name?")
print("Nice to meet you", name, ",you will be given 10 multiplication, addition and subtraction questions.")
Num1 = random.randint(1,12)
Num2 = random.randint(1,12)
sign = random.randint(1,3)
if sign == 1: # If the random number generated is 1
question = Num1 + Num2
rightanswer1 = Num1 + Num2
answer1=input(print("What is", question ,"?"))
if answer1 == rightanswer1:
print("Well Done!")
if answer1 != rightanswer1:
print("Sorry, that's incorrect, the answer was", rightanswer1)
if sign == 2:
question = Num1 - Num2
rightanswer2 = Num1 - Num2
answer2=input(print("What is", Num1, "-", Num2 ,"?"))
if answer2 == rightanswer2:
print("Well done!")
elif answer2 != rightanswer2:
print("Sorry, that's incorrect, the answer was", rightanswer2)
if sign == 3:
question = Num1 * Num2
rightanswer3 = Num1 * Num2
answer3=input(print("What is", Num1, "x", Num2 ,"?"))
if answer3 == rightanswer3:
print("Well done!")
elif answer3 != rightanswer3:
print("Sorry, that's incorrect, the answer was", rightanswer3)`
> Welcome
> What's your name? John
> Nice to meet you John ,you will be given 10 multiplication, addition and subtraction questions.
> What is 12 x 3 ?
> None 36
> Sorry, that's incorrect, the answer was 36
I think you are using python 3. In python 3 input is like raw_input in python 2. So you get the string as input. So convert it into int
var = int(input("Enter a number: "))
So in your code make it as
print("What is", Num1, "x", Num2 ,"?")
answer3 = input()
answer3 = int(answer3)
See this:
whats-the-difference-between-raw-input-and-input-in-python3-x
I'm reluctant to just give you an answer that just does it for you, so instead i'll provide you with a few hints to improve things. (i.e. this isn't an answer, just too large of a comment - and more like a codereview answer)
First off, you use a structure like this:
if x == 1:
#do something
if x == 2:
#do something else
...
In this case, which it makes no difference, it is easier to read if you use the if syntax as intended:
if <condition>:
#do this if the above test is true.
elif <more conditions>:
#do this only if the first test is false and this one is true
elif <more conditions>:
#same as above, except for the second test must be false too
else:
#do this if all the above tests are false
So you could use this something like:
if sign == 1:
...
elif sign == 2:
...
elif sign == 3:
...
else:
# something weird happened...
Which would make that section of the program easier to follow.
The same thing can be done with the if answer1 == rightanswer1: sections;
if answer1 == rightanswer1:
#correct!
else:
#incorrect.
That would be a clearer was to do it. You seem to have used the if...elif style in a couple of them, but not the first one.
Once you have this, it will be a little clearer.
The next way you could improve things is by removing duplicated code. You don't need separate branches for each sign, you can just roll it all into one:
number1 = randint(1,12)
number2 = randint(1,12)
op = randint(1,3)
question_string = "%d %s %d = ?" % (number1, number2, ["+", "-", "*"][op])
result = None
if op == 1:
result = number1 + number2
elif op == 2:
result = number1 - number2
elif op == 3:
result = number1 * number2
This will do most of the logic for you, and generate the strings you want, without duplicating all of the other code.
Small changes like this can make things much more readable.
It's printing None because the print() function returns None and you're passing that value of None from print() as the prompt to your input() functions. Eg,
answer3=input(print("What is", Num1, "x", Num2 ,"?"))
So print("What is", Num1, "x", Num2 ,"?") prints its stuff, and returns None, which then gets printed as the prompt by input().
A simple way to fix this is to just move your print() function calls out of your input() functions.
Eg,
print("What is", Num1, "x", Num2 ,"?")
answer3=input()
However, there's another major problem with your program: the rightanswer variables are ints, but the inputted answers are strings. To compare them properly they need to be the same type. So you should either convert the inputted answers to int, or alternatively, convert the rightanswers to str.
There are two problems with how you use the input function:
You misuse the prompt argument
You forget to convert the result
First, have a better look at the reference of the input function
The prompt argument
input takes a string as argument that will be displayed ("prompted") to the user to indicate that the program is waiting an input. The print function also displays a string to the user, but it doesn't return anything. It does its job and that's all (and in Python a function that returns nothing, returns None). That's what input gets to display, so it displays None. You should use format instead. It will format and return the formatted string that input can display:
answer1_as_str=input("What is {} ?".format(question))))
or
answer2_as_str=input("What is {:d} - {:d} ?".format(Num1, Num2)))
The return value
input returns the user input as a string contrary to python 2 (i.e. exactly as entered). So you have to convert the input to the desired type if you need it. If you type 10 for example, the input will return "10". If you need an int, you have to convert it yourself.
answer1 = int(answer1_as_str)
It looks like you don't really understand how input() works. You might also want to review the different datatypes and conditional statements. Other than that, it was a very good attempt. Here's my solution:
from random import randint
print("Welcome")
name = input("What's your name?\n")
print("Nice to meet you " + name + ", you will be given 10 multiplication, addition and subtraction questions.")
for i in range(10):
print("\nProblem " + str(i+1))
num1 = randint(1,12)
num2 = randint(1,12)
sign = randint(1,3)
if sign == 1:
question = str(num1) + " + " + str(num2)
answer = num1 + num2
elif sign == 2:
question = str(num1) + " - " + str(num2)
answer = num1 - num2
else:
question = str(num1) + " x " + str(num2)
answer = num1 * num2
user_answer = input("What is " + question + "? ")
if user_answer == str(answer):
print("Well done!")
else:
print("Sorry, that's incorrect, the answer was", answer)

Categories

Resources