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
rpy-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/rpy-list

Reply via email to