# -*- coding: utf-8 -*-

"""Utilities for hyper-parameter optimization."""

import random
from abc import ABC, abstractmethod
from typing import Any, Iterable, List, Mapping, Tuple

from torch.nn import Module

__all__ = ["HPOptimizerResult", "HPOptimizer"]

HPOptimizerResult = Tuple[Module, List[float], Any, Any, Any, Any]


class HPOptimizer(ABC):
    """An abstract class from which all hyper-parameter optimizers should inherit."""

    @abstractmethod
    def optimize_hyperparams(self, *args, **kwargs) -> HPOptimizerResult:
        """Run the optimizer."""

    @staticmethod
    def _sample_parameter_value(
        parameter_values: Mapping[int, Iterable[Any]]
    ) -> Mapping[int, Any]:
        """Randomly subsample a dictionary whose values are iterable."""
        return {
            parameter: (random.choice(values) if isinstance(values, list) else values)
            for parameter, values in parameter_values.items()
        }

# -*- coding: utf-8 -*-

"""Utilities for hyper-parameter optimization."""

import random
from abc import ABC, abstractmethod
from typing import Any, Iterable, List, Mapping, Tuple

from torch.nn import Module

__all__ = ["HPOptimizerResult", "HPOptimizer"]

HPOptimizerResult = Tuple[Module, List[float], Any, Any, Any, Any]


class HPOptimizer(ABC):
    """An abstract class from which all hyper-parameter optimizers should inherit."""

    @abstractmethod
    def optimize_hyperparams(self, *args, **kwargs) -> HPOptimizerResult:
        """Run the optimizer."""

    @staticmethod
    def _sample_parameter_value(
        parameter_values: Mapping[int, Iterable[Any]]
    ) -> Mapping[int, Any]:
        """Randomly subsample a dictionary whose values are iterable."""
        return {
            parameter: (random.choice(values) if isinstance(values, list) else values)
            for parameter, values in parameter_values.items()
        }

# -*- coding: utf-8 -*- Utilities for hyper-parameter optimization. An abstract class from which all hyper-parameter optimizers should inherit. Run the optimizer. Randomly subsample a dictionary whose values are iterable.