Reputation: 43
I have had a similar problem in the past, python code crashing inside a try statement. The code fails because neither the file or the directory that it is trying to open exist. But as it is inside a try statement, i dont understand why the code breaks.
{To save any reader from spending too much time trying to understand the premise of the code. It is trying to find vertices for a region file, from;
a) a master file, if it doesnt exist or it is bad, try (b)
b) a file specific to its name, if it doesnt exist or it is bad, do (c)
c) to create a new one }
p.s. The following code is inelegant and probably won't be the final solution to what im trying to do.
try:
x1,y1, x2,y2 = np.loadtxt('regions/master.reg')
plt.plot([x1,x1,x2,x2,x1],[y1,y2,y2,y1,y1], c='k')
plt.draw()
if (raw_input('Master Acceptable? (y/n): ') =='n'): raise(NameError)
except NameError:
try:
x1,y1, x2,y2 = np.loadtxt('regions/'+self.name[:-5]+'.reg')
plt.plot([x1,x1,x2,x2,x1],[y1,y2,y2,y1,y1], c='r')
plt.draw()
if raw_input('Reg Acceptable? (y/n): ') =='n': raise(NameError)
except NameError:
quality = False
while not quality:
x1=int(input('x, top left: '))
y1=int(input('y, top right: '))
x2=int(input('x, bottom left: '))
y2=int(input('y, bottom right: '))
plt.plot([x1,x1,x2,x2,x1],[y1,y2,y2,y1,y1], c='r')
plt.draw()
if raw_input('Acceptable? (y/n): ') =='y': quality=True
And the error (just saying that the file doesnt exist)
File "pre_science.py", line 45, in crop
x1,y1, x2,y2 = np.loadtxt('regions/master.reg')
File "/usr/local/lib/python2.7/dist-packages/numpy/lib/npyio.py", line 917, in loadtxt
fh = np.lib._datasource.open(fname, 'rt', encoding=encoding)
File "/usr/local/lib/python2.7/dist-packages/numpy/lib/_datasource.py", line 260, in open
return ds.open(path, mode, encoding=encoding, newline=newline)
File "/usr/local/lib/python2.7/dist-packages/numpy/lib/_datasource.py", line 616, in open
raise IOError("%s not found." % path)
IOError: regions/master.reg not found.
So my question being, is this an expected behaviour?
Upvotes: 0
Views: 382
Reputation: 3497
You're specifying in your try-except block that you're expecting a NameError, but you're getting an IOError.
By using
try:
....
except NameError:
....
you're handling only exceptions of type NameError. All other exceptions (in your case IOError) that are thrown up are not handled anywhere, thus crashing your code.
Remove the NameError after the expect or add additional expected errors in the following manner
try:
....
expect NameError, IOError:
....
Upvotes: 1
Reputation: 42748
NameError
is the wrong exception type, use OSError
:
try:
x1,y1, x2,y2 = np.loadtxt('regions/master.reg')
plt.plot([x1,x1,x2,x2,x1],[y1,y2,y2,y1,y1], c='k')
plt.draw()
if raw_input('Master Acceptable? (y/n): ') =='n': raise OSError()
except OSError:
try:
x1,y1, x2,y2 = np.loadtxt('regions/'+self.name[:-5]+'.reg')
plt.plot([x1,x1,x2,x2,x1],[y1,y2,y2,y1,y1], c='r')
plt.draw()
if raw_input('Reg Acceptable? (y/n): ') =='n': raise OSError()
except OSError:
while True:
x1=int(input('x, top left: '))
y1=int(input('y, top right: '))
x2=int(input('x, bottom left: '))
y2=int(input('y, bottom right: '))
plt.plot([x1,x1,x2,x2,x1],[y1,y2,y2,y1,y1], c='r')
plt.draw()
if raw_input('Acceptable? (y/n): ') =='y':
break
In general, NameError
should not be used as user-generated exception, because a NameError
indicates nearly always a programming error.
In the spirit of «don't repeat yourself» the restructured code look's like this:
from functools import partial
from itertools import cycle, chain
def input_rect():
x1 = int(raw_input('x, top left: '))
y1 = int(raw_input('y, top right: '))
x2 = int(raw_input('x, bottom left: '))
y2 = int(raw_input('y, bottom right: '))
for reader in chain([
partial(np.loadtxt, 'regions/master.reg'),
partial(np.loadtxt, 'regions/'+self.name[:-5]+'.reg'),
], cycle([input_rect]))
try:
x1, y1, x2, y2 = reader()
except (ValueError, OSError):
pass
else:
plt.plot([x1,x1,x2,x2,x1],[y1,y2,y2,y1,y1], c='r')
plt.draw()
if raw_input('Acceptable? (y/n): ') == 'y':
break
Upvotes: 0
Reputation: 12015
You are trying to catch only NameError. Make it to catch both IOError and NameError
try:
...
...
except (IOError, NameError):
...
...
Upvotes: 0