Moved in MergeDicts. master
Moved in MergeDicts.
Added .gitignore.

file:b/.gitignore (new)
  __pycache__
  .project
  .pydevproject
 
file:a/Modular.py -> file:b/Modular.py
#!/usr/bin/python3 #!/usr/bin/python3
''' '''
Created on Apr 26, 2013 Created on Apr 26, 2013
@author: andy @author: andy
''' '''
__all__ = ['Component', 'ModularType', 'Modular', 'Node'] __all__ = ['Component', 'ModularType', 'Modular', 'Node']
from _tools import merge_dicts  
from sys import modules from sys import modules
from collections import OrderedDict from collections import OrderedDict
   
  def MergeDicts(*dicts):
  r = {}
  for d in dicts:
  for k, v in d.items():
  if k not in r:
  r[k] = v
  elif isinstance(r[k], dict) and isinstance(v, dict):
  r[k] = MergeDicts(r[k], v)
  else: r[k] += v
   
  return r
class ModularType(type): class ModularType(type):
subclasses = {} subclasses = {}
DerivedValues = {} DerivedValues = {}
filter = {} filter = {}
@classmethod @classmethod
def __prepare__(mcls, name, bases): def __prepare__(mcls, name, bases):
return {'__classname__': name} return {'__classname__': name}
def __new__(cls, name, bases, classDict): def __new__(cls, name, bases, classDict):
newClass = type.__new__(cls, name, bases, classDict) newClass = type.__new__(cls, name, bases, classDict)
if 'moduleDepends' in classDict: if 'moduleDepends' in classDict:
for module in classDict['moduleDepends']: for module in classDict['moduleDepends']:
if module not in cls.DerivedValues: if module not in cls.DerivedValues:
cls.DerivedValues[module] = {} cls.DerivedValues[module] = {}
cls.DerivedValues[module] = merge_dicts(cls.DerivedValues[module], {newClass: classDict['moduleDepends']}) cls.DerivedValues[module] = MergeDicts(cls.DerivedValues[module], {newClass: classDict['moduleDepends']})
if 'filter' in classDict: if 'filter' in classDict:
cls.filter = merge_dicts(cls.filter, classDict['filter']) cls.filter = MergeDicts(cls.filter, classDict['filter'])
if name not in cls.subclasses: if name not in cls.subclasses:
cls.subclasses[name] = newClass cls.subclasses[name] = newClass
_all = modules[newClass.__module__].__dict__.setdefault('__all__', []) _all = modules[newClass.__module__].__dict__.setdefault('__all__', [])
if name not in _all: if name not in _all:
_all.append(name) _all.append(name)
return newClass return newClass
@classmethod @classmethod
def getSubclass(cls, idx): def getSubclass(cls, idx):
if idx in cls.subclasses: if idx in cls.subclasses:
return cls.subclasses[idx] return cls.subclasses[idx]
raise KeyError("{0}: No such ModularType class.".format(repr(idx))) raise KeyError("{0}: No such ModularType class.".format(repr(idx)))
class Modular(metaclass=ModularType): class Modular(metaclass=ModularType):
def __init__(self): def __init__(self):
self._components = OrderedDict() self._components = OrderedDict()
def addComponent(self, comp): def addComponent(self, comp):
if isinstance(comp, Modular): if isinstance(comp, Modular):
o = comp o = comp
elif isinstance(comp, type): elif isinstance(comp, type):
o = comp() o = comp()
else: else:
raise TypeError("Got '{0}', expected Component object or class.".format(comp.__class__.__name__)) raise TypeError("Got '{0}', expected Component object or class.".format(comp.__class__.__name__))
component_name = o.__class__.__name__ component_name = o.__class__.__name__
if component_name in self._components: if component_name in self._components:
return self._components[component_name] return self._components[component_name]
self._components[component_name] = o self._components[component_name] = o
o._container = self o._container = self
if o.__class__ in self.__class__.DerivedValues: if o.__class__ in self.__class__.DerivedValues:
for mod, depends in self.__class__.DerivedValues[o.__class__].items(): for mod, depends in self.__class__.DerivedValues[o.__class__].items():
dependsMet = True dependsMet = True
for depend in depends: for depend in depends:
if depend.__name__ not in self._components: if depend.__name__ not in self._components:
dependsMet = False dependsMet = False
break break
if dependsMet: if dependsMet:
c = mod() c = mod()
if isinstance(c, mod): if isinstance(c, mod):
self.addComponent(mod) self.addComponent(mod)
return o return o
def getComponent(self): def getComponent(self):
return self return self
def __getattribute__(self, *args): def __getattribute__(self, *args):
ex = True ex = True
rval = None rval = None
try: try:
rval = object.__getattribute__(self, *args) rval = object.__getattribute__(self, *args)
ex = False ex = False
except AttributeError as e: except AttributeError as e:
for component in self._components.values(): for component in self._components.values():
try: try:
rval = object.__getattribute__(component, *args) rval = object.__getattribute__(component, *args)
ex = False ex = False
except AttributeError: except AttributeError:
pass pass
except Exception as f: except Exception as f:
e = f e = f
if ex: if ex:
raise e raise e
return rval return rval
class Node(Modular): class Node(Modular):
id_count = 0 id_count = 0
@classmethod @classmethod
def next_id(cls): def next_id(cls):
cls.id_count += 1 cls.id_count += 1
return cls.id_count return cls.id_count
def __new__(cls, *args, **kwargs): def __new__(cls, *args, **kwargs):
o = super().__new__(cls) o = super().__new__(cls)
o._ID = cls.next_id() o._ID = cls.next_id()
return o return o
def __init__(self): def __init__(self):
super().__init__() super().__init__()
self.__setattr__("get{0}Node".format(self.__class__.__name__), self.getComponent) self.__setattr__("get{0}Node".format(self.__class__.__name__), self.getComponent)
self._Parent = None self._Parent = None
self._Children = {} self._Children = {}
@classmethod @classmethod
def _ChangeParent(cls, nod, new_parent): def _ChangeParent(cls, nod, new_parent):
if nod._Parent is not None: if nod._Parent is not None:
nod._Parent._RemoveChildByIndex(nod) nod._Parent._RemoveChildByIndex(nod)
new_parent._AddChildByIndex(nod) new_parent._AddChildByIndex(nod)
def _AddChildByIndex(self, child, idx=None): def _AddChildByIndex(self, child, idx=None):
if idx is not None: if idx is not None:
index = idx index = idx
else: else:
index = child._ID index = child._ID
if child._ID in self._Children: if child._ID in self._Children:
return False return False
if child._Parent is not None: if child._Parent is not None:
child._Parent._RemoveChildByIndex(idx) child._Parent._RemoveChildByIndex(idx)
child._Parent = self child._Parent = self
self._Children[index] = child self._Children[index] = child
return True return True
def _RemoveChildByIndex(self, Idx): def _RemoveChildByIndex(self, Idx):
if Idx in self._Children: if Idx in self._Children:
child = self._Children[Idx] child = self._Children[Idx]
child._Parent = None child._Parent = None
del self._Children[Idx] del self._Children[Idx]
return child return child
return False return False
class Component(Node): class Component(Node):
HumanName = "ComponentName" HumanName = "ComponentName"
HumanUnits = "units" HumanUnits = "units"
def __init__(self): def __init__(self):
super().__init__() super().__init__()
self._identifier = self.__classname__ self._identifier = self.__classname__
self._value = 0 self._value = 0
def getTareValue(self): def getTareValue(self):
return self._value return self._value
def setValue(self, value): def setValue(self, value):
self._value = value self._value = value
def getValue(self): def getValue(self):
s = self._value s = self._value
for child in self._container._Children.values(): for child in self._container._Children.values():
if self.__class__.__name__ in child._components: if self.__class__.__name__ in child._components:
childCompNode = child._components[self.__class__.__name__] childCompNode = child._components[self.__class__.__name__]
s += childCompNode.getValue() s += childCompNode.getValue()
return s return s
def __str__(self): def __str__(self):
_val = self.getValue() _val = self.getValue()
try: try:
_val = "{0:.6g}".format(_val) _val = "{0:.6g}".format(_val)
except: except:
pass pass
return "{0}: {1} {2}".format(self.HumanName, _val, self.HumanUnits) return "{0}: {1} {2}".format(self.HumanName, _val, self.HumanUnits)
class MultiValueComponent(Component): class MultiValueComponent(Component):
def __init__(self): def __init__(self):
super().__init__() super().__init__()
self._value = {} self._value = {}
def getValueByKey(self, key): def getValueByKey(self, key):
return self._value[key] return self._value[key]
def getValue(self): def getValue(self):
s = self._value s = self._value
for child in self._container._Children.values(): for child in self._container._Children.values():
if self.__classname__ in child._components: if self.__classname__ in child._components:
s = merge_dicts(s, child._components[self.__classname__].getValue()) s = MergeDicts(s, child._components[self.__classname__].getValue())
return s return s
def __str__(self): def __str__(self):
s = [] s = []
for key, value in self.getValue().items(): for key, value in self.getValue().items():
try: try:
value = "{0:.6g}".format(value) value = "{0:.6g}".format(value)
except: except:
pass pass
units = self.HumanUnits units = self.HumanUnits
if key in self.keyNames: if key in self.keyNames:
key = self.keyNames[key] key = self.keyNames[key]
if key in self.keyUnits: if key in self.keyUnits:
units = self.keyUnits[key] units = self.keyUnits[key]
s.append("{0} ({1}): {2} {3}".format(self.HumanName, key, value, units)) s.append("{0} ({1}): {2} {3}".format(self.HumanName, key, value, units))
return "\n{0: <{w}}".format('', w=self._container._depth * 4).join(s) return "\n{0: <{w}}".format('', w=self._container._depth * 4).join(s)
keyNames = {} keyNames = {}
keyUnits = {} keyUnits = {}