[docs]def calc_deltas(settings, dict_for_deltas):
"""
This function calculates deltas for action alternatives relative to the no action alternative set via the General Inputs.
Parameters:
settings: The SetInputs class. \n
dict_for_deltas: Dictionary; contains values for calculating deltas.
Returns:
An updated dictionary containing deltas relative to the no_action_alt. OptionIDs (numeric) for the deltas will be the alt_id followed by the no_action_alt. \n
For example, deltas for optionID=1 relative to optionID=0 will have optionID=10. OptionNames will also show as 'OptionID=1_name minus OptionID=0_name'.
"""
print('\nCalculating deltas...')
update_dict = dict()
for key, value in dict_for_deltas.items():
vehicle, model_year, age_id, calendar_year, series = 0, 0, 0, 0, ''
try:
# for totals and averages deltas
vehicle, alt, model_year, age_id, discount_rate = key
st, rc, ft = vehicle
except:
# for pv_annualized deltas
alt, calendar_year, discount_rate, series = key
args_to_delta = [k for k, v in value.items() if 'ID' not in k and 'DiscountRate' not in k and 'Series' not in k and 'Periods' not in k]
if alt != settings.no_action_alt:
delta_alt = f'{alt}{settings.no_action_alt}'
delta_alt = int(delta_alt)
if vehicle:
update_dict_key = (vehicle, delta_alt, model_year, age_id, discount_rate)
update_dict.update({update_dict_key: {'DiscountRate': discount_rate,
'yearID': model_year + age_id,
'sourceTypeID': st,
'regClassID': rc,
'fuelTypeID': ft,
'modelYearID': model_year,
'ageID': age_id,
'optionID': delta_alt,
}
}
)
else:
update_dict_key = (delta_alt, calendar_year, discount_rate, series)
update_dict.update({update_dict_key: {'optionID': delta_alt,
'yearID': calendar_year,
'DiscountRate': discount_rate,
'Series': series,
'Periods': 1,
}
}
)
for arg in args_to_delta:
try:
no_action_arg_value = dict_for_deltas[(vehicle, settings.no_action_alt, model_year, age_id, discount_rate)][arg]
except:
no_action_arg_value = dict_for_deltas[(settings.no_action_alt, calendar_year, discount_rate, series)][arg]
delta_periods = dict_for_deltas[(settings.no_action_alt, calendar_year, discount_rate, series)]['Periods']
update_dict[update_dict_key]['Periods'] = delta_periods
action_arg_value = dict_for_deltas[key][arg]
delta_arg_value = action_arg_value - no_action_arg_value
update_dict[update_dict_key][arg] = delta_arg_value
dict_for_deltas.update(update_dict)
return dict_for_deltas
[docs]def calc_deltas_weighted(settings, dict_for_deltas):
"""
This function calculates deltas for action alternatives relative to the passed no action alternative specifically for the weighted cost per mile dictionaries.
Parameters:
settings: The SetInputs class. \n
dict_for_deltas: Dictionary; contains values for calculating deltas.
Returns:
An updated dictionary containing deltas relative to the no_action_alt. OptionIDs (numeric) for the deltas will be the alt_id followed by the no_action_alt. \n
For example, deltas for optionID=1 relative to optionID=0 would have optionID=10.
Note:
There is no age_id or discount rate in the key for the passed weighted dictionaries.
"""
print('\nCalculating weighted deltas...')
update_dict = dict()
for key in dict_for_deltas.keys():
vehicle, alt, model_year = key[0], key[1], key[2]
id_args = [k for k, v in dict_for_deltas[key].items() if 'ID' in k or 'Name' in k]
args_to_delta = [k for k, v in dict_for_deltas[key].items() if k not in id_args]
if alt != settings.no_action_alt:
delta_alt = f'{alt}{settings.no_action_alt}'
delta_alt = int(delta_alt)
delta_dict = dict()
for arg in args_to_delta:
arg_value = dict_for_deltas[key][arg] - dict_for_deltas[(vehicle, settings.no_action_alt, model_year)][arg]
delta_dict.update({arg: arg_value})
for arg in id_args:
arg_value = dict_for_deltas[key][arg]
delta_dict.update({arg: arg_value})
delta_dict.update({'optionID': delta_alt})
update_dict[(vehicle, delta_alt, model_year)] = delta_dict
dict_for_deltas.update(update_dict)
return dict_for_deltas
if __name__ == '__main__':
import pandas as pd
from bca_tool_code.tool_setup import SetInputs
from bca_tool_code.calc_deltas import calc_deltas
settings = SetInputs()
data = {((1, 1, 1), 0, 2027, 0, 0): {'sourceTypeID': 1, 'regClassID': 1, 'fuelTypeID': 1,
'optionID': 0, 'modelYearID': 2027, 'ageID': 0, 'DiscountRate': 0,
'A': 100, 'B': 200},
((1, 1, 1), 0, 2027, 1, 0): {'sourceTypeID': 1, 'regClassID': 1, 'fuelTypeID': 1,
'optionID': 0, 'modelYearID': 2027, 'ageID': 1, 'DiscountRate': 0,
'A': 150, 'B': 250},
((1, 1, 1), 1, 2027, 0, 0): {'sourceTypeID': 1, 'regClassID': 1, 'fuelTypeID': 1,
'optionID': 1, 'modelYearID': 2027, 'ageID': 0, 'DiscountRate': 0,
'A': 50, 'B': 150},
((1, 1, 1), 1, 2027, 1, 0): {'sourceTypeID': 1, 'regClassID': 1, 'fuelTypeID': 1,
'optionID': 1, 'modelYearID': 2027, 'ageID': 1, 'DiscountRate': 0,
'A': 100, 'B': 200}}
data = calc_deltas(settings, data)
data_df = pd.DataFrame(data).transpose()
print(data_df) # delta values (optionID=10) should all be -50