Skip to content

Instantly share code, notes, and snippets.

@zzeleznick
Last active August 9, 2016 16:33
Show Gist options
  • Save zzeleznick/a0bb0aa2dd461d0f9cf44755ba461442 to your computer and use it in GitHub Desktop.
Save zzeleznick/a0bb0aa2dd461d0f9cf44755ba461442 to your computer and use it in GitHub Desktop.
Steals away keys from children
from collections import OrderedDict
"""Q: How do we define a data structure that makes it easy
to determine which keys should be passed to children
and which should be passed to report summaries.
And which keys should be promoted?
## Thoughts:
- CAPS_AND_UNDERSCORE signify importance
- Optional updates
- All keys should be passed to children by default
"""
def issub_dict(obj):
return issubclass(type(obj), dict)
class GreedyDict(OrderedDict):
"""GreedyDict will absorb updates to children dictionaries
and place those key-value pairs top-level if the key has not
yet been added"""
def __init__(self, *args, **kwds):
super(GreedyDict, self).__init__()
# shallow_copy
for k in self.__dict__.keys():
kk = k.replace('OrderedDict', 'GreedyDict')
self.__dict__[kk] = self.__dict__[k]
self.parent = None
self.root = None
self.update(*args, **kwds)
def __str__(self):
if not self:
return '%s()' % (self.__class__.__name__,)
return '%s(%r)' % (self.__class__.__name__, self.items())
__repr__ = __str__
def __getitem__(self, key):
try:
return super(GreedyDict, self).__getitem__(key)
except KeyError:
self[key] = {}
return self[key]
def __setitem__(self, key, value, PREV=0, NEXT=1, dict_setitem=dict.__setitem__):
""" Setting a new item creates a new link which goes at the end of the linked
list, and the inherited dictionary is updated with the new key/value pair.
"""
if self.parent:
pass # print 'I have a parent'
if key not in self:
root = self.__root
last = root[PREV]
last[NEXT] = root[PREV] = self.__map[key] = [last, root, key]
if issub_dict(value):
root = self.root if self.root else self
value = GreedyDict.make(value, parent=self, root=root)
if self.root:
if key not in self.root:
self.root[key] = value
elif issub_dict(self.root[key]) and len(self.root[key]) == 0:
self.root[key] = value
dict_setitem(self, key, value)
def __getattr__(self, name):
"""__getattr__ sets a default value by
determining how to handle attributes that are not found
"""
if name in self:
return self[name]
elif name.endswith('__root'):
# required to allow proper construction of object
raise AttributeError
else:
print '%s has no attribute %s' % (self.__class__.__name__, name)
return None
@classmethod
def make(cls, value, parent, root):
res = cls(value)
res.parent = parent
res.root = root
return res
def say_hi(self):
return 'HI'
def populate():
pass
def main():
x = GreedyDict()
x['PROTECTED'] = "I'm preserved"
x[0] = {3:0, 1:2}
x['args'] = {'junk': 2} # not saved to top-level
x['args'].update({'SAVEME': 10, 'ME_TOO': 40, 'PROTECTED': 'MUAHAHAH' })
print x
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment