how to combine multiple methods in python?

Viewed 52

I have three similarmethods. And I think this can be reduced to one method.

So I have this almost identical methods:

def calulate_totalAnanas_NorthMidSouth():
        
    sheet_factuur = excelWorkbook['Facturen ']
    totalAnanasNorth = sheet_factuur.cell(row=6, column=5).value
    totalAnanasMid = sheet_factuur.cell(row=7, column=5).value
    totalAnanasSouth = sheet_factuur.cell(row=8, column=5).value    
    totalAnanasNoMidSou = totalAnanasNorth + totalAnanasMid + totalAnanasSouth   
    
       
    print(totalAnanasNoMidSou)
    
def calulate_totalApples_NorthMidSouth():
        
    sheet_factuur = excelWorkbook['Facturen ']
    totalAppleNorth = sheet_factuur.cell(row=9, column=5).value
    totalApplesMid = sheet_factuur.cell(row=10, column=5).value
    totalAppleSouth = sheet_factuur.cell(row=11, column=5).value    
    totalAppleNoMidSou = totalAppleNorth + totalApplesMid + totalAppleSouth   
    
      
    print(totalAppleNoMidSou)
    
def calulate_totalWaspeen_NorthMidSouth():
        
    sheet_factuur = excelWorkbook['Facturen ']
    totalWaspeenNorth = sheet_factuur.cell(row=12, column=5).value
    totalWaspeenMid = sheet_factuur.cell(row=13, column=5).value
    totalWaspeenSouth = sheet_factuur.cell(row=14, column=5).value    
    totalWaspeenNoMidSou = totalWaspeenNorth + totalWaspeenMid + totalWaspeenSouth   
    
      
    print(totalWaspeenNoMidSou)

So my question is:how to refactor this?

5 Answers

try this code. Note that i have not tested it but idea is clear:

def calulate_total_fruit_NorthMidSouth(fruit_name: str) -> int:

    sheet_factuur = excelWorkbook['Facturen ']

    fruit_name_rows = {
        'ananas': [6, 7, 8],
        'apple': [9, 10, 11],
        'waspeen': [12, 13, 14],
    }

    total_fruit_counts = [sheet_factuur.cell(
        row=row_num, column=5).value for row_num in fruit_name_rows.get(fruit_name)]

    return sum(total_fruit_counts)


print(calulate_total_fruit_NorthMidSouth('ananas'))
print(calulate_total_fruit_NorthMidSouth('apple'))
print(calulate_total_fruit_NorthMidSouth('waspeen'))

Note!: you should pass rows as parameters to eliminate hardcoding.

So, it looks like you just need three variables for the rows. Also there is nothing special about these rows, so they might as well be a collection:

def calulate_total_NorthMidSouth(rows):
        
    sheet_factuur = excelWorkbook['Facturen ']
    total = 0
    for row in rows:
        total += sheet_factuur.cell(row=row, column=5).value
    return total

def calulate_totalAnanas_NorthMidSouth():
    totalAnanasNoMidSou = calulate_total_NorthMidSouth((6,7,8))       
       
    print(totalAnanasNoMidSou)

First I'd parametrise the row numbers so they actually make some sense. Also you can use list comprehension and other fun methods.

def calulate_total_NorthMidSouth(rows):
    return sum([excelWorkbook['Facturen '].cell(row=row, column=5).value for row in rows]) 
     
Ananas = [6,7,8]
Apple = [9,10,11]
Waspeen = [12,13,14]
products = [Ananas, Apple, Waspeen]

for product in products: print(calulate_total_NorthMidSouth(product))

Best to use a control dictionary then iterate over its keys/values. Something like this:

control = {'Ananas': [6, 7, 8], 'Apples': [9, 10, 11], 'Waspeen': [12, 13, 14]}

sheet = excelWorkbook['Facturen '] # only do this once

def calculate(sheet, rows):
    return sum(sheet.cell(row=row, column=5).value for row in rows)

for k, rows in control.items():
    print(k, calculate(sheet, rows))

I don't know how is your excel data. But I think these two ways work for you. If you want to do all the job at once:

def calulate_total_NorthMidSouth():
        
    sheet_factuur = excelWorkbook['Facturen ']

    totalAnanasNorth = sheet_factuur.cell(row=6, column=5).value
    totalAnanasMid = sheet_factuur.cell(row=7, column=5).value
    totalAnanasSouth = sheet_factuur.cell(row=8, column=5).value    
    totalAnanasNoMidSou = totalAnanasNorth + totalAnanasMid + totalAnanasSouth   
     
    totalAppleNorth = sheet_factuur.cell(row=9, column=5).value
    totalApplesMid = sheet_factuur.cell(row=10, column=5).value
    totalAppleSouth = sheet_factuur.cell(row=11, column=5).value    
    totalAppleNoMidSou = totalAppleNorth + totalApplesMid + totalAppleSouth   

    totalWaspeenNorth = sheet_factuur.cell(row=12, column=5).value
    totalWaspeenMid = sheet_factuur.cell(row=13, column=5).value
    totalWaspeenSouth = sheet_factuur.cell(row=14, column=5).value    
    totalWaspeenNoMidSou = totalWaspeenNorth + totalWaspeenMid + totalWaspeenSouth  

    total = {'totalAnanasNoMidSou': totalAnanasNoMidSou , 'totalAppleNoMidSou': totalAppleNoMidSou, 'totalWaspeenNoMidSou': totalWaspeenNoMidSou }

If you want to do it in parts:

def calulate_total_NorthMidSouth(rows):
        
    sheet_factuur = excelWorkbook['Facturen ']

    totalNorth = sheet_factuur.cell(row=rows[0], column=5).value
    totalMid = sheet_factuur.cell(row=rows[1], column=5).value
    totalSouth = sheet_factuur.cell(row=rows[2], column=5).value    
    totalNoMidSou = totalNorth + totalMid + totalSouth 

By the way, I think you can construct your excel in a better way and read the excel with pandas (faster, easier). For example, put mid, south, and north in rows and fruits in columns. In that case, you can calculate your goal super faster and more pythonic.

Related