Source code for skcriteria.core.methods

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# License: BSD-3 (https://tldrlegal.com/license/bsd-3-clause-license-(revised))
# Copyright (c) 2016-2021, Cabral, Juan; Luczywo, Nadia
# Copyright (c) 2022, 2023, 2024 QuatroPe
# All rights reserved.

# =============================================================================
# DOCS
# =============================================================================

"""Core functionalities of scikit-criteria."""

# =============================================================================
# IMPORTS
# =============================================================================

import abc
import copy
import inspect


# =============================================================================
# BASE DECISION MAKER CLASS
# =============================================================================


[docs] class SKCMethodABC(metaclass=abc.ABCMeta): """Base class for all class in scikit-criteria. Notes ----- All subclasses should specify: - ``_skcriteria_dm_type``: The type of the decision maker. - ``_skcriteria_parameters``: Availebe parameters. - ``_skcriteria_abstract_class``: If the class is abstract. If the class is *abstract* all validations are turned off. """ _skcriteria_abstract_class = True def __init_subclass__(cls): """Validate if the subclass are well formed.""" is_abstract = vars(cls).get("_skcriteria_abstract_class", False) if is_abstract: return decisor_type = getattr(cls, "_skcriteria_dm_type", None) if decisor_type is None: raise TypeError(f"{cls} must redefine '_skcriteria_dm_type'") cls._skcriteria_dm_type = str(decisor_type) params = getattr(cls, "_skcriteria_parameters", None) if params is None: raise TypeError(f"{cls} must redefine '_skcriteria_parameters'") params = frozenset(params) signature = inspect.signature(cls.__init__) has_kwargs = any( p.kind == inspect.Parameter.VAR_KEYWORD for p in signature.parameters.values() ) params_not_in_signature = params.difference(signature.parameters) if params_not_in_signature and not has_kwargs: raise TypeError( f"{cls} defines the parameters {params_not_in_signature} " "which is not found as a parameter in the __init__ method." ) cls._skcriteria_parameters = params def __repr__(self): """x.__repr__() <==> repr(x).""" method_name = self.get_method_name() parameters = [] if self._skcriteria_parameters: for pname in sorted(self._skcriteria_parameters): pvalue = getattr(self, pname) parameters.append(f"{pname}={repr(pvalue)}") str_parameters = ", ".join(parameters) return f"<{method_name} [{str_parameters}]>"
[docs] def get_method_name(self): """Return the name of the method as string.""" return type(self).__name__
[docs] def get_parameters(self): """Return the parameters of the method as dictionary.""" the_parameters = {} for parameter_name in self._skcriteria_parameters: parameter_value = getattr(self, parameter_name) the_parameters[parameter_name] = copy.deepcopy(parameter_value) return the_parameters
[docs] def copy(self, **kwargs): """Return a custom copy of the current decision-maker. This method is also useful for manually modifying the values of the object. Parameters ---------- kwargs : The same parameters supported by object constructor. The values provided replace the existing ones in the object to be copied. Returns ------- A new object. """ asdict = self.get_parameters() asdict.update(kwargs) cls = type(self) return cls(**asdict)