Revision: 596
http://rpy.svn.sourceforge.net/rpy/?rev=596&view=rev
Author: lgautier
Date: 2008-07-27 14:24:07 +0000 (Sun, 27 Jul 2008)
Log Message:
-----------
New class TaggedList
Modified Paths:
--------------
branches/rpy_nextgen/NEWS
branches/rpy_nextgen/rpy/rlike/container.py
branches/rpy_nextgen/rpy/rlike/tests/test_container.py
Modified: branches/rpy_nextgen/NEWS
===================================================================
--- branches/rpy_nextgen/NEWS 2008-07-26 09:14:58 UTC (rev 595)
+++ branches/rpy_nextgen/NEWS 2008-07-27 14:24:07 UTC (rev 596)
@@ -1,6 +1,6 @@
-SVN
-===
+Release 2.0.0a2
+===============
New features
------------
@@ -9,9 +9,12 @@
- package for R-like features in Python
-- module :mod:`rpy2.rlike.container` with the class :class:`ArgsDict`.
+- module :mod:`rpy2.rlike.container`
+- class :class:`ArgsDict` in :mod:`rpy2.rlike.container`
+- class :class:`TaggedList` in :mod:`rpy2.rlike.container`
+
:mod:`rpy2.rinterface`:
- method :meth:`named`, corresponding to R's C-level NAMED
Modified: branches/rpy_nextgen/rpy/rlike/container.py
===================================================================
--- branches/rpy_nextgen/rpy/rlike/container.py 2008-07-26 09:14:58 UTC (rev
595)
+++ branches/rpy_nextgen/rpy/rlike/container.py 2008-07-27 14:24:07 UTC (rev
596)
@@ -1,3 +1,5 @@
+import itertools
+
class ArgsDict(dict):
""" Implements the Ordered Dict API defined in PEP 372.
When `odict` becomes part of collections, this class
@@ -15,6 +17,9 @@
def __init__(self, c=[]):
+ if isinstance(c, TaggedList):
+ c = c.items()
+
if isinstance(c, dict):
#FIXME: allow instance from ArgsDict ?
raise ValueError('A regular dictionnary does not ' +\
@@ -92,7 +97,7 @@
def items(self):
""" Return an ordered list of all key/value pairs """
res = [self.byindex(i) for i in xrange(len(self.__l))]
- return res
+ return tuple(res)
def iteritems(self):
return iter(self.__l)
@@ -117,3 +122,125 @@
raise(Exception("Not yet implemented."))
+class TaggedList(list):
+ """ A list for which each item has a 'tag'. """
+
+ def __add__(self, tl):
+ try:
+ tags = tl.tags()
+ except AttributeError, ae:
+ raise ValueError('Can only concatenate TaggedLists.')
+ res = TaggedList(list(self) + list(tl),
+ tags = self.tags() + tl.tags())
+ return res
+
+ def __delitem__(self, y):
+ super(TaggedList, self).__delitem__(y)
+ self.__tags.__delitem__(y)
+
+ def __delslice__(self, i, j):
+ super(TaggedList, self).__delslice__(i, j)
+ self.__tags.__delslice__(i, j)
+
+ def __iadd__(self, y):
+ super(TaggedList, self).__iadd__(y)
+ if isinstance(y, TaggedList):
+ self.__tags.__iadd__(y.tags())
+ else:
+ self.__tags.__iadd__([None, ] * len(y))
+ return self
+
+ def __imul__(self, y):
+ restags = self.__tags.__imul__(y)
+ resitems = super(TaggedList, self).__imul__(y)
+ return self
+
+ def __init__(self, l, tags = None):
+
+ super(TaggedList, self).__init__(l)
+
+ if tags is None:
+ tags = [None, ] * len(l)
+ tags = list(tags)
+
+ if isinstance(tags, list):
+ if len(tags) != len(l):
+ raise ValueError("When a list, the parameter 'tags' must be of
same length as the given list.")
+ self.__tags = tags
+ else:
+ raise ValueError("Parameter 'tags' must be either a list or
'None'.")
+
+ def __setslice__(self, i, j, y):
+ #FIXME: implement
+ raise Exception("Not yet implemented.")
+
+ def append(self, obj, tag = None):
+ super(TaggedList, self).append(obj)
+ self.__tags.append(tag)
+
+ def extend(self, iterable):
+ if isinstance(iterable, TaggedList):
+ itertags = iterable.itertags()
+ else:
+ itertags = [None, ] * len(iterable)
+
+ for tag, item in itertools.izip(itertags, iterable):
+ self.append(item, tag=tag)
+
+
+ def insert(self, index, obj, tag=None):
+ super(TaggedList, self).insert(index, obj)
+ self.__tags.insert(index, tag)
+
+ def items(self):
+ """ Return a tuple of all pairs (tag, item). """
+ res = [(tag, item) for tag, item in itertools.izip(self.__tags, self)]
+ return tuple(res)
+
+ def iterontag(self, tag):
+ """ iterate on items marked with one given tag. """
+ i = 0
+ for onetag in self.__tags:
+ if tag == onetag:
+ yield self[i]
+ i += 1
+
+ def itertags(self):
+ """ iterate on tags. """
+ for tag in self.__tags:
+ yield tag
+
+ def pop(self, index=None):
+ if index is None:
+ index = len(self) - 1
+
+ super(TaggedList, self).pop(index)
+ self.__tags.pop(index)
+
+ def remove(self, value):
+ found = False
+ for i in xrange(len(self)):
+ if self[i] == value:
+ found = True
+ break
+ if found:
+ self.pop(i)
+
+ def reverse(self):
+ super(TaggedList, self).reverse()
+ self.__tags.reverse()
+
+ def sort(self):
+ #FIXME: implement
+ raise Exception("Not yet implemented.")
+
+
+ def tags(self):
+ """ Return a tuple of all tags """
+ res = [x for x in self.__tags]
+ return tuple(res)
+
+
+ def settag(self, i, t):
+ """ Set tag 't' for item 'i'. """
+ self.__tags[i] = t
Modified: branches/rpy_nextgen/rpy/rlike/tests/test_container.py
===================================================================
--- branches/rpy_nextgen/rpy/rlike/tests/test_container.py 2008-07-26
09:14:58 UTC (rev 595)
+++ branches/rpy_nextgen/rpy/rlike/tests/test_container.py 2008-07-27
14:24:07 UTC (rev 596)
@@ -83,9 +83,159 @@
self.assertEquals(ki[0], ko[0])
self.assertEquals(ki[1], ko[1])
+class TaggedListTestCase(unittest.TestCase):
+
+ def test__add__(self):
+ tn = ['a', 'b', 'c']
+ tv = [1,2, 3]
+ tl = rlc.TaggedList(tv, tags = tn)
+ tl = tl + tl
+ self.assertEquals(6, len(tl))
+ self.assertEquals(('a', 'b', 'c', 'a', 'b', 'c'), tl.tags())
+ self.assertEquals((1,2,3,1,2,3), tuple(tl))
+
+ def test__delitem__(self):
+ tn = ['a', 'b', 'c']
+ tv = [1,2,3]
+ tl = rlc.TaggedList(tv, tags = tn)
+ self.assertEquals(3, len(tl))
+ del tl[1]
+ self.assertEquals(2, len(tl))
+ self.assertEquals(tl.tags(), ('a', 'c'))
+ self.assertEquals(tuple(tl), (1, 3))
+
+ def test__delslice__(self):
+ self.assertTrue(False) # no test (yet)
+
+ def test__iadd__(self):
+ tn = ['a', 'b', 'c']
+ tv = [1, 2, 3]
+ tl = rlc.TaggedList(tv, tags = tn)
+ tl += tl
+ self.assertEquals(6, len(tl))
+ self.assertEquals(('a', 'b', 'c', 'a', 'b', 'c'), tl.tags())
+ self.assertEquals((1,2,3,1,2,3), tuple(tl))
+
+ def test__imul__(self):
+ tn = ['a', 'b']
+ tv = [1,2]
+ tl = rlc.TaggedList(tv, tags = tn)
+ tl *= 3
+ self.assertEquals(6, len(tl))
+ self.assertEquals(('a', 'b', 'a', 'b', 'a', 'b'), tl.tags())
+ self.assertEquals((1,2,1,2,1,2), tuple(tl))
+
+ def test__init__(self):
+ tn = ['a', 'b', 'c']
+ tv = [1,2,3]
+ tl = rlc.TaggedList(tv, tags = tn)
+
+ self.assertRaises(TypeError, rlc.TaggedList, tv, tags=123)
+ self.assertRaises(ValueError, rlc.TaggedList, tv, tags=('a', 'b'))
+
+
+ def test__setslice__(self):
+ self.assertTrue(False) # no test (yet)
+
+ def testappend(self):
+ tn = ['a', 'b', 'c']
+ tv = [1,2,3]
+ tl = rlc.TaggedList(tv, tags = tn)
+ self.assertEquals(3, len(tl))
+ tl.append(4, tag='a')
+ self.assertEquals(4, len(tl))
+ self.assertEquals(4, tl[3])
+ self.assertEquals(('a', 'b', 'c', 'a'), tl.tags())
+
+ def testextend(self):
+ tn = ['a', 'b', 'c']
+ tv = [1,2,3]
+ tl = rlc.TaggedList(tv, tags = tn)
+ tl.extend([4, 5])
+ self.assertEquals(('a', 'b', 'c', None, None), tuple(tl.itertags()))
+ self.assertEquals((1, 2, 3, 4, 5), tuple(tl))
+
+ def testinsert(self):
+ tn = ['a', 'b', 'c']
+ tv = [1,2,3]
+ tl = rlc.TaggedList(tv, tags = tn)
+ tl.insert(1, 4, tag = 'd')
+ self.assertEquals(('a', 'd', 'b', 'c'), tuple(tl.itertags()))
+ self.assertEquals((1, 4, 2, 3), tuple(tl))
+
+ def testitems(self):
+ tn = ['a', 'b', 'c']
+ tv = [1,2,3]
+ tl = rlc.TaggedList(tv, tags = tn)
+ self.assertEquals((('a', 1), ('b', 2), ('c', 3)),
+ tl.items())
+
+ def testiterontag(self):
+ tn = ['a', 'b', 'a', 'c']
+ tv = [1,2,3,4]
+ tl = rlc.TaggedList(tv, tags = tn)
+ self.assertEquals((1, 3), tuple(tl.iterontag('a')))
+
+ def testitertags(self):
+ tn = ['a', 'b', 'c']
+ tv = [1,2,3]
+ tl = rlc.TaggedList(tv, tags = tn)
+ self.assertEquals(('a', 'b', 'c'), tuple(tl.itertags()))
+
+ def testpop(self):
+ tn = ['a', 'b', 'c']
+ tv = [1,2,3]
+ tl = rlc.TaggedList(tv, tags = tn)
+ self.assertEquals(3, len(tl))
+ tl.pop()
+ self.assertEquals(2, len(tl))
+ self.assertEquals(tl.tags(), ('a', 'b'))
+ self.assertEquals(tuple(tl), (1, 2))
+
+ tl.pop(0)
+ self.assertEquals(1, len(tl))
+ self.assertEquals(tl.tags(), ('b', ))
+
+ def testremove(self):
+ tn = ['a', 'b', 'c']
+ tv = [1,2,3]
+ tl = rlc.TaggedList(tv, tags = tn)
+ self.assertEquals(3, len(tl))
+ tl.remove(2)
+ self.assertEquals(2, len(tl))
+ self.assertEquals(tl.tags(), ('a', 'c'))
+ self.assertEquals(tuple(tl), (1, 3))
+
+ def testreverse(self):
+ tn = ['a', 'b', 'c']
+ tv = [1,2,3]
+ tl = rlc.TaggedList(tv, tags = tn)
+ tl.reverse()
+ self.assertEquals(3, len(tl))
+ self.assertEquals(tl.tags(), ('c', 'b', 'a'))
+ self.assertEquals(tuple(tl), (3, 2, 1))
+
+ def testsort(self):
+ self.assertTrue(False) # no test (yet)
+ def testtags(self):
+ tn = ['a', 'b', 'c']
+ tv = [1,2,3]
+ tl = rlc.TaggedList(tv, tags = tn)
+ tags = tl.tags()
+ self.assertTrue(isinstance(tags, tuple))
+ self.assertEquals(tags, ('a', 'b', 'c'))
+
+ def testsettag(self):
+ tn = ['a', 'b', 'c']
+ tv = [1,2,3]
+ tl = rlc.TaggedList(tv, tags = tn)
+ tl.settag(1, 'z')
+ self.assertEquals(tl.tags(), ('a', 'z', 'c'))
+
def suite():
suite = unittest.TestLoader().loadTestsFromTestCase(ArgsDictTestCase)
+
suite.addTest(unittest.TestLoader().loadTestsFromTestCase(TaggedListTestCase))
return suite
if __name__ == '__main__':
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
rpy-list mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/rpy-list