Home > Software design >  Python refactoring if-elif-else statements in method
Python refactoring if-elif-else statements in method

Time:11-11

I want to try refactoring this method in my code:

def get_params_in_string(params):
    obj_name = params.PrefetchMethod.split('.')[0]

    right_method_name = 'BuhReports.'

    if obj_name in ('AccountAnalysisW', 'АнализСчетаW'):
        obj = AccountAnalysis(None, params, None, None)
        method_name = right_method_name   'GetAccountAnalysis'
    elif obj_name in ('TurnoverSheetW', 'ОборотнаяВедомостьW'):
        obj = TurnoverSheet(None, params, None, None)
        method_name = right_method_name   'GetTurnoverSheet'
    elif obj_name in ('CardAccountW', 'КарточкаСчетаW'):
        obj = CardAccount(None, params, None, None)
        method_name = right_method_name   'GetCardAccount'
    elif obj_name in ('MutualSettlementsW', 'ВзаиморасчетыW'):
        obj = MutualSettlements(None, params, None, None)
        method_name = right_method_name   'GetMutualSettlements'
    elif obj_name in ('JournalVoucherW', 'ЖурналОрдерW'):
        obj = JournalVoucher(None, params, None, None)
        method_name = right_method_name   'GetJournalVoucher'
    elif obj_name in ('WarehouseCompareW', 'СверкаСкладаW'):
        obj = WarehouseCompare(None, params, None, None)
        method_name = right_method_name   'GetWarehouseCompare'
    elif obj_name in ('DebtsW', 'ДолгиW'):
        obj = Debts(None, params, None, None)
        method_name = 'MutualSettlements.DebitorsAndCreditors'
    else:
        raise Exception('Unexpected call')

    obj.prepare_filters()
    params.Put('PrefetchMethod', method_name, sbis.FieldType.ftSTRING)
    return JournalVoucher.GetParamsInString(params)

Here is a problem. I don't like a lot of repeative code. It seems to me that some pattern can be used here, but I do not know which one. Is there any solution for this case?

CodePudding user response:

You can use a dictionary to store the comparable values, then use .get to get that value or if it doesn't exist return the given argument value (given None but that is also the default):

dct = {
    ('AccountAnalysisW', 'АнализСчетаW'): {'name': 'GetAccountAnalysis', 'obj': AccountAnalysis},
    ('TurnoverSheetW', 'ОборотнаяВедомостьW'): {'name': 'GetTurnoverSheet', 'obj': TurnoverSheet},
    ('CardAccountW', 'КарточкаСчетаW'): {'name': 'GetCardAccount', 'obj': CardAccount}
}
# create the dictionary with individual keys (basically unpack tuples
# and give the values in tuples their own value in the dict)
dct = {k: v for k, v in dct.items() for k in k}


def get_params_in_string(params):
    obj_name = params.PrefetchMethod.split('.')[0]
    right_method_name = 'BuhReports.'
    items = dct.get(obj_name, None)
    # if the key doesn't exist in the dictionary
    # then raise an exception
    if items is None:
        raise Exception('Unexpected call')
    obj = items.get('obj')(None, params, None, None)
    method_name = right_method_name   items.get('name')

    obj.prepare_filters()
    params.Put('PrefetchMethod', method_name, sbis.FieldType.ftSTRING)
    return JournalVoucher.GetParamsInString(params)

CodePudding user response:

Here is a minimal example of how can your code be refactored with dictionaries:

def foo_1(params):
    return params[0]*2

def foo_2(params):
    return params[0]*3

def run_ops(entry, params):
    # Mapping between equivalent entries
    entry_map = {'AccountAnalysisW':'АнализСчетаW', 'WarehouseCompareW':'СверкаСкладаW'}
    # Dictionary with operations for each entry
    entry_ops = {'АнализСчетаW': [foo_1, 'Foo1'], 'СверкаСкладаW': [foo_2, 'Foo2']}

    if entry in entry_map:
        entry = entry_map[entry]

    if entry in entry_ops:
        ops = entry_ops[entry]
        res = ops[0](params)
        print('Calling '   ops[1]   ' with a result '   str(res))

run_ops('WarehouseCompareW', [1,2,3])
run_ops('АнализСчетаW', [4,5])

This assumes that you can have two equivalent entries that need to be checked for. Then for any entry the dictionary stores the function call and a string in a list, which the main function will call.

  • Related