Handling exception returned by a method - python-3.x

I am calling a method that throws Valuerror exception or returns valid response as a string. I am not able to handle the situation if it is an exception. If the return is the valid string I am supposed to slice it and do other things with it.
x = sanitize("245755487")
try:
print(data = x[:3])
except:
print(x)
def sanitize(self,tel):
data = [d for d in tel if d.isalnum()]
digits = int(len(data))
if digits < 10:
raise ValueError("The digit cannot be below 10")
else:
"".join(data)
If the x is subscribable I am supposed to get that string sliced.

You need to place call to sanitize method in try block because sanitize is the method that raises exception. Placing it outside try block makes no sense. You should handle error in except block instead of print(x).
try:
x = sanitize("245755487")
print(data = x[:3])
except ValueError as err:
print(err);
#<what would you like to do if there is an error?>

Related

try.. except failing inside for loop

I have a for loop which loops through initial guesses for a scipy.optimize.minimize routine. Some of the initial guesses fail, so I want to wrap the call to scipy.optimize.minimize in a try/except statement, so that when a guess fails, it moves on to the next.
Unfortunately this is not working. Once a guess fails, the next iterations also fail, even if the initial guess is a good one that I know works.
When I try to reproduce this failure in a MWE, I can't, so I am stumped.
Here is the MWE that works
import numpy as np
def f(x):
assert type(x) == float
return np.log(x)
def arbitrary_function():
vals = [ 0.5, "string", 5, 9.3]
v_list=[]
for num in vals:
try:
v = f(num)
if v > 0:
v_list.append(v)
except:
print("failed on {}".format(num))
continue
return v_list
my_list = arbitrary_function()
print(my_list)
Am I missing something with the try.. except usage?
The error that the real code raises on the failed attempts is due to
assert np.isclose(np.sum(x_tilde), 1.0)
AssertionError
for this reason I included the assert type(x) == float in the MWE, it raises the same exception, however, it carries on fine after hitting string, whereas my actual code only does the exceptions following a failure.
The real code has inside the try statement, where I have f(num)
try:
params = scipy.optimize.minimize(stuff)
if params.success:
stuff
except:
continue
Maybe the params.success is throwing it off since that doesn't exist when the scipy.optimize.minimize fails in the middle?
It does not appear to even attempt to do scipy.optimize.minimize on the next iteration once one of the initial guesses has caused scipy to fail.

Finally block is not executed in this code

The finally block in this code doesn't execute at all.
I have wrote this code to prevent assigning a None value to the current object, so I came up with an idea to use finally and assign this object with the previous state, but when I execute it the finally block doesn't execute at all (I have added a print statement to see if it's executed and it's not).
def __idiv__(self, other):
try:
if other is None:
raise ValueError('The second number is None')
if not isinstance(other, Complex):
other = Complex(other)
den = other * other.con()
num = self * other.con()
re = num.re / den.re
im = num.im / den.re
return Complex(re, im)
except (ZeroDivisionError, ValueError) as err:
print(colored('{}: {}'.format(err.__class__.__name__, err), 'red'))
finally:
print('-'*80)
return Complex(self.re, self.im)
When I call this method I just get this without the output of print statement in finally block:
ZeroDivisionError: float division by zero

why my code returns TypeError: 'NoneType' object is not iterable? [duplicate]

This question already has answers here:
What causes my function to return None at the end? [duplicate]
(5 answers)
Closed 3 years ago.
i am trying to define a function which checks strings whether they contains the word from a dictionary and return true along with which word matched . Below is the snippet of code , everything works fine when a word matches in the string from dictionary.
def trigcheck(strings,a):
try:
str = strings.split()
m=''
a_match = [True for match in a if match in str]
a=[m for m in a if m in str]
if True in a_match:
return True,a[0]
except:
return False,""
bool1,w=trigcheck("kjfdsnfbdskjhfbskdabs",['hello','do'])
print(bool1)
print(w)
I was expecting that with string that doesn't match should return False and ' ' . But it throws error saying:
bool1,w=trigcheck("kjfd s n f dobdskjhfbskdabs",['hello','do'])
TypeError: 'NoneType' object is not iterable
If you don't raise an exception, and True is not in a_match, you don't explicitly return at all, causing you to return None implicitly. Unpacking None to bool1 and w is what raises the exception.
Fix your code by making the exceptional return unconditional if the if check fails:
def trigcheck(strings,a):
try:
str = strings.split()
m=''
a_match = [True for match in a if match in str]
a=[m for m in a if m in str]
if True in a_match:
return True,a[0]
except Exception: # Don't use bare except unless you like ignoring Ctrl-C and the like
pass
# Failure return is outside except block, so fallthrough reaches
# it whether due to an exception or because the if check failed
return False,""
Additional side-note: Your test for a match existing is relatively inefficient; it can't short-circuit, and requires a temporary list. Replacing the body of your function with the following code which relies on your exception handling to return when there are no matches:
def trigcheck(strings,a):
try:
strings = strings.split() # Don't nameshadow builtins, reuse strings instead of shadowing str
return True, next(m for m in a if m in strings)
except StopIteration:
return False, ""
reduces three scans and a two temporary lists to a single scan and no temporary lists, and avoids silencing random exceptions (e.g. a TypeError because someone passed a non-string or non-iterable as an argument) by only catching the one that indicates a failure to find a match.

Best way to handle exceptions in functon args?

I was recently coding a few Python 3.x programs and I wonder what is the best way of handling simple exceptions in python function args. In this example I'm going with checking if inserted value can be converted to int. I've come up with two ways of doing this:
def test_err_try(x, y, z):
try:
int(x)
int(y)
int(z)
except ValueError or TypeError: #try handler
return 'Bad args.'
##code##
or
def test_err_if(x, y, z):
if type(x) != int or type(y) != int or type(z) != int: #if handler
raise ValueError('Bad args.')
else:
##code##
I know that there is a difference in what the handlers are returning - in the first case it's just string 'Bad args.' and in the second it is ValueError exception.
What is the best (or rather simplest and shortest) way? First, second or neither and there is a better one?
The answer depends on your use case. If you are building a function which will be exposed to an end user, then the try except block offers more functionality because it will allow any variable which can be converted to an int. In this case I would suggest raising an error rather than having the function return a string:
try:
x = int(x)
y = int(y)
z = int(z)
except ValueError:
raise TypeError("Input arguments should be convertible to int")
If the function is meant for internal use within your program, then it is best to use the assert statement because its evaluation can be disabled once you are finished debugging your program.
assert type(x) is int
assert type(y) is int
assert type(z) is int

Python3: Why does an exception needs explicit conversion while printing the message

class MyException(Exception):
def __str__(self):
return self.args[0]
def DoWork():
raise MyException("My hoverboard is full of eels")
pass
if __name__ == '__main__':
try:
DoWork()
except MyException as ex:
print("This will get printed: " + str(ex)) #Line1
print("This will not get printed and will raise exception: " + ex) #Line2
Why does an exception needs an explicit conversion in line 1. Ideally it should work as shown in Line2.
Note: I have tried both - the removal of str from MyException class and addition of str; neither of them worked.
Please help.
You have to convert it to a string because x + y ends up calling x.__add__(y), so when x is a string you call str.__add__, which operates on two strings, not on a string and an Exception. Python's built in operators and types generally don't automatically try to force things to be the right type (like javascript, for example), you have to be explicit. This is no different to having to use int() in x = 1 + int("12"), for example.
Note that if you don't want to use str(), you can use % formatting:
print("This will also work: %s" % ex)

Resources