lst = []
while True:
try:
arr = int(input("Enter number of elements: "))
if arr == "Quit":
break
except ValueError:
print("Invalid Input")
continue
else:
break
while True:
try:
for i in range(0, arr):
ele = int(input("Enter the elements:"))
lst.append(ele)
print(lst)
except ValueError:
print("Invalid Input")
continue
else:
break
How can I create a condition to exit the program at any point in the loop by specifically entering the conditioned term?
Like when it asks me to enter an element, but i want to break the program right at that point by entering
"Quit".
How to do that in this code?
(Learner)
Use sys.exit() to exit the program completely. Use break to exit the specific loop you're in (which you've used).
Other notes:
You're doing arr = int(input(...)) but you want to accept the input of "Quit" which is a string. So if the user enters "Quit", it raise ValueError and the loop continues. So check for "Quit" first and if it's not quit, then convert to int with the try-block
Same applies for the 2nd loop where you ask the user for the elements in the list
Btw, your second loop's while True loop should be inside the for-loop which gets each element.
lst = []
while True:
arr = input("Enter number of elements: ")
if arr == "Quit":
sys.exit() # will exit completely
try:
arr = int(arr) # check for int in the try-block, error raised here, if not int
break # can put break here instead of in else, any is okay
except ValueError:
print("Invalid Input")
# continue not needed here, since it loops infinitely by default
for i in range(0, arr):
while True:
ele = input("Enter the elements:")
if ele == "Quit":
sys.exit() # will exit completely
try:
ele = int(ele) # check for int in the try-block, error raised here, if not int
lst.append(ele)
break # breaks out of `while` loop, not `for` loop; good
except ValueError:
print("Invalid Input")
# continue not needed here, since it loops infinitely by default
print(lst) # print the full list after all the inputs
The pattern for your input is repeated:
Ask user for input
if input is "Quit", then exit completely
otherwise, convert the input to an int
So this can put into a function, which you call in both places:
def int_or_quit(msg):
"""`msg` is the message you want to show at input"""
while True:
item = input(msg)
if item == "Quit":
sys.quit() # will exit completely
try:
return int(item) # try converting to int and return
except ValueError:
print("Invalid Input")
# repeats by default
# use the function above in your two code blocks, which are now simplified:
lst = []
arr = int_or_quit("Enter number of elements: ")
# program exits before if user "Quit", next part won't execute
for i in range(0, arr):
ele = int_or_quit("Enter an element:")
lst.append(ele)
print(lst)
I can see that there're 2 blocks in your code snippet. I'd suggest organising them in distinct functions, where function name infers a function goal (instead of comments):
def get_list_size():...
def fill_list():...
Next thing to do is deciding about function's return values:
from typing import List, Optional
def get_list_size() -> Optional[int]:
"""
:returns: number of desired elements of list or None, if "Quit" was pressed
:raises: ValueError exception, if non integer value was pressed
"""
def fill_list(lst_size: int) -> List[int]:
"""
returns: filled list
throws: ValueError exception, if non integer value was pressed
"""
Here you can see, how Optional type hint is used to add condition logic into the program.
Lats thing to do is to fill your functions with lightweight code:
def get_list_size() -> Optional[int]:
"""
:returns: number of desired elements of list or None, if "Quit" was pressed
:raises: ValueError exception, if non integer value was pressed
"""
while True:
try:
input_value = input("Enter number of elements: ")
# Pay attention: you have to check string input_value, not int(input_value).
# Checking int(input_value) would raise exception before 'Quit' validation.
if input_value == "Quit":
return None
return int(input_value)
# Could be rewritten as trinary if
# return None if input_value == "Quit" else int(input_value)
except ValueError:
print("Invalid Input")
# continue <- Not needed here
def fill_list(lst_size: int) -> List[int]:
"""
returns: filled list
throws: ValueError exception, if non integer value was pressed
"""
lst = []
while len(lst) < lst_size:
try:
ele = int(input("Enter the elements:"))
lst.append(ele)
print(lst)
except ValueError:
print("Invalid Input")
return lst
Pay attention: in fill_list function you have to try/except each element, so while loop was moved outside.
Last thing to do is running these functions:
desired_list = []
desired_list_size = get_list_size()
if desired_list_size is not None:
desired_list = fill_list(desired_list_size)
def one():
message = ""
while message != "Quit":
message = input("Type in Order > ")
if message == "Run":
print("Run some Code")
message = input("What do u want to run ? > ")
if message == "Exel":
print("Runing Exel")
else:
pass
else:
pass
while True:
one()
Here you can pass in funktions that will run when you call it by its Name. If u write Quit it will start over again. It starts over again if you write something wrong. U could do an FailExeption for that if u want to.
Related
Using exception handling inside a loop in python, I'm receiving inputs from a user and adds it to a list but if the user types 'done' the loop terminates and sums up the list. If the user types any other non numeric data it would print 'Wrong Data' and continue the loop. My issues are: Adding the list. Converting the user data from number to string. Reading a string data first from the user. And terminating the loop with 'done'.
total = 0
user_list = []
while True:
try:
user_entry = int(input('(\'done\' is your terminator.)\nEnter any number only! >> '))
user_list.append(user_entry)
total = total + user_list
except ValueError:
if str(user_entry) == 'done':
break
else:
print('Wrong Data')
continue
There's lots of code in the try block that should go before or after the try statement.
total = 0
user_list = []
while True:
user_entry = input('(\'done\' is your terminator.)\nEnter any number only! >> ')
if user_entry == 'done':
break
try:
user_entry = int(user_entry)
except ValueError:
print('Wrong Data')
continue
user_list.append(user_entry)
total += user_entry
Note that instead of keeping running total, you can simply wait until after the loop to call total = sum(user_list).
I'm trying to do an exercise on Python. For this, I have to use the following function:
def getNumber() :
x = input ('Choose a number: ')
if x == 17:
raise ("ErrorBadNumber","17 is a bad number")
return x
The exercise says create another function that uses getNumber and handle the exception ErrorBadNumber.
I've created the function getNumber_2 to try solve the exercise:
def getNumber() :
x = input ('Choose a number: ')
if x == 17:
raise ("ErrorBadNumber","17 is a bad number")
return x
while True:
def getNumber_2 ():
try:
getNumber ()
except ErrorBadNumber:
print('Write another number, please')
getNumber ()
Then, it appears an error: "Undefined name 'ErrorBadNumber' ". Anyway, when I only execute the function getNumber the exception doesn't happen. I don't know why. Thanks in advance.
Exceptions have to be classes that derive from the base Exception class. And i your while loop, you are defining a function, but you never call the function, so nothing ever runs. It's an infinite loop, doing nothing.
For example:
class ErrorBadNumber(Exception):
pass
def getNumber() :
x = input ('Choose a number: ')
if x != '17':
raise ErrorBadNumber("17 is a bad number")
return x
while True:
try:
getNumber ()
break
except ErrorBadNumber:
print('Write another number, please')
my task is to calculate the amount of money in a saving account in two ways and compare the results. It prompt the user for input principle, the interest rate(as a percent), and years of invest.I need to use try-except block to validate the input, and use a while statement to prompt the user until a valid input. I have issue on the validation and while process. When I had invalid input, it didn't print associated exception error as expected.The function parts are Ok, just ignore them. Also, "Going around again" is supposed to print before the next prompt input, but mine appeared by the end of correct input execution. Could you please help me? Thanks.
def calculate_compound_interest(principle, int_rate, years):
value = principle * (1 + int_rate)**years
return value
def calculate_compound_interest_recursive(principle, int_rate, years):
if years == 0:
return principle
else:
recursive_value = calculate_compound_interest_recursive(principle, int_rate, years-1)*
(1+int_rate)
return recursive_value
def format_string_output(value, recursive_value):
return "Interest calculated recursively is {:,.2f} and calculated by original formula is
{:,.2f}.These values are a match.".format(recursive_value,value)
print(__name__)
if __name__ == "__main__":
while True:
principle_input = input("Please input principle:")
interest_rate_input = input("Please input interest rate with %:")
years_input = input("Please input years:")
try:
p = float(principle_input)
i = (float(interest_rate_input.replace("%","")))/100
n = int(years_input)
except ValueError():
print("Error: invalid principle.")
except ValueError():
print("Error: invalid interest rate.")
except ValueError():
print("Error: invalid years.")
else:
print(calculate_compound_interest(p, i, n))
print(calculate_compound_interest_recursive(p, i, n))
print(format_string_output(calculate_compound_interest(p, i, n),
calculate_compound_interest_recursive(p, i, n)))
break
finally:
print("Going around again!")
Note: Finally block runs whenever a try or any except block runs.
The Try-Except blocks need to be paired up, easier to show than explain.
def calculate_compound_interest(principle, int_rate, years):
value = principle * (1 + int_rate)**years
return value
def calculate_compound_interest_recursive(principle, int_rate, years):
if years == 0:
return principle
else:
recursive_value = calculate_compound_interest_recursive(principle, int_rate, years-1)*(1+int_rate)
return recursive_value
def format_string_output(value, recursive_value):
return "Interest calculated recursively is {:,.2f} and calculated by original formula is {:,.2f}.These values are a match.".format(recursive_value,value)
if __name__ == "__main__":
while True:
principle_input = input("Please input principle:")
interest_rate_input = input("Please input interest rate with %:")
years_input = input("Please input years:")
try:
p = float(principle_input)
except ValueError():
print("Error: invalid principle.")
print("Going around again!")
continue
try:
i = (float(interest_rate_input.replace("%","")))/100
except ValueError():
print("Error: invalid interest rate.")
print("Going around again!")
continue
try:
n = int(years_input)
except ValueError():
print("Error: invalid years.")
print("Going around again!")
continue
print(calculate_compound_interest(p, i, n))
print(calculate_compound_interest_recursive(p, i, n))
print(format_string_output(calculate_compound_interest(p, i, n),
calculate_compound_interest_recursive(p, i, n)))
break
Let me know any questions via a comment.
Hi guys I was working on a shoppinglist-creator code but at the end I faced with a surprise.
My code:
import time
import math
import random
dict_of_lists={}
def addlist():
while True:
try:
listname=str(raw_input("=>Name of the list:\n"))
dict_of_lists[listname]={}
break
except ValueError:
print "=>Please enter a valid name.\n"
print "=>You added a new list named %s.\n" % (listname)
def printlists():
for lists in dict_of_lists:
return "-"+lists
def addproduct():
while True:
try:
reachlistname=input("=>Name of the list you want to add a product,Available lists are these:\n %s \nPlease enter one:\n" % (printlists()))
break
except ValueError:
print "=>Please enter a valid list name.\n"
while True:
try:
productname=raw_input("=>Name of the product:\n")
break
except ValueError:
print "=>Please enter a valid name.\n"
while True:
try:
productprice=input("=>Price of the product:\n")
if isinstance(float(productprice),float):
break
except ValueError:
print "=>Please enter a valid number.\n"
while True:
try:
productcount=input("=>Amount of the product:\n")
if isinstance(int(productcount),int):
break
except ValueError:
print "=>Please enter a valid number.\n"
dict_of_lists[reachlistname][productname]={"price":productprice,"count":productcount}
dict_of_lists[reachlistname]={productname:{"price":productprice,"count":productcount}}
allevents="1-Add a list"+" 2-Add a product to a list"
def eventtochoose():
while True:
try:
event=raw_input("=>What would you like to do? Here are the all things you can do:\n %s\nPlease enter the number before the thing you want to do:" % (allevents))
if not isinstance(int(event),int):
print "\n=>Please enter a number.\n"
else:
if event==1:
addlist()
break
elif event==2:
addproduct()
break
except ValueError:
print "\n=>Please enter a valid input.\n "
while True:
print "%s" % ("\n"*100)
eventtochoose()
So, the problem is (I suggest you run the code) it says "=>What would you like to do? Here are the all things you can do:
1-Add a list 2-Add a product to a list
Please enter the number before the thing you want to do:" and when i put an answer it simply doesn't call the fucntion.
If I put 1 It should have called the fucntion addlist but I think it doesn't. There is nothing to explain I think just look at the code and find the problem if you want to help crocodiles. Thx
When you do int(event), that returns an int if possible, and raises a ValueError if not. So, testing the type of the result doesn't do you any good—if your code gets that far, the type has to be an int.
You already have code to handle the ValueError, so you don't need any other test for the same problem.
Meanwhile, you want to start the number that you got from int(event). That's the thing that can be == 1; the original string '1' will never be == 1.
So:
while True:
try:
event=raw_input("=>What would you like to do? Here are the all things you can do:\n %s\nPlease enter the number before the thing you want to do:" % (allevents))
event = int(event)
if event==1:
addlist()
break
elif event==2:
addproduct()
break
except ValueError:
print "\n=>Please enter a valid input.\n "
You are not converting your input to an integer before comparing, so the comparisons are always false:
'1' == 1 # false
Try:
event = raw_input("=>What would you like to do? Here are the all things you can do:\n %s\nPlease enter the number before the thing you want to do:" % (allevents))
try:
event = int(event)
if event == 1:
addlist()
elif event == 2:
addproduct()
break
except ValueError:
print('Please enter a valid input')
Both functions use the same check(x) function and almost identical to each other, except the argument the second function have to take in order to use print.
Entering int as inputs showed no problem.
However, if alphabets were entered, the return result of enter_num() becomes NoneType, but this does not happen in enter_amount().
Where and how did it went wrong?
def check(x): #check if user input is integer
try:
int(x)
return True
except ValueError:
return False
def enter_num(): #get user input for lotto numbers
x = input("buy num:")
if check(x) == True: #check int
x = int(x)
return x
else:
print("Please enter integer")
enter_num()
def enter_amount(x): #get user amount of the lottos
print(x) ##if enter_num errored once, this will show None##
y = input("How many?")
if check(y) == True: #check int
y = int(y)
print("%s for %s copies" % (x,y))
return y
else:
print("Please enter integer")
enter_amount(x)
buy_num = enter_num()
amount = enter_amount(buy_num)
You never return the recursive result from enter_num():
def enter_num():
x = input("buy num:")
if check(x) == True:
x = int(x)
return x
else:
print("Please enter integer")
enter_num() # ignoring the return value
# so None is returned instead
The same applies to enter_amount(); it too ignores the recursive call.
You need to explicitly return the recursive call result, just like you would for any other expression:
def enter_num():
x = input("buy num:")
if check(x) == True:
x = int(x)
return x
else:
print("Please enter integer")
return enter_num() # ignoring the return value
Do the same for enter_amount(); change the last line to return enter_amount(x).
You really should not be using recursion however; all the user has to do is hold the ENTER key for a short amount of time for your code to end up breaking the recursion limit. See Asking the user for input until they give a valid response for better techniques; a while loop would be fine here.
There is also no need to test for == True; if already tests for truth:
if check(x):
I'd also inline the check test; no need to convert to int() twice if the string can be converted. The following won't run out of recursion depth, but just returns int(x) directly if x contained a convertible value, or prints an error message otherwise and loops right back to ask for the number again:
def enter_num():
while True:
x = input("buy num:")
try:
return int(x)
except ValueError:
print("Please enter integer")