I'd like to eliminate the code duplication in the following two methods by moving the common code into a separate method callable by both. The comments indicate the blocks of code that have a differing implementation in each method.
def compute_totals_h(self, size, bad_codes):
with open(self._in_file_path, self._FILE_READ_MODE) as f:
# initialize reader
reader = csv.reader(f)
field_names = reader.next()
for i, code in enumerate(field_names):
code = code.strip(string.punctuation).upper()
field_names[i] = code
for code in field_names:
if (len(code) <= size) and (code not in bad_codes):
self._totals[code] = 0
for row in reader:
# get totals
for i, val in enumerate(row):
code = field_names[i]
if (code in self._totals):
self._totals[code] += string_utils.to_int(val)
self._write_totals()
def compute_totals_v(self, code_field, est_field):
with open(self._in_file_path, self._FILE_READ_MODE) as f:
# initialize reader
reader = csv.DictReader(f)
for row in reader:
# get totals
code = row[code_field].strip(string.punctuation).upper()
est = string_utils.to_int(row[est_field])
if code in self._totals:
self._totals[code] += est
else:
self._totals[code] = est
self._write_totals()
I'm thinking of a solution that has a common abstract method that can be called from compute_totals_h
and compute_totals_v
with each method passing functions to handle its implementation. I can't figure out how to do this while passing the arguments for each implementation correctly. It would look something like:
def compute_totals(self, initialize_reader, get_totals):
with open(self._in_file_path, self._FILE_READ_MODE) as f:
reader = initialize_reader(f)
for row in reader:
get_totals(row)
self._write_totals()
I'll also appreciate suggestions on a better way of handling this type of code refactoring to eliminate this general class of code duplication problems.
string_utils.to_int
? Any reason to not use the builtinint
? \$\endgroup\$code_field
andest_field
? \$\endgroup\$int
since I need to handle strings that are not numeric in a predictable way (returning0
).string_utils.to_int
is a wrapper function aroundint
which catchesValueError
andTypeError
exceptions. \$\endgroup\$