I have a plain text file which contains lines with fields below:
<str_addr_a> <hex_int_addr>
<str_addr_a> <hex_int_addr> <dec_int_addr>
<str_addr_a> <str_addr_b>
<str_addr_a> <str_addr_b> <hex_int_addr>
<str_addr_a> <str_addr_b> <hex_int_addr> <dec_int_addr>
For example, the content of the file could be following:
# <str_addr_a> <hex_int_addr>
dkfi A18A
# <str_addr_a> <str_addr_b>
kloe uuep
# <str_addr_a> <str_addr_b> <hex_int_addr> <dec_int_addr>
ctff yaaq BBF2 19
# <str_addr_a> <str_addr_b> <hex_int_addr>
fkii hhyf E118
# <str_addr_a> <str_addr_b> <hex_int_addr> <dec_int_addr>
ctkj yuuq BBF0 12
I'm reading the file with function below:
def read_data(file):
with open(file, 'r', encoding='utf-8') as f:
addresses = []
for line_nr, line in enumerate(f, start=1):
line = line.strip()
if line and not line.startswith('#'):
str_addr_a = str_addr_b = hex_int_addr = dec_int_addr = None
try:
# '<str_addr_a> <hex_int_addr>'
str_addr_a, hex_int_addr = line.split()
if not is_valid_str_addr(str_addr_a):
raise ValueError from None
hex_int_addr = hex_addr(hex_int_addr).compress
except ValueError:
try:
# '<str_addr_a> <hex_int_addr> <dec_int_addr>'
str_addr_a = hex_int_addr = None
str_addr_a, hex_int_addr, dec_int_addr = line.split()
if not is_valid_str_addr(str_addr_a):
raise ValueError from None
hex_int_addr = hex_addr(hex_int_addr).compress
dec_int_addr = int(dec_int_addr)
except ValueError:
try:
# '<str_addr_a> <str_addr_b>'
str_addr_a = hex_int_addr = dec_int_addr = None
str_addr_a, str_addr_b = line.split()
if not is_valid_str_addr(str_addr_a):
raise ValueError from None
if not is_valid_str_addr(str_addr_b):
raise ValueError from None
except ValueError:
try:
# '<str_addr_a> <str_addr_b> <hex_int_addr>'
str_addr_a = str_addr_b = None
str_addr_a, str_addr_b, hex_int_addr = line.split()
if not is_valid_str_addr(str_addr_a):
raise ValueError from None
if not is_valid_str_addr(str_addr_b):
raise ValueError from None
hex_int_addr = hex_addr(hex_int_addr).compress
except ValueError:
try:
# '<str_addr_a> <str_addr_b> <hex_int_addr>
# <dec_int_addr>'
str_addr_a = str_addr_b = hex_int_addr = None
str_addr_a, str_addr_b, hex_int_addr, \
dec_int_addr = line.split()
if not is_valid_str_addr(str_addr_a):
raise ValueError from None
if not is_valid_str_addr(str_addr_b):
raise ValueError from None
hex_int_addr = hex_addr(hex_int_addr).compress
dec_int_addr = int(dec_int_addr)
except ValueError:
logging.error(f'{file}: error on line number {line_nr}')
continue
addresses.append((str_addr_a, str_addr_b, hex_int_addr, dec_int_addr))
return(addresses)
As seen above, each try/except
block tests one of the possible line formats. Such code introduces quite a lot of branches and isn't very flat. Is there a more elegant way to process such data file? Or perhaps the way I'm doing this is fine?
is_valid_str_addr
andhex_addr
. \$\endgroup\$hex_addr().compress
? \$\endgroup\$