import copy
from abc import ABCMeta, abstractmethod, ABC
from typing import List, Dict
from pytypes import is_of_type
from optimeed.core import printIfShown, SHOW_WARNING, text_format
[docs]class Option_class_interface(ABC, metaclass=ABCMeta):
"""
Interface of the class 'Option_class'. It defines all the necessary methods to manage a set of options.
"""
@abstractmethod
def __init__(self):
pass
@abstractmethod
[docs] def __str__(self):
pass
@abstractmethod
[docs] def get_optionValue(self, optionId: int):
pass
@abstractmethod
[docs] def set_optionValue(self, optionId: int, value):
pass
@abstractmethod
[docs] def get_all_options(self) -> dict:
"""
Return a dictionnary containing tuples (name of the option, value of the option)
:return: dict
"""
pass
@abstractmethod
[docs] def set_all_options(self, options: 'Option_class_interface'):
"""
The method allows to define all the options from another object of type 'Option_class_interface'
:param options: Option_class_interface
:return:
"""
pass
@abstractmethod
[docs] def add_option(self, idOption: int, name: str, value):
pass
[docs]class Options:
def __init__(self):
self.options = dict()
[docs] def get_name(self, idOption):
return self.options[idOption][0]
[docs] def get_value(self, idOption):
return self.options[idOption][1]
[docs] def add_option(self, idOption, name, value):
self.options[idOption] = (name, value)
[docs] def set_option(self, idOption, value):
self.options[idOption] = (self.get_name(idOption), value)
[docs] def copy(self):
return copy.deepcopy(self)
[docs] def set_self(self, the_options):
for idOption in the_options.options:
self.set_option(idOption, the_options.get_value(idOption))
[docs] def __str__(self):
theStr = ''
if len(self.options):
theStr += text_format.BLUE + 'Options'
for key in self.options:
theStr += '\n◦ {:<15}'.format(self.get_name(key)) + '\t-\t' + str(self.get_value(key))
theStr += text_format.END
return theStr
[docs]class Option_class(Option_class_interface):
def __init__(self):
super().__init__()
self.Options = Options()
[docs] def __str__(self):
return str(self.Options)
[docs] def get_optionValue(self, optionId):
return self.Options.get_value(optionId)
[docs] def set_optionValue(self, optionId, value):
self.Options.set_option(optionId, value)
[docs] def get_all_options(self):
return self.Options.options
[docs] def set_all_options(self, options):
self.Options = options
[docs] def add_option(self, idOption, name, value):
self.Options.add_option(idOption, name, value)
[docs]class Option_class_typed(Option_class_interface):
[docs] my_names: Dict[int, str]
[docs] my_options_0: Dict[int, int]
[docs] my_options_1: Dict[int, float]
[docs] my_options_2: Dict[int, bool]
[docs] my_options_3: Dict[int, str]
[docs] my_options_4: Dict[int, List[int]]
[docs] my_options_5: Dict[int, List[float]]
[docs] my_options_6: Dict[int, List[str]]
[docs] my_options_7: Dict[int, List[bool]]
def __init__(self):
super().__init__()
self.nbr_of_types = len(self.__get_types())
self.my_names = {}
self.my_map = {}
for i in range(self.nbr_of_types):
setattr(self, 'my_options_' + str(i), {})
@staticmethod
[docs] def __get_types():
return [int, float, bool, str, List[int], List[float], List[bool], List[str]]
[docs] def get_optionValue(self, optionId: int):
return getattr(self, self.my_map[optionId])[optionId]
[docs] def set_optionValue(self, optionId: int, value):
try:
del self.my_map[optionId]
except KeyError:
print("There is no option with this id ({}) :/".format(optionId))
return
self.add_option(optionId, self.my_names[optionId], value)
[docs] def get_all_options(self):
options = {}
for i in range(self.nbr_of_types):
the_options = getattr(self, 'my_options_' + str(i), {})
for k in the_options:
options[k] = (self.my_names[k], the_options[k])
return options
[docs] def add_option(self, idOption: int, name: str, value):
if idOption in self.my_map:
printIfShown("Sorry but this id (" + str(idOption) + ") already exists and is associated to '" + self.my_names[idOption] + "' :/", SHOW_WARNING)
return
success = False
types = self.__get_types()
for i in range(self.nbr_of_types):
if self.__match(value, types[i]):
self.my_names[idOption] = name
getattr(self, 'my_options_' + str(i))[idOption] = value
self.my_map[idOption] = 'my_options_' + str(i)
success = True
break
if not success:
printIfShown("This type of value (" + str(type(value)) + ") is not supported by the 'Options class' yet :/\n Variable '" + name + "' has not been added to the options ! ", SHOW_WARNING)
return
@staticmethod
[docs] def __match(value, theType):
return is_of_type(value, theType)
[docs] def set_all_options(self, options: Option_class_interface):
for idOption in options.get_all_options():
self.set_optionValue(idOption, options.get_optionValue(idOption))
[docs] def __str__(self):
theStr = ''
if self.my_names:
theStr += text_format.BLUE + 'Options'
for key in self.my_map:
theStr += '\n◦ {:<15}'.format(self.my_names[key]) + '\t-\t' + str(self.get_optionValue(key))
theStr += text_format.END
return theStr