Revision: 441
          http://rpy.svn.sourceforge.net/rpy/?rev=441&view=rev
Author:   lgautier
Date:     2008-03-15 07:16:23 -0700 (Sat, 15 Mar 2008)

Log Message:
-----------
- implemented item assignment in SexpVector
- added unit tests for that (currently the code is not passing all of them)

Modified Paths:
--------------
    trunk/sandbox/rpy_nextgen/rpy/rinterface/rinterface.c
    trunk/sandbox/rpy_nextgen/rpy/rinterface/tests/test_SexpVector.py

Modified: trunk/sandbox/rpy_nextgen/rpy/rinterface/rinterface.c
===================================================================
--- trunk/sandbox/rpy_nextgen/rpy/rinterface/rinterface.c       2008-03-15 
12:24:10 UTC (rev 440)
+++ trunk/sandbox/rpy_nextgen/rpy/rinterface/rinterface.c       2008-03-15 
14:16:23 UTC (rev 441)
@@ -730,7 +730,81 @@
   return res;
 }
 
+/* a[i] = val */
+static PyObject *
+VectorSexp_ass_item(PyObject *object, Py_ssize_t i, PyObject *val)
+{
+  PyObject* res;
+  R_len_t i_R;
 
+  /* R is still with int for indexes */
+  if (i >= R_LEN_T_MAX) {
+    PyErr_Format(PyExc_IndexError, "Index value exceeds what R can handle.");
+    return NULL;
+  }
+
+  SEXP *sexp = &(((SexpObject *)object)->sexp);
+  if (i >= GET_LENGTH(*sexp)) {
+    PyErr_Format(PyExc_IndexError, "Index out of range.");
+    return NULL;
+  }
+
+  if (! sexp) {
+    PyErr_Format(PyExc_ValueError, "NULL SEXP.");
+    return NULL;
+  }
+
+  int is_SexpObject = PyObject_TypeCheck(val, &Sexp_Type);
+  if (! is_SexpObject) {
+    PyErr_Format(PyExc_ValueError, "Any new value must be of "
+                "type 'Sexp_Type'.");
+    return NULL;
+  }
+  SEXP *sexp_val = &(((SexpObject *)val)->sexp);
+  if (! sexp_val) {
+    PyErr_Format(PyExc_ValueError, "NULL SEXP.");
+    return NULL;
+  }
+
+  if (TYPEOF(*sexp_val) != TYPEOF(*sexp)) {
+    PyErr_Format(PyExc_ValueError, "The type for the new value cannot be 
different.");
+    return NULL;
+  }
+
+  if ((TYPEOF(*sexp_val) != VECSXP) & (LENGTH(*sexp_val) != 1)) {
+    PyErr_Format(PyExc_ValueError, "The new value must be of length 1.");
+    return NULL;
+  }
+
+  i_R = (R_len_t)i;
+  switch (TYPEOF(*sexp)) {
+  case REALSXP:
+    (NUMERIC_POINTER(*sexp))[i_R] = (NUMERIC_POINTER(*sexp_val))[0];
+    break;
+  case INTSXP:
+    (INTEGER_POINTER(*sexp))[i_R] = (INTEGER_POINTER(*sexp_val))[0];
+    break;
+  case LGLSXP:
+    (LOGICAL_POINTER(*sexp))[i_R] = (LOGICAL_POINTER(*sexp_val))[0];
+    break;
+  case CPLXSXP:
+    (COMPLEX_POINTER(*sexp))[i_R] = (COMPLEX_POINTER(*sexp_val))[0];
+    break;
+  case STRSXP:
+    SET_STRING_ELT(*sexp, i_R, *sexp_val);
+    break;
+  case VECSXP:
+    SET_VECTOR_ELT(*sexp, i_R, *sexp_val);
+    break;
+  default:
+    PyErr_Format(PyExc_ValueError, "cannot handle type %d", 
+                TYPEOF(*sexp));
+    res = NULL;
+    break;
+  }
+  return res;
+}
+
 static PySequenceMethods VectorSexp_sequenceMethods = {
   (lenfunc)VectorSexp_len,              /* sq_length */
   0,                              /* sq_concat */
@@ -740,7 +814,7 @@
   //FIXME: implement
   0, //(ssizessizeargfunc)VectorSexp_slice,  /* sq_slice */
   //FIXME: implement
-  0, //(ssizeobjargproc)VectorSexp_ass_item,   /* sq_ass_item */
+  (ssizeobjargproc)VectorSexp_ass_item,   /* sq_ass_item */
   0,                              /* sq_ass_slice */
   0,                              /* sq_contains */
   0,                              /* sq_inplace_concat */
@@ -1178,7 +1252,6 @@
         }
     }
     break;
-    //FIXME: add complex 
   default:
     PyErr_Format(PyExc_ValueError, "cannot handle type %d", rType);
     sexp = NULL;

Modified: trunk/sandbox/rpy_nextgen/rpy/rinterface/tests/test_SexpVector.py
===================================================================
--- trunk/sandbox/rpy_nextgen/rpy/rinterface/tests/test_SexpVector.py   
2008-03-15 12:24:10 UTC (rev 440)
+++ trunk/sandbox/rpy_nextgen/rpy/rinterface/tests/test_SexpVector.py   
2008-03-15 14:16:23 UTC (rev 441)
@@ -4,6 +4,9 @@
 #FIXME: can starting and stopping an embedded R be done several times ?
 rinterface.initEmbeddedR("foo", "--vanilla", "--no-save", "--quiet")
 
+def floatEqual(x, y, epsilon = 0.00000001):
+    return abs(x - y) < epsilon
+
 class SexpVectorTestCase(unittest.TestCase):
     #def setUpt(self):
     #    rinterface.initEmbeddedR("foo", "--no-save")
@@ -59,6 +62,7 @@
         ok = isList(sexp)[0]
         self.assertTrue(ok)
 
+        self.assertEquals(2, len(sexp))
         
 
     def testNew_InvalidType(self):
@@ -84,5 +88,70 @@
         for i, li in enumerate(myList):
             self.assertEquals(i, myList[i][0])
 
+    def testAssignItemDifferentType(self):
+        c_R = rinterface.globalEnv.get("c")
+        myVec = c_R(rinterface.SexpVector([0, 1, 2, 3, 4, 5], 
rinterface.INTSXP))
+        self.assertRaises(ValueError, myVec.__setitem__, 0, 
rinterface.SexpVector(["a", ], rinterface.STRSXP))
+        
+    def testAssignItemOutOfBound(self):
+        c_R = rinterface.globalEnv.get("c")
+        myVec = c_R(rinterface.SexpVector([0, 1, 2, 3, 4, 5], 
rinterface.INTSXP))
+        self.assertRaises(ValueError, myVec.__setitem__, 10, 
rinterface.SexpVector([1, ], rinterface.INTSXP))
+
+    def testAssignItemInt(self):
+        c_R = rinterface.globalEnv.get("c")
+        myVec = c_R(rinterface.SexpVector([0, 1, 2, 3, 4, 5], 
rinterface.INTSXP))
+        myVec[0] = rinterface.SexpVector([100, ], rinterface.INTSXP)
+        self.assertTrue(myVec[0] == 100)
+
+        myVec[3] = rinterface.SexpVector([100, ], rinterface.INTSXP)
+        self.assertTrue(myVec[3] == 100)
+
+    def testAssignItemReal(self):
+        c_R = rinterface.globalEnv.get("c")
+        myVec = c_R(rinterface.SexpVector([0.0, 1.0, 2.0, 3.0, 4.0, 5.0], 
rinterface.REALSXP))
+        myVec[0] = rinterface.SexpVector([100.0, ], rinterface.REALSXP)
+        self.assertTrue(floatEqual(myVec[0], 100.0))
+
+        myVec[3] = rinterface.SexpVector([100.0, ], rinterface.REALSXP)
+        self.assertTrue(floatEqual(myVec[3], 100.0))
+
+    def testAssignItemLogical(self):
+        c_R = rinterface.globalEnv.get("c")
+        myVec = c_R(rinterface.SexpVector([True, False, True, True, False], 
rinterface.LGLSXP))
+        myVec[0] = rinterface.SexpVector([False, ], rinterface.LGLSXP)
+        self.assertFalse(myVec[0])
+
+        myVec[3] = rinterface.SexpVector([False, ], rinterface.LGLSXP)
+        self.assertFalse(myVec[3])
+
+    def testAssignItemComplex(self):
+        c_R = rinterface.globalEnv.get("c")
+        myVec = c_R(rinterface.SexpVector([1.0+2.0j, 2.0+2.0j, 3.0+2.0j, 
4.0+2.0j, 5.0+2.0j], rinterface.CPLXSXP))
+        myVec[0] = rinterface.SexpVector([100.0+200.0j, ], rinterface.CPLXSXP)
+        self.assertTrue(floatEqual(myVec[0].real, 100.0))
+        self.assertTrue(floatEqual(myVec[0].imag, 200.0))
+
+        myVec[3] = rinterface.SexpVector([100.0+200.0j, ], rinterface.CPLXSXP)
+        self.assertTrue(floatEqual(myVec[3].real, 100.0))
+        self.assertTrue(floatEqual(myVec[3].imag, 200.0))
+
+    def testAssignItemList(self):
+        myVec = rinterface.SexpVector([rinterface.SexpVector(["a", ], 
rinterface.STRSXP), 
+                                       rinterface.SexpVector([1, ], 
rinterface.INTSXP),
+                                       rinterface.SexpVector([3, ], 
rinterface.INTSXP)], rinterface.VECSXP)
+        
+        myVec[0] = rinterface.SexpVector([rinterface.SexpVector([100.0, ], 
rinterface.REALSXP), ], rinterface.VECSXP)
+        self.assertTrue(floatEqual(myVec[0][0][0], 100.0))
+        
+        myVec[2] = rinterface.SexpVector([rinterface.SexpVector(["a", ], 
rinterface.STRSXP), ], rinterface.VECSXP) 
+        self.assertTrue(myVec[2][0][0] == "a")
+        
+    def testAssignItemString(self):
+        letters_R = rinterface.globalEnv.get("letters")
+        #FIXME: segfaults
+        #letters_R[0] = rinterface.SexpVector(["z", ], rinterface.STRSXP)
+        self.assertTrue(letters_R[0] == "z")
+
 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: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
rpy-list mailing list
rpy-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/rpy-list

Reply via email to