I am learning python exception handling. I came across a challenge where I had to define a function to raise exceptions when certain conditions didn't meet. I was able to raise exceptions just fine for all the hidden test cases but one. Here's my code below:
def Handle_Exc1():
try:
a=int(input())
b=int(input())
if not (a<150 and b>100):
raise ValueError('Input integers value out of range.')
except ValueError as e:
print(e)
else:
try:
c=a+b
if c>400:
raise ValueError('Their sum is out of range')
except ValueError as f:
print(f)
else:
print("All in range")
The above code worked for all the hidden test cases but one. I cannot find out what kind of scenario or whats the input is given either. However, the code should have been able to handle all the scenarios. But it isn't. Need your help to figure out how I could have made this code foolproof.
Any help is much appreciated.
Thanks in advance.
Mahi
can you tell that one hidden test scenario which is failing & what input is given you can pass the variable in error, you don't have to create try and except block every time you just allow in outer scope
try:
a=int(input('a:'))
b=int(input('b:'))
if a>=150 :
raise ValueError('Input integer a value out of range. it should be less than 150,you provide :',a)
elif b<= 100:
raise ValueError('Input integer b value out of range. it should be greater than 100,you provide :',b)
c = a+b
if c>400:
raise ValueError('Their sum is greater than 400. sum is :',c)
except ValueError as f:
print(f)
I figured out the answer. I missed to include values 150 and 100 in the if statement. Working code below:
def Handle_Exc1():
try:
a=int(input())
b=int(input())
if not (a<=150 and b>=100):
raise ValueError('Input integers value out of range.')
c=a+b
if c>400:
raise ValueError('Their sum is out of range')
except ValueError as f:
print(f)
else:
print("All in range")
This passed all the test cases.
Related
I am trying to implement a retry ability whenever a function fails with an index error. I started with this:
I know the reason for failure is passing high value to curr_val, but setting high values will generate better output
#these lines are inside another for loop
curr_val=40
while True:
try:
ret1, ret2 = extract(arg1,arg2,val=curr_val)
except IndexError:
curr_val -=5
continue
break
##process ret1
According to this answer, it is possible to use the decorator (like tenacity) to handle such cases, supporting any kind of exception.
my current try with tenacity is as follows:
curr_val = 5
#tenacity.retry(wait=tenacity.wait_fixed(1))
def try_to_extract():
try:
return extract(arg1,arg2,val=curr_val)
except Exception:
curr_val -=1
raise
However, it does not have access to the outside variables and keeps raising exception, without changing curr_val
Can anyone let me know how to handle this? meaning using curr_val inside retry and handle this case. (retrying with another argument(decremented curr_val), in case of failure or timeout)
the iterator can help this.
#tenacity.retry
def try_to_extract(value_iter):
curr_val = next(value_iter)
print(curr_val)
try:
return extract(arg1,arg2,val=curr_val)
except Exception:
raise
curr_val = 40
try_to_extract(itertools.count(curr_val, -1))
I am trying to complete a lab soon but I am having difficulty, the prompt is:
A pedometer treats walking 2,000 steps as walking 1 mile. Write a steps_to_miles() function that takes the number of steps as a parameter and returns the miles walked. The steps_to_miles() function throws a ValueError object with the message "Exception: Negative step count entered." when the number of steps is negative. Complete the main() program that reads the number of steps from a user, calls the steps_to_miles() function, and outputs the returned value from the steps_to_miles() function. Use a try-except block to catch any ValueError object thrown by the steps_to_miles() function and output the exception message.
Output each floating-point value with two digits after the decimal point, which can be achieved as follows:
print('{:.2f}'.format(your_value))
I have been working on it for awhile now, my code is:
def steps_to_miles():
steps = int(input())
if steps < 0:
raise ValueError
return steps
if __name__ == '__main__':
try:
steps = steps_to_miles()
miles_walked = float(steps / 2000)
print('{:.2f}'.format(miles_walked))
except ValueError:
print('Exception: Negative step count entered.')
(Sorry for formatting errors...) The code runs but is only giving me 4 out of the 10 points due to Zybooks stating "test_passed function missing" and "Test stepsToMiles(-3850), should throw an exception". What am I missing or how can fix it? Or alternatively is there another way to write the code?
def steps_to_miles(steps):
if steps < 0:
raise ValueError
return float(steps / 2000)
if __name__ == '__main__':
steps = int(input())
try:
miles_walked = steps_to_miles(steps)
except ValueError:
print('Exception: Negative step count entered.')
print('{:.2f}'.format(miles_walked))
in body of try, need use only 'danger' code
your function was unworked becourse: you dont send any parameter, and it dont return value
input moved into main . It was next error: steps was local variable, which dont used in global namespace, and in function main
We can't do a lot to help you with an automatic homework grader, you should probably ask your teacher or TA. Here are a few pointers:
Your steps_to_miles does not take any arguments, according to the assignment it should take a single integer argument.
The ValueError you throw does not have a message attached to it.
steps_to_miles should divide its argument by 2000 but it doesn't do so. Instead you divide by 2000 outside of the function.
You print a specific string in your except block instead of printing the exception's actual message.
You may need to make your error message a variable, in regards to your zyBooks giving you this error: "Test stepsToMiles(-3850).
I would try this in your function: raise ValueError('Exception: Negative step count entered.')
I would also write in this in your final "except" statement.
except ValueError as err:
print(err)
this should work:
def steps_to_miles(num_steps):
if num_steps < 0:
raise ValueError("Exception: Negative step count entered.")
return num_steps / 2000
if __name__ == '__main__':
num_steps = int(input())
try:
num_miles = steps_to_miles(num_steps)
print('{:.2f}'.format(num_miles))
except ValueError as e:
print(e)
I am making a code to solve quadratic formula and need exception handling such that missing command
line arguments are detected. In the except IndexError: block, instead of exiting
the program you should use input() to ask the user for the missing input data. It doesn't work with the following code. Anyone have any ideas?
from math import sqrt
import sys
print('This program will solve the quadratic formula with given values, please enter below.')
try:
a=float(sys.argv[1]) #first system argument
b=float(sys.argv[2]) #second system argument
c=float(sys.argv[3]) #third system argument
d=b**2-4*a*c #discriminant
x1=((-b+sqrt(d))/2*a) #first solution
x2=((-b-sqrt(d))/2*a) #second solution
except IndexError:
raise IndexError(
'Oops! Looks like you have not entered all values. Try again.') #request user input
a=input(sys.argv[1]) #first system argument
b=input(sys.argv[2]) #second system argument
c=input(sys.argv[3]) #third system argument
d=b**2-4*a*c #discriminant
x1=((-b+sqrt(d))/2*a) #first solution
x2=((-b-sqrt(d))/2*a) #second solution
print(f'The quadratic formula with used a,b,c values gives two roots {x1:.2f} and {x2:.2f}')
I see several ways to improve with the original code:
Statements following raise are never executed
Conversion of string via float() may throw a ValueError
If less than 3 arguments are supplied, then sys.argv[n] will throw an error
You should revalidate re-entered input until it's correct.
You shouldn't trigger reentry of correct values if later ones have issues.
If your discriminant d is negative, sqrt() will throw a ValueError
Make your code DRY (Don't Repeat Yourself) by factoring out validation logic.
You need some way to do output.
The following code fixes these by:
Adding a validate method to be more DRY and validate input and handle ValueError.
Process the 3 arguments in order via an iterator that returns '' if not supplied, which the validate method will handle.
Test for negative discriminant.
from math import sqrt
import sys
print('This program will solve the quadratic formula with given values, please enter below.')
def validate(name, value):
try:
return float(value)
except ValueError:
new_value = input(f"Entered a value for {name}: ")
return validate(name, new_value)
args = iter(sys.argv)
a = validate('a', next(args, ''))
b = validate('b', next(args, ''))
c = validate('c', next(args, ''))
d=b**2-4*a*c #discriminant
if d >= 0 :
x1=((-b+sqrt(d))/2*a) #first solution
x2=((-b-sqrt(d))/2*a) #second solution
print(f"the roots {x1} and {x2}")
else:
print("the equation has no real-valued solutions")
You are raising un exception inside the catch block:
except IndexError:
raise IndexError(
'Oops! Looks like you have not entered all values. Try again.')
You can remove it and prompt the user this message using input() or something similar. for example:
except IndexError:
a= input('Oops! Looks like you have not entered all values. Enter the value again.')
I have a function like this:
for product in responseSoup.findAll("offersummary"):
try:
if product.lowestnewprice.formattedprice != None:
price.append(product.lowestnewprice.formattedprice.text)
else:
price.append("")
except:
price.append("")
I am confused how to do the if/else statement with the try/except block? Will list comprehension speed up efficiency?
[product.lowestnewprice.formattedprice for product in responseSoup.findAll("offersummary")]
Here is a very readable solution:
prices = []
for product in responseSoup.findAll("offersummary"):
price = product.get(lowestnewprice, {}).get(formattedprice, {}).get(text)
if price is not None:
prices.append(price)
else:
prices.append('')
If you really don't care about readability, here's a very atrocious looking one-liner:
price = [''
if product.get(lowestnewprice, {}).get(formattedprice, {}).get(
text) is None else
product.lowestnewprice.formattedprice.text
for product in responseSoup.findAll("offersummary")]
They do essentially the same thing, but, in my opinion, the more readable solution is better.
EDIT
I just figured out a much better one-liner:
price = [product.get(lowestnewprice,{}).get(formattedprice,{}).get(text) or ''
for product in responseSoup.findAll("offersummary")]
It's still less readable than the "very readable" solution, but it is not too bad. Now the decision really comes down to a matter of your preference.
try and except blocks are used to see if the following code works. If not and it matches the given error, run that block of code. Else, run the other line of code. For example:
try:
m = raw_input("Please enter an integer")
n = int(m)
except ValueError:
print "Invalid number"
else:
print n
So, the program attempts to assign m the input from the user. Then n is assigned the input as an integer. Now the error chosen is ValueError since if m is a string, the conversion to n will raise that error. If it does, then it does the code in the except block, which is to print "Invalid number". If the conversion is successful, then print n.
Now with your program, you will try the if and else block. If the code doesn't work and it raises the error given in the except block, it will do price.append(""). Else, it will run the code in the else block, which you don't have. You need the else: to work in your try/except block for it to work including a specified error after the keyword except in your except statement.
It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 12 years ago.
I have a menu that asks for the user to pick one of the options. Since this menu is from 1 to 10, I'm using input besides raw_input.
My code as an if statement that if the number the user inputs is from 1 to 10 it does the option. If the user inputs any number besides that ones, the else statement says to the user pick a number from 1 to 10.
The problem is if the user types an string, lets say for example qwert. It gives me an error because its an string. I understand why and I don want to use raw_input.
What can I do to wen the user types a string it goes to my else statement and print for example "Only numbers are valid. Pick a number from 1 to 10"
I don't want to use any advanced programing to do this
Regards,
Favolas
EDIT
Thanks for all your answers and sorry for the late response but I had some health problems.
I couldn't use try or except because my teacher didn't allow it.
In the end, I've used raw_input because it was the simplest alternative but was glad to see that are many ways to solve this problem.
Regards,
Favolas
You can throw an exception when you try to convert your string into a number.
Example:
try:
int(myres)
except:
print "Only numbers are valid"
You should use raw_input(), even if you don't want to :) This will always give you a string. You can then use code like
s = raw_input()
try:
choice = int(s)
except ValueError:
# choice is invalid...
to try to convert to an int.
Im not sure what you consider advanced - a simple way to do it would be with something like this.
def getUserInput():
while True:
a = raw_input("Enter a number between 1 and 10: ")
try:
number = int(a)
if (0 < number <= 10):
return number
else:
print "Between 1 and 10 please"
except:
print "Im sorry, please enter a number between 1 and 10"
Here, I have used try/except statements, to ensure that the entered string can be converted to an integer. And a loop (which will keep running) until the entered number is between 1 and 10 (0< number <=10)
What you really are after is how to figure out if something could pass as an integer. The following would do the job:
try:
i = int(string_from_input)
ecxept ValueError:
# actions in case the input is anything other than int, like continuing the loop
You clearly have something against exception handling. I don't understand why -- it's a fundamental part of (not just Python) programming and something you should be comfortable with. It's no more 'advanced' than handling error codes, just a different mentality.
Here are the docs. It's pretty simple:
It is possible to write programs that
handle selected exceptions. Look at
the following example, which asks the
user for input until a valid integer
has been entered, but allows the user
to interrupt the program (using
Control-C or whatever the operating
system supports); note that a
user-generated interruption is
signalled by raising the
KeyboardInterrupt exception.
>>> while True:
... try:
... x = int(raw_input("Please enter a number: "))
... break
... except ValueError:
... print "Oops! That was no valid number. Try again..."
...
The try statement works as follows.
First, the try clause (the
statement(s) between the try and
except keywords) is executed. If no
exception occurs, the except clause is
skipped and execution of the try
statement is finished. If an exception
occurs during execution of the try
clause, the rest of the clause is
skipped. Then if its type matches the
exception named after the except
keyword, the except clause is
executed, and then execution continues
after the try statement. If an
exception occurs which does not match
the exception named in the except
clause, it is passed on to outer try
statements; if no handler is found, it
is an unhandled exception and
execution stops with a message as
shown above. A try statement may have
more than one except clause, to
specify handlers for different
exceptions. At most one handler will
be executed. Handlers only handle
exceptions that occur in the
corresponding try clause, not in other
handlers of the same try statement. An
except clause may name multiple
exceptions as a parenthesized tuple,
for example:
... except (RuntimeError, TypeError, NameError):
... pass
The last except clause may omit the
exception name(s), to serve as a
wildcard. Use this with extreme
caution, since it is easy to mask a
real programming error in this way! It
can also be used to print an error
message and then re-raise the
exception (allowing a caller to handle
the exception as well):
Personally, I liked my first answer better. However, this one should fit your requirements with more code.
import sys
def get_number(a, z):
if a > z:
a, z = z, a
while True:
line = get_line('Please enter a number: ')
if line is None:
sys.exit()
if line:
number = str_to_int(line)
if number is None:
print('You must enter base 10 digits.')
elif a <= number <= z:
return number
else:
print('Your number must be in this range:', a, '-', z)
else:
print('You must enter a number.')
def get_line(prompt):
sys.stdout.write(prompt)
sys.stdout.flush()
line = sys.stdin.readline()
if line:
return line[:-1]
def str_to_int(string):
zero = ord('0')
integer = 0
for character in string:
if '0' <= character <= '9':
integer *= 10
integer += ord(character) - zero
else:
return
return integer
May I recommend using this function in Python 3.1? The two arguments are the expected number range.
def get_number(a, z):
if a > z:
a, z = z, a
while True:
try:
line = input('Please enter a number: ')
except EOFError:
raise SystemExit()
else:
if line:
try:
number = int(line)
assert a <= number <= z
except ValueError:
print('You must enter base 10 digits.')
except AssertionError:
print('Your number must be in this range:', a, '-', z)
else:
return number
else:
print('You must enter a number.')