Mercurial > repos > laurenmarazzi > netisce_test
view tools/myTools/bin/sfa/containers.py @ 1:7e5c71b2e71f draft default tip
Uploaded
author | laurenmarazzi |
---|---|
date | Wed, 22 Dec 2021 16:00:34 +0000 |
parents | |
children |
line wrap: on
line source
# -*- coding: utf-8 -*- import sys if sys.version_info <= (2, 8): from builtins import super import os import re import importlib import collections import abc import six import sfa.base import sfa.algorithms import sfa.data from sfa.utils import Singleton __all__ = ["AlgorithmSet", "DataSet"] @six.add_metaclass(abc.ABCMeta) class Container(collections.MutableMapping): """ A simple container class, which handles multiple objects with its hashable functionality (using dictionary). """ def __init__(self, *args, **kwargs): """ _dict: internal data structure, which is hashable. _dpath: Path of the directory containing algorithms, data, etc. """ self._map = dict() self._dpath = None self._all_keys = None self.update(dict(*args, **kwargs)) def __getitem__(self, key): return self._map[key] def __setitem__(self, key, value): if isinstance(value, sfa.base.ContainerItem): self._map[key] = value else: raise TypeError("Container.__setitem__ only accepts " "sfa.base.ContainerItem type object.") def __delitem__(self, key): del self._map[key] def __iter__(self): return iter(self._map) def __len__(self): return len(self._map) def __str__(self): return str(self._map) def keys(self): return self._map.keys() def values(self): return self._map.values() def create(self, keys=None): """ Create a single or multiple objects according to keys. keys: a single string or multiple strings in an iterable object. All related objects are created if 'keys' is None. """ if keys is not None: if type(keys) is str: return self._create_single(keys) elif hasattr(keys, '__iter__'): mult = [] # To return multiple elements # An iterable object contains multiple keys. for elem in keys: mult.append(self._create_single(elem)) return mult else: self._create_all() return self # end of def create @abc.abstractmethod def get_all_keys(self): """""" # end of def @abc.abstractmethod def _create_single(self, key): """Create a single object""" # end of def @abc.abstractmethod def _create_all(self): """Create all objects""" # end of def """ <References> [Dictionary functionality] http://stackoverflow.com/questions/3387691/python-how-to-perfectly-override-a-dict """ # end of def class excluded = ['np.py'] @Singleton class AlgorithmSet(Container): _instance = None def __new__(cls, *args, **kwargs): return super().__new__(cls, *args, **kwargs) def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) """ sfa.algorithms.__file__ represents a directory path containing sfa.algorithms's init module (__init__.py). """ self._dpath = os.path.dirname(sfa.algorithms.__file__) # end of def __init__ def get_all_keys(self): if not self._all_keys: self._all_keys = [] for entity in os.listdir(self._dpath): if re.match(r"[^_]\w+\.py$", entity) \ and entity not in excluded: mod_name = entity.split('.')[0] # Module name print(mod_name, entity) key = mod_name.upper() self._all_keys.append(key) yield key # end of for else: return iter(self._all_keys) def _create_single(self, key): if key in self._map: return self._map[key] key_low = key.lower() fstr_module_path = "%s.%s" % (sfa.algorithms.__name__, key_low) _key = key.upper() # We use captital characters for the key. if _key in self._map: # Avoid redundant importing return mod = importlib.import_module(fstr_module_path) # The following is of test purpose (removable in the future). if "this_should_be_imported" in mod.__name__: return alg = mod.create_algorithm(_key) self._map[_key] = alg # For testing purpose print("%s algorithm has been created." % (_key)) return alg def _create_all(self): """ Import all algorithms, based on file names """ for entity in os.listdir(self._dpath): if re.match(r"[^_]\w+\.py", entity) \ and entity not in excluded: mod_name = entity.split('.')[0] # Module name self._create_single(mod_name) # end of for # end of def _create_all # end of class Algorithms @Singleton class DataSet(Container): """ The name of this class is similar to that of 'DataSet' in C#. The instance of this class handles multiple sfa.base.Data objects. """ _instance = None def __new__(cls, *args, **kwargs): return super().__new__(cls, *args, **kwargs) def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) """ sfa.data.__file__ represents a directory path containing sfa.data's init module (__init__.py). """ self._dpath = os.path.dirname(sfa.data.__file__) # end of def __init__ def get_all_keys(self): if not self._all_keys: self._all_keys = [] for entity in os.listdir(self._dpath): dpath = os.path.join(self._dpath, entity) if not entity.startswith('_') and os.path.isdir(dpath): key = entity.upper() self._all_keys.append(key) yield key else: return iter(self._all_keys) def _create_single(self, key): if key in self._map: return self._map[key] key_items = key.split("_") key_1st, key_2nd = key_items[:2] mod_name = "%s_%s"%(key_1st.lower(), key_2nd.lower()) fstr_module_path = "%s.%s" % (sfa.data.__name__, mod_name) _key = key.upper() if _key in self._map: # Avoid redundant importing return elif mod_name.upper() in self._map: # All data object in this directory has been created before. return mod = importlib.import_module(fstr_module_path) if len(key_items) > 2: # Create the specified single data object data = mod.create_data(key) else: # Create all data objects from this directory data = mod.create_data() if isinstance(data, dict): self._map[_key] = data elif isinstance(data, list): self._map[_key] = {obj.abbr.upper(): obj for obj in data} elif isinstance(data, sfa.base.Data): _key = data.abbr.upper() self._map[_key] = data else: err_msg = "%s.create_data() returns unsupported type."\ % (fstr_module_path) raise TypeError(err_msg) # end of if # For testing purpose print("%s data has been created." % (_key)) return self._map[_key] # end of def _create_single def _create_all(self): """ Import all data, based on the directory names of data modules """ for entity in os.listdir(self._dpath): dpath = os.path.join(self._dpath, entity) if not entity.startswith('_') and os.path.isdir(dpath): self._create_single(entity) # end of for # end of def _create_all # end of def class DataSet