i want to add code that rejects any invalid answers [duplicate] - python

This question already has answers here:
Asking the user for input until they give a valid response
(22 answers)
Closed 10 months ago.
#for project 2
# division
def divide(a, b):
return (a / b)
# palindrome
def isPalindrome(s):
return s == s[::-1]
print("Select operation.")
print("1. Divide")
print("2. Palindrome")
print("3. Square root")
while True:
choice = input("Enter choice(1/2/3): ")
if choice == '1':
num1 = float(input("Enter first number: "))
num2 = float(input("Enter second number: "))
print(num1, "/", num2, "=", divide(num1, num2))
elif choice == '2':
def isPalindrome(s):
return s == s[::-1]
s = str(input("Enter word:"))
ans = isPalindrome(s)
if ans:
print (s+" "+"is a palindrome.")
else:
print (s+" "+"is not a palindrome.")
elif choice == '3':
threenumber = float(input("Enter a number: "))
sqrt = threenumber ** 0.5
print ("The square root of " + str(threenumber) + " is " + "sqrt", sqrt)
next_calculation = input("Let's do next calculation? (yes/no): ")
if next_calculation == "no":
break
else:
print("Invalid Input")
When testing it myself, in the beginning, if I entered any other input rather than 1, 2, or 3, it would jump to the "next_calculation" function. I want it to say "That's not an option, silly." instead.
When I select 1 or 3 if I enter anything other than a number the program will stop. I want it to say "That's not a valid number, silly."
How do I do this?

You can do that with continue to ignore the loop and return to the start after checking if the input is in your list of possible values
if choice not in ('1', '2', '3'):
print("Invalid input")
continue
Put that after the input

I'd add right after choice = input("Enter choice(1/2/3): "), this snippet:
while (choice not in ['1','2','3']):
print("That's not a valid number, silly.")
choice = input("Enter choice(1/2/3): ")
In this way, you won't reach the end of the cycle unless you give a correct number.

I think you should try to use Switch in this case, instead of if/elses.
Check out this answer.
Otherwise, #Icenore answer seems to be correct. Also, remember to correctly ident your code, your current else: code is being executed after your while True:

Related

How do I repeat the code form the top after a while loop?

I want this code to repeat from the top. Im trying to build a calculator app and when I say "Do you want to continue (y) or go back to home (n): " I want it so that if the user says "n" then it will start the code from the beggining. Here is the code I want to do this in.
# Importing stuff
import math
import random
import time
import numpy as np
def startup():
global ask
print("Welcome to this math python program")
ask = input(
"Do you wnat to solve 1, add, 2, subtract, 3, multiply, divide, or 5 other complex problems? (answer with 1, 2, 3, 4, or 5: "
)
startup()
# Some stuff to make it look better
print(" ")
print(" ")
def add():
print("Addition")
num1 = int(input("First number: "))
num2 = int(input("Second Number: "))
num = num1 + num2
print("The answer is " + str(num))
# Subtract
def subtract():
print("Subtraction")
num3 = int(input("First number: "))
num4 = int(input("Second Number: "))
num5 = num3 - num4
print("The answer is " + str(num5))
print(" ")
def multiply():
print("Multiplication")
num6 = int(input("First number: "))
num7 = int(input("Second Number: "))
num8 = num6 * num7
print("The answer is " + str(num8))
print(" ")
def divide():
print("Division")
num9 = int(input("First number: "))
num10 = int(input("Second Number: "))
num11 = num9 / num10
print("The answer is " + str(num11))
print(" ")
def squareRoot():
print("Square Root")
asksqrt = int(
input("What number would you like to find the square root of: "))
answer1 = math.sqrt(asksqrt)
print("The square root of " + str(asksqrt) + " is: " + str(answer1))
print(" ")
def cubeRoot():
print("Cube root")
num12 = int(input("What number do you want to find the cube root of: "))
cube_root = np.cbrt(num12)
print("Cube root of ", str(num12), " is ", str(cube_root))
print(" ")
def exponent():
print("Exponents")
num13 = int(input("First you are going to tell me the number: "))
num14 = int(input("Next you are going to tell me the exponent: "))
num15 = num13**num14
print(str(num13) + " to the power of " + str(num14) + " is " + str(num15))
print(" ")
# While loops
while ask == "1":
print(" ")
add()
ask4 = input("Do you want to continue (y) or go back to home (n): ")
while ask4 == "y":
add()
while ask == "2":
print(" ")
subtract()
ask5 = input("Do you want to continue (y) or go back to home (n): ")
while ask5 == "y":
add()
while ask == "3":
print(" ")
multiply()
ask6 = input("Do you want to continue? (y/n) ")
while ask6 == "y":
add()
while ask == "4":
print(" ")
divide()
ask7 = input("Do you want to continue (y) or go back to home (n): ")
while ask7 == "y":
add()
while ask == "5":
ask2 = input(
"Do you want to do a 1, square root equation, 2, cube root equation, or 3 an exponent equation? (1, 2, 3): "
)
print(" ")
while ask2 == "1":
print(" ")
squareRoot()
ask8 = input("Do you want to continue (y) or go back to home (n): ")
while ask8 == "y":
add()
while ask2 == "2":
print(" ")
cubeRoot()
ask9 = input("Do you want to continue (y) or go back to home (n): ")
while ask9 == "y":
add()
while ask2 == "3":
print(" ")
exponent()
ask10 = input("Do you want to continue (y) or go back to home (n): ")
while ask10 == "y":
add()
I'm a begginer so I dont know a lot. If you could tell me what I can do better that would be much appreciated.
In this case, it's good to take a step back and think of what your main entrypoint, desired exit scenario and loop should look like. In pseudo-code, you can think of it like this:
1. Introduce program
2. Ask what type of calculation should be conducted
3. Do calculation
4. Ask if anything else should be done
5. Exit
At points 2 and 4, your choices are either exit program or do a thing. If you want to 'do a thing' over and over, you need a way of going from 3 back into 2, or 4 back into 3. However, steps 2 and 4 are basically the same, aren't they. So let's write a new main loop:
EDIT: Decided to remove match/case example as it's an anti-pattern
if __name__ == "__main__": # Defines the entrypoint for your code
current_task = 'enter'
while current_task != 'exit':
current_task = ask_user_for_task() # The user will input a string, equivalent to your startup()
if current_task == 'add': # If its 'add', run add()
add()
elif current_task == 'subtract':
subtract()
else:
current_task = 'exit' # If its 'exit' or anything else not captured in a case, set current_task to 'exit'. This breaks the while loop
ask_user_for_task() will be an input() call where the user gives the name of the function they want to execute:
def ask_user_for_task():
return input("Type in a calculation: 'add', 'subtract', ...")
This answer is not perfect - what if you don't want to exit if the user accidentally types in 'integrate'. What happens if the user types in "Add", not 'add'? But hopefully this gives you a starting point.
What you want to do can be greatly simplified. The number you choose correlates to the index of the operation in funcs. Other than that, the program is so simple that each part is commented.
Using this method eliminates the need for excessive conditions. The only real condition is if it is a 2 argument operation or a 1 argument operation. This is also very easily extended with more operations.
import operator, math, numpy as np
from os import system, name
#SETUP
#function to clear the console
clear = lambda: system(('cls','clear')[name=='posix'])
"""
this is the index in `funcs` where we switch from 2 arg operations to 1 arg operations
more operations can be added to `funcs`
simply changing this number accordingly will fix all conditions
"""
I = 6
"""
database of math operations - there is no "0" choice so we just put None in the 0 index.
this tuple should always be ordered as:
2 argument operations, followed by
1 argument operations, followed by
exit
"""
funcs = (None, operator.add, operator.sub, operator.mul, operator.truediv, operator.pow, math.sqrt, np.cbrt, exit)
#operation ranges
twoarg = range(1,I)
onearg = range(I,len(funcs))
#choice comparison
choices = [f'{i}' for i in range (1,len(funcs)+1)]
#this is the only other thing that needs to be adjusted if more operations are added
menu = """
choose an operation:
1:add
2:subtract
3:multiply
4:divide
5:exponent
6:square root
7:cube root
8:quit
>> """
#IMPLEMENT
while 1:
clear()
print("Supa' Maffs")
#keep asking the same question until a valid choice is picked
while not (f := input(menu)) in choices: pass
f = int(f)
#vertical space
print("")
if f in twoarg: x = (int(input("1st number: ")), int(input("2nd number: ")))
elif f in onearg: x = (int(input("number: ")), )
else : funcs[f]() #exit
#unpack args into operation and print results
print(f'answer: {funcs[f](*x)}\n')
input('Press enter to continue')
if you want to, you can see the code below:
while(input("want to continue (y/n)?") == 'y'):
operation = input("operation: ")
num_1 = float(input("first num: "))
num_2 = float(input("second num: "))
match operation:
case "+":
print(num_1 + num_2)
case "-":
print(num_1 - num_2)
case "*":
print(num_1 * num_2)
case "/":
print(num_1 / num_2)
case other:
pass
make sure you have the version 3.10 or later of python

Return to another part of a loop

I am learning python and I cannot figure out how to get back to a certain part of loop depending on the response.
If it reaches:
else :
print('Answer must be yes or no')
I want it to start back at:
print ("We are going to add numbers.")
I have tried several different suggestions I have seen on here, but they result in starting back at the very beginning.
My code:
import random
num1 = random.randint(1,100)
num2 = random.randint(1,100)
addition = num1 + num2
print("Hello. What is your name?")
name = str(input())
print ("Nice to meet you " + name)
print ("We are going to add numbers.")
print ("Does that sound good?")
answer = str.lower(input())
if answer == str('yes'):
print ('Yay!!')
print ('Add these numbers')
print (num1, num2)
numbers = int(input())
if numbers == addition:
print('Good Job!')
else:
print('Try again')
numbers = int(input())
elif answer == str('no'):
print ('Goodbye')
else :
print('Answer must be yes or no')
You need a loop that starts with the thing you want to get back to:
def start():
import random
num1 = random.randint(1, 100)
num2 = random.randint(1, 100)
addition = num1 + num2
print("Hello. What is your name?")
name = str(input())
print("Nice to meet you " + name)
while True:
print("We are going to add numbers.")
print("Does that sound good?")
answer = str.lower(input())
if answer == "no":
print("Goodbye")
return
elif answer == "yes":
break
else:
print('Answer must be yes or no')
print('Yay!!')
print('Add these numbers')
print(num1, num2)
# This following part might want to be a loop too?
numbers = int(input())
if numbers == addition:
print('Good Job!')
else:
print('Try again')
numbers = int(input())

How to stop loop?

I'm a step away from completing my binary converter, though it keeps on repeating, it's and endless loop.
def repeat1():
if choice == 'B' or choice == 'b':
while True:
x = input("Go on and enter a binary value: ")
try:
y = int(x, 2)
except ValueError:
print("Please enter a binary value, a binary value only consists of 1s and 0s")
print("")
else:
if len(x) > 50:
print("The number of characters that you have entered is", len(x))
print("Please enter a binary value within 50 characters")
z = len(x)
diff = z - 50
print("Please remove", diff, "characters")
print(" ")
else:
print(x, "in octal is", oct(y)[2:])
print(x, "in decimal is", y)
print(x, "in hexidecimal is", hex(y)[2:])
print(" ")
def tryagain1():
print("Type '1' to convert from the same number base")
print("Type '2' to convert from a different number base")
print("Type '3' to stop")
r = input("Would you like to try again? ")
print("")
if r == '1':
repeat1()
print("")
elif r == '2':
loop()
print("")
elif r == '3':
print("Thank you for using the BraCaLdOmbayNo Calculator!")
else:
print("You didn't enter any of the choices! Try again!")
tryagain1()
print("")
tryagain1()
I'm looking for a way to break the loop specifically on the line of code "elif r== '3':. I already tried putting 'break', but it doesn't seem to work. It keeps on asking the user to input a binary value even though they already want to stop. How do I break the loop?
elif r == '3':
print("Thank you for using the BraCaLdOmbayNo Calculator!")
return 0
else:
print("You didn't enter any of the choices! Try again!")
choice = try again()
if choice == 0:
return 0
print("")
tryagain1()
return is suppose to be used at the end of the Function or code when you have nothing else to do

How would I assign the list of operators so that the random numbers are worked out to tell the user if they're correct or not?

How would I assign the list of operators so that the random numbers are worked out to tell the user if they're correct or not?
# Controlled Assessment - Basic Times Table Test
import random
score = 0
print ("Welcome to the times table test")
name = input("Please type your name: ")
print ("How to play")
print ("Step 1: When you see a question work out the answer and type it in the space.")
print ("Step 2: Once you have typed your answer press the enter key.")
print ("Step 3: The program will tell you if you're right or wrong.")
print ("Step 4: The next question will load and you can repeat from step 1.")
print ("When you have answered all 10 questions your final score will be printed.")
for q in range(10):
Number1 = random.randint(1,12)
Number2 = random.randint(1,12)
ListOfOperator = ['+','-','*']
Operator =random.choice(ListOfOperator)
print ('what is' ,Number1,Operator,Number2)
Answer= input ("Please Type Your Answer: ")
realanswer = (Number1,Operator,Number2)
if ListOfOperator:
ListOfOperator=['+'] = Number1+Number2
ListOfOperator=['-'] = Number1-Number2
ListOfOperator=['*'] = Number1*Number2
if Answer==realanswer:
print("Your answer is correct")
score = score + 1
print (score)
else:
print("Your answer is incorrect, the correct answer is.",realanswer,".")
print (score)
The code that needs to assign to the list of operators is...
if ListOfOperator:
ListOfOperator=['+'] = Number1+Number2
ListOfOperator=['-'] = Number1-Number2
ListOfOperator=['*'] = Number1*Number2
It should work out the answer to each question using the function I'm telling the program that if the operator from the operator list is * to work out Number1*Number2
The current output for telling them if the answer is correct or not prints
Your answer is incorrect, the correct answer is Number1*Number2.
when if the question is what is 10*3 it should be printing
Your answer is incorrect, the correct answer is 30.
Now that I have this code...
if Operator == '+':
realanswer = Number1+Number2
elif Operator == '-':
realanswer = Number1-Number2
elif Operator == '*':
realanswer = Number1*Number2
if Answer==realanswer:
print("Your answer is correct")
score = score + 1
print (score)
else:
print("Your answer is incorrect, the correct answer is.",realanswer,".")
print (score)
The program always prints that the question is incorrect even with the correct answer inputted, it will then print the correct answer, how would I make it so that It would tell them if it's correct too?
The operator module implements basic operations as functions. Define a dict that maps operator symbols such as "+" to the operator function then use that map to do the calculation.
import random
import operator
op_map = {'+':operator.add, '-':operator.sub, '*':operator.mul}
op_list = list(op_map.keys())
score = 0
print ("Welcome to the times table test")
name = input("Please type your name: ")
print ("How to play")
print ("Step 1: When you see a question work out the answer and type it in the space.")
print ("Step 2: Once you have typed your answer press the enter key.")
print ("Step 3: The program will tell you if you're right or wrong.")
print ("Step 4: The next question will load and you can repeat from step 1.")
print ("When you have answered all 10 questions your final score will be printed.")
for q in range(10):
Number1 = random.randint(1,12)
Number2 = random.randint(1,12)
Operator =random.choice(op_list)
print ('what is' ,Number1,Operator,Number2)
while True:
try:
Answer= int(input("Please Type Your Answer: "))
break
except ValueError:
print("Must be an integer... try again...")
realanswer = op_map[Operator](Number1, Number2)
if Answer==realanswer:
print("Your answer is correct")
score = score + 1
print (score)
else:
print("Your answer is incorrect, the correct answer is.",realanswer,".")
print (score)
To perform multiple check like this you can use if, elif statements:
if Operator == '+':
realanswer = Number1+Number2
elif Operator == '-':
realanswer = Number1-Number2
elif Operator == '*':
realanswer = Number1*Number2
For your reference: Python Docs
...
def realanswer(Num1, Op, Num2):
return {
'+': Num1 + Num2,
'-': Num1 - Num2,
'*': Num1 * Num2,
}[Op]
for q in range(2):
Number1 = random.randint(1,12)
Number2 = random.randint(1,12)
ListOfOperator = ['+','-','*']
Operator =random.choice(ListOfOperator)
print ('what is',Number1,Operator,Number2)
userInput = input("Please Type Your Answer: ")
Answer = 0
try:
Answer = int(userInput)
except ValueError:
print("Input not convertible to int!")
rAnswer = realanswer(Number1,Operator,Number2)
if Answer == rAnswer:
print("Correct!")
else:
print("Incorrect...")

Letters inside "int(input(())"

def multiply(): #starts sub program when 'multiply()' is called
num1 = random.randint(1,12) #randomly generates a number between 1 and 12
num2 = random.randint(1,12)
while loop == True: #creates loop, and uses previously defined 'loop'
ans = int(input("What is the answer to " + str(num1) + " x " + str(num2) + " ? ")) #asks question and requires a user input
correct = (ans == num1 * num2)
if correct:
print("You are correct! ")
break #if the answer is correct, it prints 'You are correct!' and breaks to avoid the loop
else:
print("Wrong, please try again. ")
loop == False #if the answer is wrong, it loops back to when 'loop' was last 'True'
I am wondering if there is a way for me to include a line of code that allows me to display "That is not an option!" when a symbol other than a number is entered into the 5th line in the code.
Use an exception to catch unexpected inputs.
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import random
def multiply():
# Randomly generates a number between 1 and 12
num1 = random.randint(1,12)
num2 = random.randint(1,12)
while True:
i = input("What is the answer to {} x {} ".format(
str(num1), str(num2)))
try:
ans = int(i)
except ValueError:
print('That is not an option!')
continue
if ans == num1 * num2:
print("You are correct!")
break
else:
print("Wrong, please try again.")
if __name__ == "__main__":
multiply()
When you convert to int there is the chance that they will enter a non-integer value so the conversion will fail, so you can use a try/except
def multiply(): #starts sub program when 'multiply()' is called
num1 = random.randint(1,12) #randomly generates a number between 1 and 12
num2 = random.randint(1,12)
while loop == True: #creates loop, and uses previously defined 'loop'
try:
ans = int(input("What is the answer to " + str(num1) + " x " + str(num2) + " ? ")) #asks question and requires a user input
correct = (ans == num1 * num2)
if correct:
print("You are correct! ")
break #if the answer is correct, it prints 'You are correct!' and breaks to avoid the loop
else:
print("Wrong, please try again. ")
loop == False
except ValueError:
print("That is not an option")
Note that your previous code is now nested in a try block. If the int() fails because they entered a bad input, it will throw a ValueError that you can catch and notify them.
As a side note, another way to format your question to them would be
'What is the answer to {} x {}?'.format(num1, num2)
This is a nice way to generate a string with injected variable values.

Categories

Resources