Correctly applying architecture patterns to what you’re building, based on the problem being solved isn’t talked about much. Having mostly written scripts in the past, building a module requires a lot more thought upfront.
For example, when writing a method, what sorts of inputs do you want to allow for, vs. already having some of those inputs as part of the method.
SOLUTION A
def clean_report(report, list_of_column_to_drop, dict_of_column_to_rename):
report = report.drop(list_of_columns_to_drop, axis=1)
for x in report.columns:
report.rename(columns={x:new_x}, inplace=True)
return report
VS.
SOLUTION B
def clean_report(report_type='ONE'):
if report_type == 'ONE':
list_of_columns_to_drop = ['A', 'C', 'D']
dict_of_columns_to_rename = {'b':'B', 'exi':'X'}
elif report_type == 'TWO':
list_of_columns_to_drop = ['M', 'J', 'R']
dict_of_columns_to_rename = {'some': 'L', 'plus': 'P'}
else:
print ("report type handler is not defined")
report = report.drop(list_of_columns_to_drop, axis=1)
for x in report.columns:
report.rename(columns={x:new_x}, inplace=True)
Solution A leaves it to the user to input stuff, while Solution B handles it based on the inputs it generally expects.
In a script, I could get by with either, since it’s not a one-off thing that I can easily change if needed.
But in a package, I need to think more about the tradeoffs. I need to consider:
These types of considerations at every turn are slowing down my programming practice currently. But (I think), they’re also making me a better programmer.