Skip to content

Commit f58e942

Browse files
committed
replace sys.exit with raise errors
1 parent ad7164b commit f58e942

File tree

7 files changed

+115
-154
lines changed

7 files changed

+115
-154
lines changed

devtests.ipynb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
"cell_type": "code",
2525
"execution_count": null,
2626
"metadata": {
27-
"collapsed": true
27+
"collapsed": false
2828
},
2929
"outputs": [],
3030
"source": []

wfdb/_headers.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import numpy as np
22
import re
33
import os
4-
import sys
54
from collections import OrderedDict
65
from calendar import monthrange
76
from . import _signals
@@ -193,7 +192,7 @@ def checkfieldcohesion(self, recwritefields, sigwritefields):
193192
# even if some of its elements are None.
194193
for f in sigwritefields:
195194
if len(getattr(self, f)) != self.nsig:
196-
sys.exit('The length of field: '+f+' must match field nsig.')
195+
raise ValueError('The length of field: '+f+' must match field nsig.')
197196

198197
# Each filename must correspond to only one fmt, (and only one byte offset if defined).
199198
datfmts = {}
@@ -202,7 +201,7 @@ def checkfieldcohesion(self, recwritefields, sigwritefields):
202201
datfmts[self.filename[ch]] = self.fmt[ch]
203202
else:
204203
if datfmts[self.filename[ch]] != self.fmt[ch]:
205-
sys.exit('Each filename (dat file) specified must have the same fmt')
204+
raise ValueError('Each filename (dat file) specified must have the same fmt')
206205

207206
datoffsets = {}
208207
if self.byteoffset is not None:
@@ -214,7 +213,7 @@ def checkfieldcohesion(self, recwritefields, sigwritefields):
214213
datoffsets[self.filename[ch]] = self.byteoffset[ch]
215214
else:
216215
if datoffsets[self.filename[ch]] != self.byteoffset[ch]:
217-
sys.exit('Each filename (dat file) specified must have the same byte offset')
216+
raise ValueError('Each filename (dat file) specified must have the same byte offset')
218217

219218

220219
# Write a header file using the specified fields
@@ -320,11 +319,11 @@ def checkfieldcohesion(self):
320319
# The length of segname and seglen must match nseg
321320
for f in ['segname', 'seglen']:
322321
if len(getattr(self, f)) != self.nseg:
323-
sys.exit('The length of field: '+f+' does not match field nseg.')
322+
raise ValueError('The length of field: '+f+' does not match field nseg.')
324323

325324
# Check the sum of the 'seglen' fields against 'siglen'
326325
if np.sum(self.seglen) != self.siglen:
327-
sys.exit("The sum of the 'seglen' fields do not match the 'siglen' field")
326+
raise ValueError("The sum of the 'seglen' fields do not match the 'siglen' field")
328327

329328

330329
# Write a header file using the specified fields

wfdb/_signals.py

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import numpy as np
22
import os
3-
import sys
43
from . import downloads
54

65
# All defined WFDB dat formats
@@ -32,11 +31,10 @@ def checksignalcohesion(self, writefields):
3231

3332
# Match the actual signal shape against stated length and number of channels
3433
if (self.siglen, self.nsig) != self.d_signals.shape:
35-
print('siglen and nsig do not match shape of d_signals')
3634
print('siglen: ', self.siglen)
3735
print('nsig: ', self.nsig)
3836
print('d_signals.shape: ', self.d_signals.shape)
39-
sys.exit()
37+
raise ValueError('siglen and nsig do not match shape of d_signals')
4038

4139
# For each channel (if any), make sure the digital format has no values out of bounds
4240
for ch in range(0, self.nsig):
@@ -46,20 +44,20 @@ def checksignalcohesion(self, writefields):
4644
chmin = min(self.d_signals[:,ch])
4745
chmax = max(self.d_signals[:,ch])
4846
if (chmin < dmin) or (chmax > dmax):
49-
sys.exit("Channel "+str(ch)+" contain values outside allowed range ["+str(dmin)+", "+str(dmax)+"] for fmt "+str(fmt))
47+
raise IndexError("Channel "+str(ch)+" contain values outside allowed range ["+str(dmin)+", "+str(dmax)+"] for fmt "+str(fmt))
5048

5149
# Ensure that the checksums and initial value fields match the digital signal (if the fields are present)
5250
if self.nsig>0:
5351
if 'checksum' in writefields:
5452
realchecksum = self.calc_checksum()
5553
if self.checksum != realchecksum:
56-
print("checksum field does not match actual checksum of d_signals: ", realchecksum)
57-
sys.exit()
54+
print("The actual checksum of d_signals is: ", realchecksum)
55+
raise ValueError("checksum field does not match actual checksum of d_signals")
5856
if 'initvalue' in writefields:
5957
realinitvalue = list(self.d_signals[0,:])
6058
if self.initvalue != realinitvalue:
61-
print("initvalue field does not match actual initvalue of d_signals: ", realinitvalue)
62-
sys.exit()
59+
print("The actual initvalue of d_signals is: ", realinitvalue)
60+
raise ValueError("initvalue field does not match actual initvalue of d_signals")
6361

6462

6563
def set_p_features(self, do_dac = False):
@@ -116,7 +114,7 @@ def set_d_features(self, do_adc = False, singlefmt = 1):
116114
if self.fmt is None:
117115
# Make sure that neither adcgain nor baseline are set
118116
if self.adcgain is not None or self.baseline is not None:
119-
sys.exit('If fmt is not set, gain and baseline may not be set either.')
117+
raise Exception('If fmt is not set, gain and baseline may not be set either.')
120118
# Choose appropriate fmts based on estimated signal resolutions.
121119
res = estres(self.p_signals)
122120
self.fmt = wfdbfmt(res, singlefmt)
@@ -130,7 +128,7 @@ def set_d_features(self, do_adc = False, singlefmt = 1):
130128
self.adcgain, self.baseline = self.calculate_adcparams()
131129
# Exactly one field set
132130
elif (self.adcgain is None) ^ (self.baseline is None):
133-
sys.exit('If fmt is set, gain and baseline should both be set or not set.')
131+
raise Exception('If fmt is set, gain and baseline should both be set or not set.')
134132

135133
self.checkfield('adcgain', 'all')
136134
self.checkfield('baseline', 'all')
@@ -230,7 +228,7 @@ def calculate_adcparams(self):
230228

231229
# WFDB library limits...
232230
if abs(gain)>214748364 or abs(baseline)>2147483648:
233-
sys.exit('Chen, please fix this')
231+
raise Exception('cx1111, please fix this!')
234232

235233
gains.append(gain)
236234
baselines.append(baseline)
@@ -853,7 +851,7 @@ def wfdbfmtres(fmt):
853851
elif fmt == '32':
854852
return 32
855853
else:
856-
sys.exit('Invalid WFDB format.')
854+
raise ValueError('Invalid WFDB format.')
857855

858856
# Write a dat file.
859857
# All bytes are written one at a time
@@ -956,7 +954,7 @@ def wrdatfile(filename, fmt, d_signals, byteoffset):
956954
# Convert to unsigned 8 bit dtype to write
957955
bwrite = bwrite.astype('uint8')
958956
else:
959-
sys.exit('This library currently only supports the following formats: 80, 16, 24, 32')
957+
raise ValueError('This library currently only supports writing the following formats: 80, 16, 24, 32')
960958

961959
# Byte offset in the file
962960
if byteoffset is not None and byteoffset>0:

wfdb/annotations.py

Lines changed: 18 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import numpy as np
22
import pandas as pd
3-
import sys
43
import re
54
import os
65
from . import _headers
@@ -99,7 +98,7 @@ def checkfields(self):
9998
for field in ['recordname', 'annotator', 'annsamp', 'anntype']:
10099
if getattr(self, field) is None:
101100
print('The ', field, ' field is mandatory for writing annotation files')
102-
sys.exit()
101+
raise Exception('Missing required annotation field')
103102

104103
# Check all set fields
105104
for field in annfields:
@@ -114,32 +113,30 @@ def checkfield(self, field):
114113
if field in ['recordname', 'annotator', 'fs']:
115114
# Check the field type
116115
if type(getattr(self, field)) not in annfieldtypes[field]:
117-
print('The '+field+' field must be one of the following types:')
118116
print(annfieldtypes[field])
119-
sys.exit()
117+
raise TypeError('The '+field+' field must be one of the above types.')
120118

121119
# Field specific checks
122120
if field == 'recordname':
123121
# Allow letters, digits, hyphens, and underscores.
124122
acceptedstring = re.match('[-\w]+', self.recordname)
125123
if not acceptedstring or acceptedstring.string != self.recordname:
126-
sys.exit('recordname must only comprise of letters, digits, hyphens, and underscores.')
124+
raise ValueError('recordname must only comprise of letters, digits, hyphens, and underscores.')
127125
elif field == 'annotator':
128126
# Allow letters only
129127
acceptedstring = re.match('[a-zA-Z]+', self.annotator)
130128
if not acceptedstring or acceptedstring.string != self.annotator:
131-
sys.exit('annotator must only comprise of letters')
129+
raise ValueError('annotator must only comprise of letters')
132130
elif field == 'fs':
133131
if self.fs <=0:
134-
sys.exit('The fs field must be a non-negative number')
132+
raise ValueError('The fs field must be a non-negative number')
135133

136134
else:
137135
fielditem = getattr(self, field)
138136

139137
# Ensure the field item is a list or array.
140138
if type(fielditem) not in [list, np.ndarray]:
141-
print('The ', field, ' field must be a list or numpy array')
142-
sys.exit()
139+
raise TypeError('The '+field+' field must be a list or numpy array')
143140

144141
# Check the data types of the elements
145142
# annsamp and anntype may NOT have nones. Others may.
@@ -149,44 +146,44 @@ def checkfield(self, field):
149146
print("All elements of the '", field, "' field must be one of the following types:")
150147
print(annfieldtypes[field])
151148
print("All elements must be present")
152-
sys.exit()
149+
raise Exception()
153150
else:
154151
for item in fielditem:
155152
if item is not None and type(item) not in annfieldtypes[field]:
156153
print("All elements of the '", field, "' field must be one of the following types:")
157154
print(annfieldtypes[field])
158155
print("Elements may also be set to 'None'")
159-
sys.exit()
156+
raise Exception()
160157

161158
# Field specific checks
162159
# The C WFDB library stores num/sub/chan as chars.
163160
if field == 'annsamp':
164161
sampdiffs = np.concatenate(([self.annsamp[0]], np.diff(self.annsamp)))
165162
if min(self.annsamp) < 0 :
166-
sys.exit("The 'annsamp' field must only contain non-negative integers")
163+
raise ValueError("The 'annsamp' field must only contain non-negative integers")
167164
if min(sampdiffs) < 0 :
168-
sys.exit("The 'annsamp' field must contain monotonically increasing sample numbers")
165+
raise ValueError("The 'annsamp' field must contain monotonically increasing sample numbers")
169166
if max(sampdiffs) > 2147483648:
170-
sys.exit('WFDB annotation files cannot store sample differences greater than 2**31')
167+
raise ValueError('WFDB annotation files cannot store sample differences greater than 2**31')
171168
elif field == 'anntype':
172169
# Ensure all fields lie in standard WFDB annotation codes
173170
if set(self.anntype) - set(annsyms.values()) != set():
174171
print("The 'anntype' field contains items not encoded in the WFDB annotation library.")
175172
print('To see the valid annotation codes call: showanncodes()')
176173
print('To transfer non-encoded anntype items into the aux field call: self.type2aux()')
177-
sys.exit()
174+
raise Exception()
178175
elif field == 'subtype':
179176
# signed character
180177
if min(self.subtype) < 0 or max(self.subtype) >127:
181-
sys.exit("The 'subtype' field must only contain non-negative integers up to 127")
178+
raise ValueError("The 'subtype' field must only contain non-negative integers up to 127")
182179
elif field == 'chan':
183180
# unsigned character
184181
if min(self.chan) < 0 or max(self.chan) >255:
185-
sys.exit("The 'chan' field must only contain non-negative integers up to 255")
182+
raise ValueErrort("The 'chan' field must only contain non-negative integers up to 255")
186183
elif field == 'num':
187184
# signed character
188185
if min(self.num) < 0 or max(self.num) >127:
189-
sys.exit("The 'num' field must only contain non-negative integers up to 127")
186+
raise ValueError("The 'num' field must only contain non-negative integers up to 127")
190187
#elif field == 'aux': # No further conditions for aux field.
191188

192189

@@ -198,7 +195,7 @@ def checkfieldcohesion(self):
198195
for field in ['annsamp', 'anntype', 'num', 'subtype', 'chan', 'aux']:
199196
if getattr(self, field) is not None:
200197
if len(getattr(self, field)) != nannots:
201-
sys.exit("All written annotation fields: ['annsamp', 'anntype', 'num', 'subtype', 'chan', 'aux'] must have the same length")
198+
raise ValueError("All written annotation fields: ['annsamp', 'anntype', 'num', 'subtype', 'chan', 'aux'] must have the same length")
202199

203200
# Write an annotation file
204201
def wrannfile(self):
@@ -260,10 +257,10 @@ def type2aux(self):
260257

261258
# Ensure that anntype is a list of strings
262259
if type(self.anntype)!= list:
263-
sys.exit('anntype must be a list')
260+
raise TypeError('anntype must be a list')
264261
for at in self.anntype:
265262
if type(at) != str:
266-
sys.exit('anntype elements must all be strings')
263+
raise TypeError('anntype elements must all be strings')
267264

268265
external_anntypes = set(self.anntype) - set(annsyms.values())
269266

wfdb/downloads.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import numpy as np
22
import re
33
import os
4-
import sys
54
import requests
65

76
# Read a header file from physiobank
@@ -110,7 +109,7 @@ def getrecordlist(dburl, records):
110109
if records == 'all':
111110
r = requests.get(os.path.join(dburl, 'RECORDS'))
112111
if r.status_code == 404:
113-
sys.exit('The database '+dburl+' has no WFDB files to download')
112+
raise ValueError('The database '+dburl+' has no WFDB files to download')
114113

115114
# Get each line as a string
116115
recordlist = r.content.decode('ascii').splitlines()
@@ -129,7 +128,7 @@ def getannotators(dburl, annotators):
129128
if annotators == 'all':
130129
return
131130
else:
132-
sys.exit('The database '+dburl+' has no annotation files to download')
131+
raise ValueError('The database '+dburl+' has no annotation files to download')
133132
# Make sure the input annotators are present in the database
134133
annlist = r.content.decode('ascii').splitlines()
135134
annlist = [a.split('\t')[0] for a in annlist]
@@ -145,7 +144,7 @@ def getannotators(dburl, annotators):
145144
# user input ones. Check validity.
146145
for a in annotators:
147146
if a not in annlist:
148-
sys.exit('The database contains no annotators with extension: ', a)
147+
raise ValueError('The database contains no annotators with extension: '+a)
149148

150149
return annotators
151150

0 commit comments

Comments
 (0)