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')
Related
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')
I'm trying to do a silly little program that will let me open an image given a specific number.
import os
c1= os.startfile('Cat1.PNG')
c2= os.startfile('Cat2.PNG')
c3= os.startfile('Cat3.PNG')
catlist= [c1,c2,c3]
valid= False
def cats(valid):
while not valid:
try:
answer=int(input('Choose a number between 1 and 3'))
valid= True
except ValueError:
print("This is not a number")
if answer >=1 and answer <=3:
print(catlist[answer-1])
else:
print('Wrong value')
del (answer)
cats(valid)
return
cats(valid)
My problem is that my pictures just get all open when I start the program, while I want to open them when I choose a specific number.
The problem with your code is in the part where you assign the os.startfile() function to a variable.
When Python interpreter goes through your code, as soon as it hits the c1= os.startfile('Cat1.PNG') line of code, it executes the command and opens the files immediately.
import os
valid = True
def cats(valid):
while valid:
try:
x = int(input("Enter a number here: "))
valid = False
except ValueError:
print("This is not a number!")
if x == 1:
os.startfile('1.jpg')
elif x == 2:
os.startfile('2.jpg')
elif x == 3:
os.startfile('3.jpg')
else:
print("Wrong value")
valid = True
cats(valid)
There is probably a better and more efficient way to do it, but here is a solution I came up with.
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.
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.
Can I combine these functions together to shorten my python code? I'm creating a quick program!
Here are the functions:
def try1():
try:
num1=input("Enter num 1: ")
return num1
except ValueError:
print("incorrect!")
return #value
def try2():
try:
num2=input("Enter num 2: ")
return num2
except ValueError:
print ("incorrect!")
return #value
def try3():
try:
num3=input("Enter num 3: ")
return num3
except ValueError:
print ("incorrect!")
return #value
def try4():
try:
num4=input("Enter num 4: ")
return num4
except ValueError:
print ("incorrect!")
return #value
Please post your suggestions and answers below.
As you can see from my reputations, I am a new programmer hoping to find kind people on Stackoverflow.
(This answer is based on the original revision of the question which is no longer accessible but showed a different problem, where the user is keep being asked until a valid number is entered. And the code showed some skill game system or something, so that’s why my questions are longer and more specific too.)
Something like this?
def getInt(name, target):
while True:
try:
return int(input('Please enter {0} for {1}: '.format(name, target)))
except ValueError:
print('Incorrect!')
strength0 = getInt('strength', 'character 1')
skill0 = getInt('skill', 'character 1')
strength1 = getInt('strength', 'character 2')
skill1 = getInt('skill', 'character 2')
In general, when you have multiple functions that approximately do the same thing, then yes, there is a lot potential to refactor it so you don’t repeat yourself. In this case, what was different is the question the user was being asked, so if we parameterize that, we are good to use just a single function to handle it all.
The function can be generalised to ask for the input of any number, for example:
def try_num(n):
num = int(input("Enter num {} : ".format(n)))
while num != n:
print ("incorrect!")
num = int(input("Enter num {} : ".format(n)))
return num
Use it like this:
try_num(10)
Enter num 10 : 9
incorrect!
Enter num 10 : 10
10
def safe_int(x):
try:
return int(x)
except ValueError:
return 0
[safe_int(raw_input("Number %d:"%i)) for i in range(4)]
I would create a validation method and simply pass in the strings.
def validate(question):
while True:
try:
print question,
input = raw_input()
if input.isdigit():
return int(input)
else:
print "Not a valid integer"