Basic Exception Handling - python

I'm trying to just execute this simple exceptiion handler and it won't work for some reason. I want it to throw the exception and write the error to a file.
fileo = "C:/Users/bgbesase/Documents/Brent/ParsePractice/out.txt"
g = 4
h = 6
try:
if g > h:
print 'Hey'
except Exception as e:
f = open(fileo, 'w')
f.truncate()
f.write(e)
f.close()
print e
Any ideas what I am doing wrong?

Your snippet is not supposed to raise any exceptions. Maybe you want to do something like
try:
if g > h:
print 'Hey'
else:
raise NotImplementedError('This condition is not handled here!')
except Exception as e:
# ...
Another possibility is that you meant to say:
try:
assert g > h
print 'Hey!'
except AssertionError as e:
# ...
The assert keyword basically behaves like a "fail-safe." If the condition is false, it will raise an AssertionError exception. It is often used to check preconditions for arguments to functions. (Say a value needs to be greater than zero for the function to make sense.)
Edit:
An exception is a sort of "signal" in your code that halts whatever your program was doing and finds it way to the nearest "exception handler." Whenever an exception occurs in your program, all execution immediately halts, and it tries to go to the nearest except: section of the code. If none exists, the program crashes. Try executing the following program:
print 'Hello. I will try doing a sum now.'
sum = 3 + 5
print 'This is the sum: ' + str(sum)
print 'Now I will do a division!'
quotient = 5/0
print 'This is the result of that: ' + str(quotient)
If you run it, you will see that your program crashes. My Python tells me:
ZeroDivisionError: integer division or modulo by zero
This is an exception! Something exceptional happened! You can't divide by zero, of course. As you now know, this exception is a sort of signal that finds its way to the closest exception: block, or the exception handler. We can rewrite this program so it is safer.
try:
print 'Hello. I will try doing a sum now.'
sum = 3 + 5
print 'This is the sum: ' + str(sum)
print 'Now I will do a division!'
quotient = 5/0
print 'This is the result of that: ' + str(quotient)
except Exception as e:
print 'Something exceptional occurred!'
print e
Now we catch the exception, the signal that something exceptional happened. We put the signal in the variable e and we print it. Now your program will result in
Something exceptional occurred!
integer division or modulo by zero
When the ZeroDivisionError exception occurred, it stopped the execution at that spot, and went straight to the exception handler. We can also manually raise exceptions if we want to.
try:
print 'This you will see'
raise Exception('i broke your code')
print 'This you will not'
except Exception as e:
print 'But this you will. And this is the exception that occurred:'
print e
The raise keyword manually sends an exception signal. There are different kinds of exceptions, like the ZeroDivisionError exception, the AssertionError exception, the NotImplementedError exception and tons more, but I leave those for further studies.
In your original code, there was nothing exceptional happening, so that's why you never saw an exception getting triggered. If you want to trigger an exception based on a condition (like g > h) you can use the assert keyword, which behaves a little like raise, but it only raises an exception when the condition is false. So if you write
try:
print 'Is all going well?'
assert 3 > 5
print 'Apparently so!'
except AssertionError as e:
print 'Nope, it does not!'
You will never see the "Apparently so!" message, since the assertion is false and it triggers an exception. Assertion are useful for making sure values make sense in your program and you want to abort the current operation if they don't.
(Note that I caught explicitly the AssertionError in my exception handling code. This will not catch other exceptions, only AssertionErrors. You'll get to this in no time if you continue reading about exceptions. Don't worry too much about them now.)

You're not actually ever raising an exception. To raise an exception, you need to use the raise keyword with an Exception class or instance of an Exception class. In this case, I would recommend a ValueError as you've gotten a bad value.
fileo = "C:/Users/bgbesase/Documents/Brent/ParsePractice/out.txt"
g = 4
h = 6
try:
if g > h:
raise ValueError('Hey')
except Exception as e:
f = open(fileo, 'w')
f.truncate()
f.write(str(e))
f.close()
print e

Related

How to stop an Error from being caught by more than one except blocks?

I have some code inside a try block that throws a ValueError. I have an except block that catches this ValueError and handles it. Once this is done I do not want other except blocks to catch this ValueError.
In the code below, there is another try except block later in the code and this ValueError is being caught by the second except too. How can I make sure the ValueError is caught only by the first except and not the second one?
# Get features to plot
try: #First Try Block
raw_features_list_1 = fsobject_1.genFeature(gmm.FftClassifier.fft_features)
except ValueError: #First Except Block
pass
filtered_features_list_1 = np.array([row[0] for row in raw_features_list_1 if row is not None]).reshape(-1, 1)
try: #Second Try Block
raw_features_list_2 = fsobject_2.genFeature(gmm.FftClassifier.fft_features)
except ValueError: #Second Except Block
pass
print("I am here")
filtered_features_list_2 = np.array([row[0] for row in raw_features_list_2 if row is not None]).reshape(-1, 1)
The above code gives me the following result:
I am here
NameError Traceback (most recent call last)
<ipython-input-16-ff0067cb5362> in <module>
11 pass
12 print("I am here")
---> 13 filtered_features_list_2 = np.array([row[0] for row in raw_features_list_2 if row is not None]).reshape(-1, 1)
NameError: name 'raw_features_list_2' is not defined
This is because due to the ValueError generated by the first Try Block the second try block is not being evaluated and the the second Except block is being evaluated directly.
I would like to evaluate the first Try Blocks, handle the ValueError in the First Except Block. Then evaluate the second Try Blocks and, if it generates a ValueError, handle that in the second Except Block.
Sorry looks like what I am asking is already the default behavior of python.
I had another issue where the function generating raw_features_list_2 was throwing a ValueError and aborting before returning raw_features_list_2. So I felt as if the second try block wasn't being evaluated at all. I fixed my problem by handling the exception inside the function that returns raw_features_list_2.
As can be seen below, python catches an exception only once.
In [26]: try:
...: 1/0
...: except ZeroDivisionError:
...: print("Caught")
...: try:
...: pass
...: except ZeroDivisionError:
...: print("Caught Again")
Caught
So my question is..kind of irrelevant.

Results won't be written into the txt file

Even though I'm using file.flush() at the end, no data will be written into the txt file.
# some essential code to connect to the server
while True:
try:
# do some stuff
try:
gaze_positions = filtered_surface['gaze_on_srf']
for gaze_pos in gaze_positions:
norm_gp_x, norm_gp_y = gaze_pos['norm_pos']
if (0 <= norm_gp_x <= 1 and 0 <= norm_gp_y <= 1):
with open('/the/path/to/the/file.txt', 'w') as file:
file.write('[' + norm_gp_x + ', ' + norm_gp_y + ']')
file.flush()
print(norm_gp_x, norm_gp_y)
except:
pass
except KeyboardInterrupt:
break
What am I doing wrong? Obvisouly I miss something, but I can't figure it out, what it is. Another odd thing: there's even no output for print(norm_gp_x, norm_gp_y). If I put the with open ... in a comment, I'll get the output.
got it:
First
if (0 <= norm_gp_x <= 1 and 0 <= norm_gp_y <= 1):
then:
file.write('[' + norm_gp_x + ', ' + norm_gp_y + ']')
So you're adding strings and integers. This triggers an exception, and since you used an universal except: pass construct, the code skips every iteration (note that this except statement also catches the KeyboardInterrupt exception you're trying to catch at a higher level, so that doesn't work either)
Never use that construct. If you want to protect about a specific exception (ex: IOError), use:
try IOError as e:
print("Warning: got exception {}".format(e))
so your exception is 1) focused and 2) verbose. Always wait until you get exceptions that you want to ignore to ignore them, selectively (read Catch multiple exceptions in one line (except block))
So the fix for your write it:
file.write('[{},{}]'.format(norm_gp_x, norm_gp_y))
or using the list representation since you're trying to mimic it:
file.write(str([norm_gp_x, norm_gp_y]))
Aside: your other issue is that you should use append mode
with open('/the/path/to/the/file.txt', 'a') as file:
or move you open statement before the loop, else you'll only get the last line in the file (a classic) since w mode truncates the file when opening. And you can drop flush since exiting the context closes the file.

check try exception IndexError in python

I have this two pieces of code:
try:
error1=tree.xpath[...]
error2=tree.xpath[...]
except IndexError:
print 'hello' #piece 1
try:
error3=tree.xpath[...]
error4=tree.xpath[...]
except IndexError:
print 'hello' #piece 2
Depends on what xpath pattern is, one of two pieces work well. For example for some sites piece 1 is working fine (so I have to comment piece 2) and for some other sites piece two is working fine (so I have to comment out piece 1).
How can I mix and use both pieces in all conditions for all web sites I am using them?
You can nest exceptions:
try:
error1=tree.xpath[...]
error2=tree.xpath[...]
print "Method 1 succeed"
except IndexError:
print "Method 1 failed, trying method 2"
try:
error3=tree.xpath[...]
error4=tree.xpath[...]
print "Method 2 succeed"
except IndexError:
print 'Both method failed'
You can use the same code by introducing a new variable which keeps a check if the commands were successful.
success = False
try:
error1=tree.xpath[...]
error2=tree.xpath[...]
success = True
except IndexError:
print 'hello' #snippet 1
if not success:
try:
error1=tree.xpath[...]
error2=tree.xpath[...]
except IndexError:
print 'hello' #snippet 2

Better way to fail a try in python if result is valid but not wanted

If you do a try in python, and the code doesn't fail, but it's outside of a range you want or something, what is the best way to make it fail so it goes to the except?
A simple example is as follows, to check the input is a number between 0 and 1:
input = 0.2
try:
if 0 < float( input ) < 1:
print "Valid input"
else:
"fail"+0 (to make the code go to except)
except:
print "Invalid input"
Is there a better way to go about this? The between range is just an example, so it should work with other things too (also, in the above example, it should also be able to use a number in string format, so detecting the type wouldn't really work).
Sorry but rchang's answer is not reliable for production code (assert statements are skipped if Python is run with the -O flag). The correct solution is to raise a ValueError, ie:
try:
if 0 < float(input) < 1:
raise ValueError("invalid input value")
print "Valid input"
except (TypeError, ValueError):
print "Invalid input"
You can use the raise statement:
try:
if (some condition):
Exception
except:
...
Note that Exception can be more specific, like for example, a ValueError, or maybe it can be an exception defined by you:
class MyException(Exception):
pass
try:
if (some condition):
raise MyException
except MyException:
...
The other answer is accurate. But to educate you more about exception handling ... you could use raise.
Also consider Bruno's comment where he says:
You also want to catch TypeError in case input is neither a string nor a number.
Thus in this case we may add another except block
input = 1.2
try:
if 0 < float( input ) < 1:
print "Valid input"
else:
raise ValueError #(to make the code go to except)
except ValueError:
print "Input Out of Range"
except TypeError:
print "Input NaN"
TypeError will be raised iff the input is an object ( for e.g)
The built-in assertion mechanism may be a fit here.
input = 0.2
try:
assert 0 < float( input ) < 1
print "Valid input"
except (AssertionError, ValueError):
print "Invalid input"
AssertionError will be raised if the condition you provide to the assert statement does not evaluate to True. Also, upon attempting the float conversion upon an invalid value would raise the ValueError.

Execute if no exception thrown

I have some code I want to execute if an exception is not thrown.
Currently I'm doing this:
try:
return type, self.message_handlers[type](self, length - 1)
finally:
if not any(self.exc_info()):
self.last_recv_time = time.time()
Can this be improved on? Is this the best way to do it?
Update0
The optional else clause is executed if and when control flows off the
end of the try clause.
Currently, control “flows off the end” except in the case of an
exception or the execution of a return, continue, or break statement.
try:
tmp = type, self.message_handlers[type](self, length - 1)
except Exception:
pass #or handle error, or just "raise" to re-raise
else:
self.last_recv_time = time.time()
return tmp
Your code suggests that you don't want to catch the exception if it occurs, so why not simply
result = type, self.message_handlers[type](self, length - 1)
self.last_recv_time = time.time()
return result
(Am I missing anything?)

Categories