Revision: 586 http://rpy.svn.sourceforge.net/rpy/?rev=586&view=rev Author: lgautier Date: 2008-07-23 22:05:22 +0000 (Wed, 23 Jul 2008)
Log Message: ----------- new module (should have been added to SVN earlier) Added Paths: ----------- branches/rpy_nextgen/rpy/rlike/__init__.py branches/rpy_nextgen/rpy/rlike/container.py branches/rpy_nextgen/rpy/rlike/tests/ branches/rpy_nextgen/rpy/rlike/tests/__init__.py branches/rpy_nextgen/rpy/rlike/tests/test_container.py Added: branches/rpy_nextgen/rpy/rlike/container.py =================================================================== --- branches/rpy_nextgen/rpy/rlike/container.py (rev 0) +++ branches/rpy_nextgen/rpy/rlike/container.py 2008-07-23 22:05:22 UTC (rev 586) @@ -0,0 +1,119 @@ +class NamedList(dict): + """ Implements the Ordered Dict API defined in PEP 372. + When `odict` becomes part of collections, this class + should inherit from it rather than from `dict`. + + This class differs a little from the Ordered Dict + proposed in PEP 372 by the fact that: + + - not all elements have to be named. None has key value means + an absence of name for the element. + + - unlike in R, all names are unique. + + """ + + def __init__(self, c=[]): + + if isinstance(c, dict): + #FIXME: allow instance from NamedList ? + raise ValueError('A regular dictionnary does not ' +\ + 'conserve the order of its keys.') + + super(NamedList, self).__init__() + self.__l = [] + l = self.__l + + for k,v in c: + self[k] = v + + + def __cmp__(self, o): + raise(Exception("Not yet implemented.")) + + def __eq__(self): + raise(Exception("Not yet implemented.")) + + def __getitem__(self, key): + if key is None: + raise ValueError("Unnamed items cannot be retrieved by key.") + i = super(NamedList, self).__getitem__(key) + return self.__l[i][1] + + def __iter__(self): + l = self.__l + for e in l: + k = e[0] + if k is None: + continue + else: + yield k + + def __len__(self): + return len(self.__l) + + def __ne__(self): + raise(Exception("Not yet implemented.")) + + def __repr__(self): + s = 'o{' + for k,v in self.iteritems(): + s += "'" + str(k) + "': " + str(v) + ", " + s += '}' + return s + + def __reversed__(self): + raise(Exception("Not yet implemented.")) + + def __setitem__(self, key, value): + """ Replace the element if the key is known, + and conserve its rank in the list, or append + it if unknown. """ + + if key is None: + self.__l.append((key, value)) + return + + if self.has_key(key): + i = self.index(key) + self.__l[i] = (key, value) + else: + self.__l.append((key, value)) + super(NamedList, self).__setitem__(key, len(self.__l)-1) + + def byindex(self, i): + """ Fetch a value by index (rank), rather than by key.""" + return self.__l[i] + + def index(self, k): + """ Return the index (rank) for the key 'k' """ + return super(NamedList, self).__getitem__(k) + + 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 + + def iteritems(self): + return iter(self.__l) + + def reverse(self): + """ Reverse the order of the elements in-place (no copy).""" + l = self.__l + n = len(self.__l) + for i in xrange(n/2): + tmp = l[i] + l[i] = l[n-i-1] + kv = l[i] + if kv is not None: + super(NamedList, self).__setitem__(kv[0], i) + l[n-i-1] = tmp + kv = tmp + if kv is not None: + super(NamedList, self).__setitem__(kv[0], n-i-1) + + + def sort(self, cmp=None, key=None, reverse=False): + raise(Exception("Not yet implemented.")) + + Added: branches/rpy_nextgen/rpy/rlike/tests/__init__.py =================================================================== --- branches/rpy_nextgen/rpy/rlike/tests/__init__.py (rev 0) +++ branches/rpy_nextgen/rpy/rlike/tests/__init__.py 2008-07-23 22:05:22 UTC (rev 586) @@ -0,0 +1,14 @@ +import unittest + +import test_container + +def suite(): + suite_container = test_container.suite() + alltests = unittest.TestSuite([suite_container, + ]) + return alltests + +def main(): + r = unittest.TestResult() + suite().run(r) + return r Added: branches/rpy_nextgen/rpy/rlike/tests/test_container.py =================================================================== --- branches/rpy_nextgen/rpy/rlike/tests/test_container.py (rev 0) +++ branches/rpy_nextgen/rpy/rlike/tests/test_container.py 2008-07-23 22:05:22 UTC (rev 586) @@ -0,0 +1,83 @@ +import unittest +import itertools +import rpy2.rlike.container as rlc + +class NamedListTestCase(unittest.TestCase): + + def testNew(self): + nl = rlc.NamedList() + + x = (('a', 123), ('b', 456), ('c', 789)) + nl = rlc.NamedList(x) + + def testLen(self): + x = rlc.NamedList() + self.assertEquals(0, len(x)) + + x['a'] = 2 + x['b'] = 1 + + self.assertEquals(2, len(x)) + + def testGetSetitem(self): + x = rlc.NamedList() + + x['a'] = 1 + self.assertEquals(1, len(x)) + self.assertEquals(1, x['a']) + self.assertEquals(0, x.index('a')) + x['a'] = 2 + self.assertEquals(1, len(x)) + self.assertEquals(2, x['a']) + self.assertEquals(0, x.index('a')) + x['b'] = 1 + self.assertEquals(2, len(x)) + self.assertEquals(1, x['b']) + self.assertEquals(1, x.index('b')) + + def testGetSetitemWithNone(self): + x = rlc.NamedList() + + x['a'] = 1 + x[None] = 2 + self.assertEquals(2, len(x)) + x['b'] = 5 + self.assertEquals(3, len(x)) + self.assertEquals(1, x['a']) + self.assertEquals(5, x['b']) + self.assertEquals(0, x.index('a')) + self.assertEquals(2, x.index('b')) + + def testReverse(self): + x = rlc.NamedList() + x['a'] = 3 + x['b'] = 2 + x['c'] = 1 + x.reverse() + self.assertEquals(1, x['c']) + self.assertEquals(0, x.index('c')) + self.assertEquals(2, x['b']) + self.assertEquals(1, x.index('b')) + self.assertEquals(3, x['a']) + self.assertEquals(2, x.index('a')) + + def testCall(self): + + def f(**kwargs): + return [k for k in kwargs] + + x = rlc.NamedList() + x['a'] = 3 + x['b'] = 2 + x['c'] = 1 + + k = f(**x) + for ki, ko in itertools.izip(x, k): + self.assertTrue(ki, ko) + +def suite(): + suite = unittest.TestLoader().loadTestsFromTestCase(NamedListTestCase) + return suite + +if __name__ == '__main__': + unittest.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