Python Catching Exception But Printing Them - python

I have built a max heap and trying to extract max as long as there are elements. If there isn't I'm returning an IndexError. This the code I'm trying to execute:
while True:
try:
print hp.extract_max()
except:
break
and in the extract_max() method:
def extract_max(self):
if self.size == 0:
return IndexError
item = self.items[0]
self.items[0] = self.items[self.size - 1]
self.heapify_down()
del self.items[len(self.items) - 1]
return item
However, the code is not breaking upon encountering an IndexError, rather printing it too. The while loop is not breaking.
<type 'exceptions.IndexError'>
<type 'exceptions.IndexError'>
....
it keeps printing the exception, without breaking the loop.
What's the problem?

As the other answer stated, you should raise the exception instead of return so:
if self.size == 0:
raise IndexError
I just want to add that you are catching all type of exceptions with except, you might want to change it to catch IndexError only to avoid catching other exceptions (ex: KeyboardInterrupt) as the following:
while True:
try:
print hp.extract_max()
except IndexError:
break

You should be raising an exception, not returning it. Do raise IndexError.

Related

What is the proper way to write this exception handling?

I only want my list to have one element in it. There should be one exception raised if the list is empty and a different exception raised if the list has more than one element.
The following code accomplishes the task, but I don't think it's written as well as it should by any standards out there. Additionally, if the condition is met that the list is greater than one, I want it to print the python error "index out of range" as it does in the other condition. How can I improve upon this?
x = []
try:
if len(x) > 1:
raise Exception
else:
testVar = x[0]
except IndexError as e:
print(e)
print("list does not have any elements.")
except Exception as e:
print(e)
print("There are too many elements in the list.")
Here is a better way to write that.
def func(x):
if not x:
print("list does not have any elements.")
return None
if len(x) > 1:
print("There are too many elements in the list.")
return None
return x[0]
Note that if we omit the first three lines, then Python will automatically raise an IndexError when you refer to x[0].

How to avoid 'IndexError: list index out of range' error?

Suppose there are a list called 'my_list' and an int variable called 'list_index'. Basically, the list 'my_list' might change over time and hence the 'list_index' might raise 'IndexError: list index out of range'. However, I just want to make record when this error occurs since it is not that important. To avoid this error, my basic solutions currently are:
# My first way
if my_list[list_index: list_index +1]:
print('item exists')
else:
print('item does not exist')
# My second way
if -len(my_list) <= list_index < len(my_list):
print('item exists')
else:
print('item does not exist')
Except for try/except statement, are there other solutions to avoid the 'IndexError: list index out of range' error?
You can use a try-except.
a = [1,2,3]
try:
print(a[4])
except IndexError:
pass
What we can do in this scenario is we know a possible error can happen, so we encapsulate the statements where the error is prone to happen inside try and we add an except block with an error type where we define what the program should do if it encounters that error.
The general syntax for it is,
try:
# statements that can possibly cause an error
except error_type:
# what to do if an error occurred
So here the error you are mentioning is IndexError which catches the out of index exception in runtime. So a neat and pythonic way to do it is as follows.
try:
index_value = my_list[list_index]
except IndexError:
index_value = -1
print('Item index does not exist')
Use range(len(LIST)-1):
for i in range(len(LIST)-1):
if LIST[i] < LIST[i+1]:
... # you got an idea; no index error since range(len(LIST)-1)
actually you don't need to catch it, you need to avoid it by using following construction:
my_list = [1, 2, 3, 4]
for i in range(0, len(my_list)):
print(my_list[i])
len(my_list) - will prevent you to access to item that doesn't exist

what's the necessity of "else" in Python exception handling?

I am having trouble understanding the following control flow.
try:
# normal execution block
except A:
# handle exception A
except B:
# handle exception B
except:
# handle other exceptions
else:
# if no exceptions, go here
finally:
# always do this
I don't understand the purpose of the a else in this context. I am coming from Java where there is no else clause for handling exceptions.
If I have something to write in the else part, I would assume that I can directly write it outside of the exception handling part either.
So, whats the necessity of the else clause in Python exception handling?
If I have something to write in else clause,I can directly write outside of the exception handle part either.
No.
def with_else(x):
try:
int(x)
except ValueError:
print('that did not work')
else:
print('that worked!')
def without_else(x):
try:
int(x)
except ValueError:
print('that did not work')
print('that worked!')
Demo:
>>> with_else(1)
that worked!
>>> without_else(1)
that worked!
>>> with_else('foo')
that did not work
>>> without_else('foo')
that did not work
that worked!
processing = True
try:
x = might_raise_a_key_error()
# a
except KeyError:
...
else:
# b
finally:
processing = False
# c
If you have a piece of code which 1) depends on x, 2) you don’t want handled by except KeyError, but 3) you do want covered by the finally clause, do you put it in # a, # b or # c?
Answer: # b.

Confusion related to Nested Try Except in Python

def FancyDivide(numbers, index):
try:
try:
denom = numbers[index]
for i in range(len(numbers)):
numbers[i] /= denom
except IndexError, e:
FancyDivide(numbers, len(numbers) - 1)
else:
print "1"
finally:
print "0"
except ZeroDivisionError, e:
print "-2"
Function Output
>>> FancyDivide([0, 2, 4], 0)
0
-2
I expect only -2 as the answer but why 0. According to me ZeroDivisionError should be caught by last except statement and therefore the answer should be -2. Confused. Please Help.
The finally block will execute regardless of if an Exception is thrown or not.
With your code throwing the exception inside the nested try, the associated finally block will execute before the outer except.
You're right, the ZeroDivisionError will be caught by the outer try block, but finally clauses are always executed before leaving their respective try block (even when an exception is raised within it).
So in your case, the inner try raises the exception, the inner finally is executed, then the outer try catches the exception.
More info here: https://docs.python.org/2/tutorial/errors.html#defining-clean-up-actions

Continually catch exception in python

I need to keep catching an exception while indexing a list throws a IndexError exception, for example:
l = []
while((l[3]) throws IndexError):
//Add more data to the list
l += [3]
How can I keep checking to see if the method call has thrown an exception without having nested a nested try/catch block?
It depends what you would like to extend your list with. Assuming 'None' you could do it like this:
l = []
while True:
try:
l[3] = 'item'
break
except IndexError:
l.extend([None])
print l # [None, None, None, 'item']

Categories

Resources