# Path: lcs/strategies/action_selection/BestAction.py
# class BestAction:
# 
#     def __init__(self, all_actions: int):
#         self.all_actions = all_actions
# 
#     def __call__(self, population):
#         cl = population.get_best_classifier()
# 
#         if cl is not None:
#             return cl.action
#         else:
#             return np.random.randint(self.all_actions)
# 
# Path: lcs/strategies/action_selection/RandomAction.py
# class RandomAction:
# 
#     def __init__(self, all_actions: int):
#         self.all_actions = all_actions
# 
#     def __call__(self, population):
#         return np.random.randint(self.all_actions)


from itertools import groupby
from . import RandomAction, BestAction
import numpy as np
import lcs.agents.acs as acs
import lcs.agents.acs2 as acs2
                    raise TypeError()
            else:
                # Normal exploration
                return RandomAction(all_actions=self.all_actions)(population)
        else:
            return BestAction(all_actions=self.all_actions)(population)

    def _handle_latest_action_for_acs2(self, population) -> int:
        last_executed_cls = None
        number_of_cls_per_action = {i: 0 for i in range(self.all_actions)}

        if len(population) > 0:
            last_executed_cls = min(population, key=lambda cl: cl.talp)

            # Count how many classifiers are there for each action
            population.sort(key=lambda cl: cl.action)
            for _action, _clss in groupby(population, lambda cl: cl.action):
                number_of_cls_per_action[_action] = \
                    sum([cl.num for cl in _clss])

        # If there are some actions with no classifiers - select them
        for action, nCls in number_of_cls_per_action.items():
            if nCls == 0:
                return action

        # Otherwise return the action of the last executed classifier
        if last_executed_cls:
            return last_executed_cls.action

        # if there is no classifiers at all - select random action

# Path: lcs/strategies/action_selection/BestAction.py
# class BestAction:
# 
#     def __init__(self, all_actions: int):
#         self.all_actions = all_actions
# 
#     def __call__(self, population):
#         cl = population.get_best_classifier()
# 
#         if cl is not None:
#             return cl.action
#         else:
#             return np.random.randint(self.all_actions)
# 
# Path: lcs/strategies/action_selection/RandomAction.py
# class RandomAction:
# 
#     def __init__(self, all_actions: int):
#         self.all_actions = all_actions
# 
#     def __call__(self, population):
#         return np.random.randint(self.all_actions)


# Path: lcs/strategies/action_selection/ActionDelay.py
from itertools import groupby
from . import RandomAction, BestAction
import numpy as np
import lcs.agents.acs as acs
import lcs.agents.acs2 as acs2

                    raise TypeError()
            else:
                # Normal exploration
                return RandomAction(all_actions=self.all_actions)(population)
        else:
            return BestAction(all_actions=self.all_actions)(population)

    def _handle_latest_action_for_acs2(self, population) -> int:
        last_executed_cls = None
        number_of_cls_per_action = {i: 0 for i in range(self.all_actions)}

        if len(population) > 0:
            last_executed_cls = min(population, key=lambda cl: cl.talp)

            # Count how many classifiers are there for each action
            population.sort(key=lambda cl: cl.action)
            for _action, _clss in groupby(population, lambda cl: cl.action):
                number_of_cls_per_action[_action] = \
                    sum([cl.num for cl in _clss])

        # If there are some actions with no classifiers - select them
        for action, nCls in number_of_cls_per_action.items():
            if nCls == 0:
                return action

        # Otherwise return the action of the last executed classifier
        if last_executed_cls:
            return last_executed_cls.action

        # if there is no classifiers at all - select random action

        return RandomAction(all_actions=self.all_actions)(population)