<gh_stars>10-100
from collections import defaultdict
# import re
# from sklearn import __version__
# import warnings


class Config:
    """
    Base configuration object e.g. for a GLM loss, penalty, penalty flavor, or constraint. This is very simlar to sklearn's BaseEstimator class e.g. most of the code is simply copied.
    """
    def _get_param_names(self):
        """
        Gets the names of all the parameters. Any attribute that does not end in '_' is considered a parameter.

        Output
        ------
        names: list of str
            The parameter names.
        """
        return [k for k in self.__dict__.keys() if k[-1] != '_']

    # TODO: do we need the class method version that does not allow arg/keyword arg parameters
    # @classmethod
    # def _get_param_names(cls):
    #     """Get parameter names for the estimator"""
    #     # fetch the constructor or the original constructor before
    #     # deprecation wrapping if any
    #     init = getattr(cls.__init__, 'deprecated_original', cls.__init__)
    #     if init is object.__init__:
    #         # No explicit constructor to introspect
    #         return []

    #     # introspect the constructor arguments to find the model parameters
    #     # to represent
    #     init_signature = inspect.signature(init)
    #     # Consider the constructor parameters excluding 'self'
    #     parameters = [p for p in init_signature.parameters.values()
    #                   if p.name != 'self' and p.kind != p.VAR_KEYWORD]
    #     for p in parameters:
    #         if p.kind == p.VAR_POSITIONAL:
    #             raise RuntimeError("scikit-learn estimators should always "
    #                                "specify their parameters in the signature"
    #                                " of their __init__ (no varargs)."
    #                                " %s with constructor %s doesn't "
    #                                " follow this convention."
    #                                % (cls, init_signature))
    #     # Extract and sort argument names excluding 'self'
    #     return sorted([p.name for p in parameters])

    def get_params(self, deep=True):
        """
        Get parameters for this estimator.

        Parameters
        ----------
        deep : bool, default=True
            If True, will return the parameters for this estimator and
            contained subobjects that are estimators.

        Returns
        -------
        params : dict
            Parameter names mapped to their values.
        """
        out = dict()
        for key in self._get_param_names():
            value = getattr(self, key)
            if deep and hasattr(value, 'get_params'):
                deep_items = value.get_params().items()
                out.update((key + '__' + k, val) for k, val in deep_items)
            out[key] = value
        return out

    def set_params(self, **params):
        """
        Set the parameters of this estimator.

        The method works on simple estimators as well as on nested objects
        (such as :class:`~sklearn.pipeline.Pipeline`). The latter have
        parameters of the form ``<component>__<parameter>`` so that it's
        possible to update each component of a nested object.

        Parameters
        ----------
        **params : dict
            Estimator parameters.

        Returns
        -------
        self : estimator instance
            Estimator instance.
        """
        if not params:
            # Simple optimization to gain speed (inspect is slow)
            return self
        valid_params = self.get_params(deep=True)

        nested_params = defaultdict(dict)  # grouped by prefix
        for key, value in params.items():
            key, delim, sub_key = key.partition('__')
            if key not in valid_params:
                raise ValueError('Invalid parameter %s for estimator %s. '
                                 'Check the list of available parameters '
                                 'with `estimator.get_params().keys()`.' %
                                 (key, self))

            if delim:
                nested_params[key][sub_key] = value
            else:
                setattr(self, key, value)
                valid_params[key] = value

        for key, sub_params in nested_params.items():
            valid_params[key].set_params(**sub_params)

        return self

from collections import defaultdict
# import re
# from sklearn import __version__
# import warnings


class Config:
    """
    Base configuration object e.g. for a GLM loss, penalty, penalty flavor, or constraint. This is very simlar to sklearn's BaseEstimator class e.g. most of the code is simply copied.
    """
    def _get_param_names(self):
        """
        Gets the names of all the parameters. Any attribute that does not end in '_' is considered a parameter.

        Output
        ------
        names: list of str
            The parameter names.
        """
        return [k for k in self.__dict__.keys() if k[-1] != '_']

    # TODO: do we need the class method version that does not allow arg/keyword arg parameters
    # @classmethod
    # def _get_param_names(cls):
    #     """Get parameter names for the estimator"""
    #     # fetch the constructor or the original constructor before
    #     # deprecation wrapping if any
    #     init = getattr(cls.__init__, 'deprecated_original', cls.__init__)
    #     if init is object.__init__:
    #         # No explicit constructor to introspect
    #         return []

    #     # introspect the constructor arguments to find the model parameters
    #     # to represent
    #     init_signature = inspect.signature(init)
    #     # Consider the constructor parameters excluding 'self'
    #     parameters = [p for p in init_signature.parameters.values()
    #                   if p.name != 'self' and p.kind != p.VAR_KEYWORD]
    #     for p in parameters:
    #         if p.kind == p.VAR_POSITIONAL:
    #             raise RuntimeError("scikit-learn estimators should always "
    #                                "specify their parameters in the signature"
    #                                " of their __init__ (no varargs)."
    #                                " %s with constructor %s doesn't "
    #                                " follow this convention."
    #                                % (cls, init_signature))
    #     # Extract and sort argument names excluding 'self'
    #     return sorted([p.name for p in parameters])

    def get_params(self, deep=True):
        """
        Get parameters for this estimator.

        Parameters
        ----------
        deep : bool, default=True
            If True, will return the parameters for this estimator and
            contained subobjects that are estimators.

        Returns
        -------
        params : dict
            Parameter names mapped to their values.
        """
        out = dict()
        for key in self._get_param_names():
            value = getattr(self, key)
            if deep and hasattr(value, 'get_params'):
                deep_items = value.get_params().items()
                out.update((key + '__' + k, val) for k, val in deep_items)
            out[key] = value
        return out

    def set_params(self, **params):
        """
        Set the parameters of this estimator.

        The method works on simple estimators as well as on nested objects
        (such as :class:`~sklearn.pipeline.Pipeline`). The latter have
        parameters of the form ``<component>__<parameter>`` so that it's
        possible to update each component of a nested object.

        Parameters
        ----------
        **params : dict
            Estimator parameters.

        Returns
        -------
        self : estimator instance
            Estimator instance.
        """
        if not params:
            # Simple optimization to gain speed (inspect is slow)
            return self
        valid_params = self.get_params(deep=True)

        nested_params = defaultdict(dict)  # grouped by prefix
        for key, value in params.items():
            key, delim, sub_key = key.partition('__')
            if key not in valid_params:
                raise ValueError('Invalid parameter %s for estimator %s. '
                                 'Check the list of available parameters '
                                 'with `estimator.get_params().keys()`.' %
                                 (key, self))

            if delim:
                nested_params[key][sub_key] = value
            else:
                setattr(self, key, value)
                valid_params[key] = value

        for key, sub_params in nested_params.items():
            valid_params[key].set_params(**sub_params)

        return self
# import re # from sklearn import __version__ # import warnings Base configuration object e.g. for a GLM loss, penalty, penalty flavor, or constraint. This is very simlar to sklearn's BaseEstimator class e.g. most of the code is simply copied. Gets the names of all the parameters. Any attribute that does not end in '_' is considered a parameter.          Output         ------         names: list of str             The parameter names. # TODO: do we need the class method version that does not allow arg/keyword arg parameters # @classmethod # def _get_param_names(cls): #     """Get parameter names for the estimator""" #     # fetch the constructor or the original constructor before #     # deprecation wrapping if any #     init = getattr(cls.__init__, 'deprecated_original', cls.__init__) #     if init is object.__init__: #         # No explicit constructor to introspect #         return [] #     # introspect the constructor arguments to find the model parameters #     # to represent #     init_signature = inspect.signature(init) #     # Consider the constructor parameters excluding 'self' #     parameters = [p for p in init_signature.parameters.values() #                   if p.name != 'self' and p.kind != p.VAR_KEYWORD] #     for p in parameters: #         if p.kind == p.VAR_POSITIONAL: #             raise RuntimeError("scikit-learn estimators should always " #                                "specify their parameters in the signature" #                                " of their __init__ (no varargs)." #                                " %s with constructor %s doesn't " #                                " follow this convention." #                                % (cls, init_signature)) #     # Extract and sort argument names excluding 'self' #     return sorted([p.name for p in parameters]) Get parameters for this estimator.          Parameters         ----------         deep : bool, default=True             If True, will return the parameters for this estimator and             contained subobjects that are estimators.          Returns         -------         params : dict             Parameter names mapped to their values. Set the parameters of this estimator.          The method works on simple estimators as well as on nested objects         (such as :class:`~sklearn.pipeline.Pipeline`). The latter have         parameters of the form ``<component>__<parameter>`` so that it's         possible to update each component of a nested object.          Parameters         ----------         **params : dict             Estimator parameters.          Returns         -------         self : estimator instance             Estimator instance. # Simple optimization to gain speed (inspect is slow) # grouped by prefix