# Path: pyDEA/core/models/model_base.py
# class ModelBase(object):
#     ''' Abstract base class for some of the DEA models.
# 
#         Attributes:
#             input_data (InputData): object that stores all input data.
#             update_dmu_str_var (func): function that updates
#                 solution progress.
#             lp_model (pulp.LpProblem): pulp LP.
# 
#         Args:
#             input_data (InputData): object that stores all input data.
#             update_str (func, optional): function that updates
#                 solution progress. Defaults to a function that does nothing.
#     '''
#     def __init__(self, input_data, update_str=do_nothing):
#         self.input_data = input_data
#         self.update_dmu_str_var = update_str
#         self.lp_model = None
# 
#     def run(self):
#         ''' Solves a given problem.
#         '''
#         check_input_and_output_categories(self.input_data)
#         model_solution = self._create_solution()
#         self._create_lp()
#         for count, dmu_code in enumerate(self.input_data.DMU_codes):
#             self.run_for_one_DMU(dmu_code, model_solution)
#             # self.lp_model.writeLP("dmu_{0}.txt".format(dmu_code))
#             self.update_dmu_str_var()
#         return model_solution
# 
#     def _create_solution(self):
#         ''' Allocates solution object.
# 
#             Returns:
#                 (Solution): created solution object.
#         '''
#         return Solution(self.input_data)
# 
#     def run_for_one_DMU(self, dmu_code, model_solution):
#         ''' Solves LP for a given DMU and stores solution.
# 
#             Args:
#                 dmu_code (str): DMU code.
#                 model_solution (Solution): solution.
#         '''
#         self._update_lp(dmu_code)
#         self.lp_model.solve()
#         self._fill_solution(dmu_code, model_solution)
# 
#     def _fill_solution(self, dmu_code, model_solution):
#         ''' Fills given solution with data calculated for one DMU.
#             Must be implemented in derived classes.
# 
#             Args:
#                 dmu_code (str): DMU code for which the LP was solved.
#                 model_solution (Solution): object where solution for one DMU
#                     will be written.
#         '''
#         raise NotImplementedError()
# 
#     def _create_lp(self):
#         ''' Creates initial linear program. Must be implemented in derived
#             classes.
#         '''
#         raise NotImplementedError()
# 
#     def _update_lp(self, dmu_code):
#         ''' Updates existing linear program with coefficients corresponding
#             to a given DMU. Must be implemented in derived classes.
# 
#             Args:
#                 dmu_code (str): DMU code.
#         '''
#         raise NotImplementedError()
# 
# Path: pyDEA/core/utils/dea_utils.py
# def is_efficient(efficiency_score, lambda_variable):
#     ''' Checks if dmu with given efficiency score and value of
#         lambda variable is efficient.
# 
#         Args:
#             efficiency_score (double): efficiency spyDEA.core.
#             lambda_variable (double): value of lambda variable corresponding
#                 to DMU under consideration.
# 
#         Returns:
#             bool: True if DMU is efficient, False otherwise.
# 
#         Example:
#             >>> is_efficient(1, 1)
#             True
#             >>> is_efficient(0.5, 0)
#             False
#             >>> is_efficient(0.9999999, 1)
#             True
#             >>> is_efficient(1.0000001, 1)
#             True
# 
#     '''
#     if efficiency_score == 1:
#         return True
#     if lambda_variable > ZERO_TOLERANCE:
#         return True
#     # it seems that lambda_variable is not ultimate indication of efficiency
#     if efficiency_score > 1:
#         return True
#     return False
# 
# ZERO_TOLERANCE = 1e-10


import pulp
from pyDEA.core.models.model_base import ModelBase
from pyDEA.core.utils.dea_utils import is_efficient, ZERO_TOLERANCE
            lambda_variables = dict()
            for dmu_constraint, dmu in self._dmu_constraint_names.items():
                if self.lp_model.constraints[dmu_constraint].pi is None:
                    self.lp_model.constraints[dmu_constraint].pi = 0
                # else:
                #     print(self.lp_model.constraints[dmu_constraint].pi)
                if (abs(self.lp_model.constraints[dmu_constraint].pi) >
                        ZERO_TOLERANCE):
                    lambda_variables[dmu] = self._concrete_model.process_dual_value(
                        self.lp_model.constraints[dmu_constraint].pi)
            lambda_var = lambda_variables.get(dmu_code, 0)
            model_solution.add_efficiency_score(
                dmu_code, self._get_efficiency_score(lambda_var))
            # print('lambda_variables: {0}'.format(lambda_variables))
            model_solution.add_lambda_variables(dmu_code, lambda_variables)

    def _get_efficiency_score(self, lambda_variable):
        ''' Returns efficiency score based on a given lambda variable.

            Args:
                lambda_variable (double): value of the lambda variable.

            Returns:
                double: efficiency spyDEA.core.
        '''
        eff_score = self._concrete_model.process_obj_var(pulp.value(
            self.lp_model.objective))
        # None is possible when objective function is zero
        if eff_score is None:
            eff_score = 0

# Path: pyDEA/core/models/model_base.py
# class ModelBase(object):
#     ''' Abstract base class for some of the DEA models.
# 
#         Attributes:
#             input_data (InputData): object that stores all input data.
#             update_dmu_str_var (func): function that updates
#                 solution progress.
#             lp_model (pulp.LpProblem): pulp LP.
# 
#         Args:
#             input_data (InputData): object that stores all input data.
#             update_str (func, optional): function that updates
#                 solution progress. Defaults to a function that does nothing.
#     '''
#     def __init__(self, input_data, update_str=do_nothing):
#         self.input_data = input_data
#         self.update_dmu_str_var = update_str
#         self.lp_model = None
# 
#     def run(self):
#         ''' Solves a given problem.
#         '''
#         check_input_and_output_categories(self.input_data)
#         model_solution = self._create_solution()
#         self._create_lp()
#         for count, dmu_code in enumerate(self.input_data.DMU_codes):
#             self.run_for_one_DMU(dmu_code, model_solution)
#             # self.lp_model.writeLP("dmu_{0}.txt".format(dmu_code))
#             self.update_dmu_str_var()
#         return model_solution
# 
#     def _create_solution(self):
#         ''' Allocates solution object.
# 
#             Returns:
#                 (Solution): created solution object.
#         '''
#         return Solution(self.input_data)
# 
#     def run_for_one_DMU(self, dmu_code, model_solution):
#         ''' Solves LP for a given DMU and stores solution.
# 
#             Args:
#                 dmu_code (str): DMU code.
#                 model_solution (Solution): solution.
#         '''
#         self._update_lp(dmu_code)
#         self.lp_model.solve()
#         self._fill_solution(dmu_code, model_solution)
# 
#     def _fill_solution(self, dmu_code, model_solution):
#         ''' Fills given solution with data calculated for one DMU.
#             Must be implemented in derived classes.
# 
#             Args:
#                 dmu_code (str): DMU code for which the LP was solved.
#                 model_solution (Solution): object where solution for one DMU
#                     will be written.
#         '''
#         raise NotImplementedError()
# 
#     def _create_lp(self):
#         ''' Creates initial linear program. Must be implemented in derived
#             classes.
#         '''
#         raise NotImplementedError()
# 
#     def _update_lp(self, dmu_code):
#         ''' Updates existing linear program with coefficients corresponding
#             to a given DMU. Must be implemented in derived classes.
# 
#             Args:
#                 dmu_code (str): DMU code.
#         '''
#         raise NotImplementedError()
# 
# Path: pyDEA/core/utils/dea_utils.py
# def is_efficient(efficiency_score, lambda_variable):
#     ''' Checks if dmu with given efficiency score and value of
#         lambda variable is efficient.
# 
#         Args:
#             efficiency_score (double): efficiency spyDEA.core.
#             lambda_variable (double): value of lambda variable corresponding
#                 to DMU under consideration.
# 
#         Returns:
#             bool: True if DMU is efficient, False otherwise.
# 
#         Example:
#             >>> is_efficient(1, 1)
#             True
#             >>> is_efficient(0.5, 0)
#             False
#             >>> is_efficient(0.9999999, 1)
#             True
#             >>> is_efficient(1.0000001, 1)
#             True
# 
#     '''
#     if efficiency_score == 1:
#         return True
#     if lambda_variable > ZERO_TOLERANCE:
#         return True
#     # it seems that lambda_variable is not ultimate indication of efficiency
#     if efficiency_score > 1:
#         return True
#     return False
# 
# ZERO_TOLERANCE = 1e-10


# Path: pyDEA/core/models/multiplier_model_base.py
import pulp
from pyDEA.core.models.model_base import ModelBase
from pyDEA.core.utils.dea_utils import is_efficient, ZERO_TOLERANCE

            lambda_variables = dict()
            for dmu_constraint, dmu in self._dmu_constraint_names.items():
                if self.lp_model.constraints[dmu_constraint].pi is None:
                    self.lp_model.constraints[dmu_constraint].pi = 0
                # else:
                #     print(self.lp_model.constraints[dmu_constraint].pi)
                if (abs(self.lp_model.constraints[dmu_constraint].pi) >
                        ZERO_TOLERANCE):
                    lambda_variables[dmu] = self._concrete_model.process_dual_value(
                        self.lp_model.constraints[dmu_constraint].pi)
            lambda_var = lambda_variables.get(dmu_code, 0)
            model_solution.add_efficiency_score(
                dmu_code, self._get_efficiency_score(lambda_var))
            # print('lambda_variables: {0}'.format(lambda_variables))
            model_solution.add_lambda_variables(dmu_code, lambda_variables)

    def _get_efficiency_score(self, lambda_variable):
        ''' Returns efficiency score based on a given lambda variable.

            Args:
                lambda_variable (double): value of the lambda variable.

            Returns:
                double: efficiency spyDEA.core.
        '''
        eff_score = self._concrete_model.process_obj_var(pulp.value(
            self.lp_model.objective))
        # None is possible when objective function is zero
        if eff_score is None:
            eff_score = 0

        if is_efficient(eff_score, lambda_variable):