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
[email protected]
https://lists.sourceforge.net/lists/listinfo/rpy-list