""" """ # --------------------------------------- # # imports # # --------------------------------------- # from pandas import DataFrame, concat from BBUtils.logging_handle import logger # --------------------------------------- # # definitions # # --------------------------------------- # MODULE_LOGGER_HEAD = "request_load_estimator -> " START_NR_OF_EMPLOYEES = 50 START_NR_OF_APPLICATIONS = 5 START_NR_OF_SERVICE_REQUESTS = 0 START_NR_OF_SERVICE_DESK_EMPLOYEES = 3 START_DOCUMENTATION_LEVEL = 1 START_KNOWLEDGE_LEVEL = 1 START_SYSTEMS_COMPLEXITY = 1 KNOWLEDGE_REDUCTION_FACTOR = 0.2 DOCUMENTATION_LEVEL_MAX = 4 DOCUMENTATION_LEVEL_MIN = 0.5 KNOWLEDGE_LEVEL_MAX = 4 KNOWLEDGE_LEVEL_MIN = 0.5 # --------------------------------------- # # global vars # # --------------------------------------- # # --------------------------------------- # # functions # # --------------------------------------- # def limit_value(value: float, min_value: float, max_value: float) -> float: if value < min_value: return min_value elif value > max_value: return max_value else: return value # --------------------------------------- # # classes # # --------------------------------------- # class RequestLoadEstimator: AVERAGE_REQUEST_WORKING_TIME = 0.5 AVERAGE_DAY_WORKING_TIME = 6 AVERAGE_PROBLEM_LEVEL_IN_PERCENT = 0.1 def __init__(self): self._days_cycle = 4 self.service_desk_employees = 0 self.documentation_level = 0 self.service_desk_knowledge_level = 0 self.systems_complexity = 0 self.nr_of_applications = 0 self.nr_of_employees = 0 self.new_application_problems = 0 self.nr_of_open_service_requests = 0 self.processed_service_requests = 0 self._desired_request_working_time = 0 self.personal_available_time = 0 self.actual_week = 0 self.data_set = DataFrame() self.initialize_data() self.prev_dict = {"day": 0, "days_cycle": 0, "service_desk_employees": 0, "documentation_level": 0, "service_desk_knowledge_level": 0, "systems_complexity": 0, "nr_of_applications": 0, "new_application_problems": 0, "nr_of_open_service_requests": 0, "request_working_time": 0, "personal_available_time": 0, "processed_service_requests": 0, "nr_of_employees": 0} pass def set_weeks_cycle(self, days: int): self._days_cycle = days def add_new_applications(self, nr: int): if nr > 0: logger.info(MODULE_LOGGER_HEAD + "Adding new applications: " + str(nr)) documentation_level_reduction = (nr / self.nr_of_applications) * 0.2 self.documentation_level -= documentation_level_reduction if self.documentation_level < DOCUMENTATION_LEVEL_MIN: self.documentation_level = DOCUMENTATION_LEVEL_MIN complexity_increase = (nr / self.nr_of_applications) * 0.2 self.systems_complexity += complexity_increase self.nr_of_applications += nr elif nr < 0: logger.info(MODULE_LOGGER_HEAD + "Removing applications: " + str(nr)) complexity_reduction = (nr / self.nr_of_applications) * 0.2 self.systems_complexity -= complexity_reduction self.nr_of_applications += nr def add_new_employees(self, nr: int): if nr > 0: logger.info(MODULE_LOGGER_HEAD + "Adding new employees: " + str(nr)) self.systems_complexity += nr / self.nr_of_employees self.nr_of_employees += nr elif nr < 0: logger.info(MODULE_LOGGER_HEAD + "Removing employees: " + str(nr)) self.systems_complexity -= nr / self.nr_of_employees self.nr_of_employees += nr def add_service_desk_employees(self, nr: int): if nr > 0: logger.info(MODULE_LOGGER_HEAD + "Adding new service desk employees: " + str(nr)) knowledge_level_reduction = (nr / self.service_desk_employees) * 0.2 self.service_desk_knowledge_level = limit_value(self.service_desk_knowledge_level - knowledge_level_reduction, KNOWLEDGE_LEVEL_MIN, KNOWLEDGE_LEVEL_MAX) self.service_desk_employees += nr elif nr < 0: logger.info(MODULE_LOGGER_HEAD + "Removing service desk employees: " + str(nr)) self.service_desk_employees += nr def process_weeks(self): logger.info(MODULE_LOGGER_HEAD + "Processing weeks") for day in range(self._days_cycle): self._calc_nr_of_service_requests() self._calc_request_working_time() self._calc_personal_available_time() self._calc_documentation_and_knowledge_level() self._calc_application_problems() self.actual_week += 1 self._process_data_set() pass def initialize_data(self): logger.info(MODULE_LOGGER_HEAD + "Initializing data") self._days_cycle = 7 self.service_desk_employees = START_NR_OF_SERVICE_DESK_EMPLOYEES self.documentation_level = START_DOCUMENTATION_LEVEL self.service_desk_knowledge_level = START_KNOWLEDGE_LEVEL self.systems_complexity = START_SYSTEMS_COMPLEXITY self.nr_of_applications = START_NR_OF_APPLICATIONS self.nr_of_employees = START_NR_OF_EMPLOYEES self.new_application_problems = 0 self.processed_service_requests = 0 self.nr_of_open_service_requests = START_NR_OF_SERVICE_REQUESTS self._desired_request_working_time = 0 self.personal_available_time = 0 self.actual_week = 0 self.data_set = DataFrame() def _calc_application_problems(self): self.new_application_problems = ((self.nr_of_employees * self.nr_of_applications * self.systems_complexity / self.documentation_level) * self.AVERAGE_PROBLEM_LEVEL_IN_PERCENT) if self.new_application_problems < 0: self.new_application_problems = 0 pass def _calc_nr_of_service_requests(self): self.nr_of_open_service_requests += int(self.new_application_problems) def _calc_request_working_time(self): self._desired_request_working_time = (self.nr_of_open_service_requests * (self.AVERAGE_REQUEST_WORKING_TIME / self.service_desk_knowledge_level)) if self._desired_request_working_time < 0: self._desired_request_working_time = 0 if self._desired_request_working_time < (self.service_desk_employees * self.AVERAGE_DAY_WORKING_TIME): self.processed_service_requests = self.nr_of_open_service_requests self.nr_of_open_service_requests = 0 else: self.processed_service_requests = int((self.service_desk_employees * self.AVERAGE_DAY_WORKING_TIME) / ( self.AVERAGE_REQUEST_WORKING_TIME / self.service_desk_knowledge_level)) self.nr_of_open_service_requests -= self.processed_service_requests if self.nr_of_open_service_requests < 0: self.nr_of_open_service_requests = 0 pass def _calc_personal_available_time(self): self.personal_available_time = (self.service_desk_employees * self.AVERAGE_DAY_WORKING_TIME) - \ self._desired_request_working_time pass def _calc_documentation_and_knowledge_level(self): documentation_level_reduction = (self.personal_available_time * KNOWLEDGE_REDUCTION_FACTOR / (self.nr_of_employees * self.nr_of_applications)) self.documentation_level += documentation_level_reduction if documentation_level_reduction >= 0 else documentation_level_reduction / 10 know_how_reduction = self.personal_available_time * KNOWLEDGE_REDUCTION_FACTOR / ( self.nr_of_employees * self.service_desk_employees) self.service_desk_knowledge_level += know_how_reduction if know_how_reduction >= 0 else know_how_reduction / 10 self.documentation_level = limit_value(self.documentation_level, DOCUMENTATION_LEVEL_MIN, DOCUMENTATION_LEVEL_MAX) self.service_desk_knowledge_level = limit_value(self.service_desk_knowledge_level, KNOWLEDGE_LEVEL_MIN, KNOWLEDGE_LEVEL_MAX) def _process_data_set(self): row = { "day": self.actual_week, "days_cycle": self._days_cycle, "service_desk_employees": self.service_desk_employees, "documentation_level": self.documentation_level, "service_desk_knowledge_level": self.service_desk_knowledge_level, "systems_complexity": self.systems_complexity, "nr_of_applications": self.nr_of_applications, "new_application_problems": self.new_application_problems, "nr_of_open_service_requests": self.nr_of_open_service_requests, "request_working_time": self._desired_request_working_time, "personal_available_time": self.personal_available_time, "nr_of_processed_service_requests": self.processed_service_requests, "nr_of_employees": self.nr_of_employees, } new_df = DataFrame([row]) if self.data_set.empty: self.data_set = new_df else: self.data_set = concat([self.data_set, new_df], ignore_index=False) pass # --------------------------------------- # # main # # --------------------------------------- #