pythonpandasdataframeglobal-variableslocal-variables

Make global variables become local variables


I'm creating a program to calculate the price of a telecommunications package based on call history. Here is main function.

from math import ceil

prev_date = None
expen_minutes_used = 0

def calculate_call_cost(row):
    
    global prev_date, expen_minutes_used 

    if prev_date is None or row['data of call'].date() != prev_date:
        prev_date = row['data of call'].date() 
        expen_minutes_used = 0

    expen_minutes = 0
    if expen_minutes_used < 5:
        expen_minutes = min(5 - expen_minutes_used, ceil(row['Duration in second'] / 60))
                        
        expen_minutes_used += expen_minutes 

    cheap_minutes = ceil(row['Duration in second'] / 60) - expen_minutes
                    
    
    cost = cheap_minutes * 0.40 + expen_minutes * 3.95
    return cost

calls_data_sorted['Cost of tariff'] = calls_data_sorted.apply(calculate_call_cost, axis = 1) 
total_cost2 = calls_data_sorted['Cost of tariff'].sum()
calls_data_sorted

Please tell me is there any way to change those global varibales into local varibles.


Solution

  • Put the state that needs to persist between calls in a dictionary. Pass this as an argument to calculate_call_cost(), and the function can update the dictionary.

    from math import ceil
    
    state_dict = {'prev_date': None, 'expen_minutes_used': 0}
    
    def calculate_call_cost(row, state: dict):
        if state['prev_date'] is None or row['data of call'].date() != state['prev_date']:
            state['prev_date'] = row['data of call'].date() 
            state['expen_minutes_used'] = 0
    
        expen_minutes = 0
        if state['expen_minutes_used'] < 5:
            expen_minutes = min(5 - state['expen_minutes_used'], ceil(row['Duration in second'] / 60))
                            
            state['expen_minutes_used'] += expen_minutes 
    
        cheap_minutes = ceil(row['Duration in second'] / 60) - expen_minutes
                        
        
        cost = cheap_minutes * 0.40 + expen_minutes * 3.95
        return cost
    
    calls_data_sorted['Cost of tariff'] = calls_data_sorted.apply(lambda row: calculate_call_cost(row, state_dict), axis = 1) 
    total_cost2 = calls_data_sorted['Cost of tariff'].sum()
    

    You could also make a class with calculate_call_cost() as a method. The variables that need to persist can be attributes of the class.