added some convenience methods to Jeep

git-svn-id: svn://svn.cy55.de/Zope3/src/cybertools/trunk@2109 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
helmutm 2007-10-12 14:08:00 +00:00
parent 6cfb4c0464
commit 2ab7fc800b
2 changed files with 116 additions and 15 deletions

View file

@ -31,14 +31,19 @@ class Jeep(object):
_attributes = ('_sequence',)
def __init__(self, seq=[]):
sequence = self._sequence = []
for item in seq:
if isinstance(item, (list, tuple)) and len(item) == 2:
attr, value = item
sequence.append(attr)
object.__setattr__(self, attr, value)
else:
self.append(item)
if isinstance(seq, Jeep):
self._sequence = list(seq.keys())
for key, value in seq.items():
object.__setattr__(self, key, value)
else:
sequence = self._sequence = []
for item in seq:
if isinstance(item, (list, tuple)) and len(item) == 2:
attr, value = item
sequence.append(attr)
object.__setattr__(self, attr, value)
else:
self.append(item)
def __len__(self):
return len(self._sequence)
@ -75,7 +80,7 @@ class Jeep(object):
return getattr(self, key, _notfound) is not _notfound
def keys(self):
return [key for key in self._sequence]
return list(self._sequence)
def values(self):
return list(self)
@ -94,9 +99,6 @@ class Jeep(object):
return value
return existing
def index(self, key):
return self._sequence.index(key)
def append(self, obj):
self.insert(len(self), obj)
@ -135,9 +137,25 @@ class Jeep(object):
def index(self, obj):
idx = self.find(obj)
if idx < 0:
raise ValueError('list.index(x): x not in list')
raise ValueError('list.index(x): %r not in list' % obj)
return idx
def remove(self, *keys):
myKeys = self.keys()
for key in keys:
if key in myKeys:
del self[key]
def select(self, *keys):
myKeys = self._sequence
self._sequence = [k for k in keys if k in myKeys]
for k in myKeys:
if k not in keys:
super(Jeep, self).__delattr__(k)
def reorder(self, delta, *keys):
self._sequence = moveByDelta(self._sequence, keys, delta)
class Term(object):
""" A simple name/title association that may be put in a jeep object.
@ -152,3 +170,20 @@ class Term(object):
def __str__(self):
return self.title
def moveByDelta(objs, toMove, delta):
""" Return the list given by objs re-ordered in a way that the elements
of toMove (which must be in the objs list) have been moved by delta.
"""
result = [obj for obj in objs if obj not in toMove]
if delta < 0:
objs = list(reversed(objs))
result.reverse()
toMove = sorted(toMove, lambda x,y: cmp(objs.index(x), objs.index(y)))
for element in toMove:
newPos = min(len(result), objs.index(element) + abs(delta))
result.insert(newPos, element)
if delta < 0:
result.reverse()
return result

View file

@ -78,6 +78,25 @@ More Dictionary Methods
>>> dict(jeep)
{'second': 'new second value', 'third': 'third value', 'first': 'first value'}
>>> jeep.setdefault('first', 'new first value')
'first value'
>>> jeep['first']
'first value'
>>> jeep.setdefault('fourth', 'new fourth value')
'new fourth value'
>>> jeep['fourth']
'new fourth value'
>>> len(jeep)
4
>>> del jeep['fourth']
>>> len(jeep)
3
>>> del jeep['fourth']
Traceback (most recent call last):
...
ValueError: ...not in list
More Methods and Operators
--------------------------
@ -103,7 +122,7 @@ Sequence Additions with Named Objects
-------------------------------------
Objects that have a ``__name__`` attribute can be appended
to a Jeep object as the dictionary key can be obtained from these attribute.
to a Jeep object as the dictionary key can be obtained from this attribute.
>>> class Term(object):
... def __init__(self, token, title=None, value=None):
@ -135,7 +154,54 @@ an exception:
Constructors
------------
>>> jeep2 = Jeep((('f', '1st'), ('s', '2nd'), ('t', '3rd')))
A simple way of creating a Jeep object is using a sequence
of key-value pairs.
>>> jeep2 = Jeep((('1', '1st'), ('2', '2nd'), ('3', '3rd')))
>>> list(jeep2)
['1st', '2nd', '3rd']
Using a Jeep object as the argument of the constructor yields a shallow
copy.
>>> jeep3 = Jeep(jeep2)
>>> jeep3['1'] is jeep2['1']
True
>>> jeep3['4'] = '4th'
>>> len(jeep3)
4
>>> len(jeep2)
3
More in-place changes
---------------------
Remove elements in a fault-tolerant way.
>>> jeep.keys()
['first', 'term2', 'second', 'term1']
>>> jeep.remove('third', 'second')
>>> len(jeep)
3
>>> jeep.keys()
['first', 'term2', 'term1']
>>> 'second' in jeep
False
Reorder the sequence and remove all elements that are not
in the argument list.
>>> jeep.select('term1', 'term2', 'nope')
>>> jeep.keys()
['term1', 'term2']
>>> 'first' in jeep
False
You may even reposition a certain element.
>>> jeep3.keys()
['1', '2', '3', '4']
>>> jeep3.reorder(-1, '2', '4')
>>> jeep3.keys()
['2', '1', '4', '3']