From: ageay Date: Thu, 1 Mar 2012 12:30:52 +0000 (+0000) Subject: Some little improvements in python ergonomy for DataArrays. X-Git-Tag: V6_main_FINAL~806 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=f434712159eb78d256bdfbc413effbab818811d3;p=tools%2Fmedcoupling.git Some little improvements in python ergonomy for DataArrays. --- diff --git a/src/MEDCoupling/MEDCouplingMemArray.cxx b/src/MEDCoupling/MEDCouplingMemArray.cxx index ce1bb6810..adc01bd70 100644 --- a/src/MEDCoupling/MEDCouplingMemArray.cxx +++ b/src/MEDCoupling/MEDCouplingMemArray.cxx @@ -353,6 +353,25 @@ void DataArrayDouble::setInfoAndChangeNbOfCompo(const std::vector& _info_on_compo=info; } +/*! + * This method returns the only one value in 'this', if and only if number of elements (nb of tuples * nb of components) is equal to 1, and that 'this' is allocated. + * If one or more conditions is not fulfilled an exception will be thrown. + */ +double DataArrayDouble::doubleValue() const throw(INTERP_KERNEL::Exception) +{ + if(isAllocated()) + { + if(getNbOfElems()==1) + { + return *getConstPointer(); + } + else + throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is allocated but number of elements is not equal to 1 !"); + } + else + throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is not allocated !"); +} + /*! * This method should be called on an allocated DataArrayDouble instance. If not an exception will be throw ! * This method checks the number of tupes. If it is equal to 0, it returns true, if not false is returned. @@ -2519,12 +2538,17 @@ void DataArrayDouble::finishUnserialization(const std::vector& tinyInfoI, c } } -DataArrayDoubleIterator::DataArrayDoubleIterator(DataArrayDouble *da):_da(da),_tuple(new DataArrayDoubleTuple(da)),_tuple_id(0),_nb_tuple(0) +DataArrayDoubleIterator::DataArrayDoubleIterator(DataArrayDouble *da):_da(da),_tuple_id(0),_nb_comp(0),_nb_tuple(0) { if(_da) { _da->incrRef(); - _nb_tuple=da->getNumberOfTuples(); + if(_da->isAllocated()) + { + _nb_comp=da->getNumberOfComponents(); + _nb_tuple=da->getNumberOfTuples(); + _pt=da->getPointer(); + } } } @@ -2532,7 +2556,6 @@ DataArrayDoubleIterator::~DataArrayDoubleIterator() { if(_da) _da->decrRef(); - delete _tuple; } DataArrayDoubleTuple *DataArrayDoubleIterator::nextt() @@ -2540,26 +2563,18 @@ DataArrayDoubleTuple *DataArrayDoubleIterator::nextt() if(_tuple_id<_nb_tuple) { _tuple_id++; - _tuple->next(); - return _tuple; + DataArrayDoubleTuple *ret=new DataArrayDoubleTuple(_pt,_nb_comp); + _pt+=_nb_comp; + return ret; } else return 0; } -DataArrayDoubleTuple::DataArrayDoubleTuple(DataArrayDouble *da):_pt(0),_nb_of_compo(0) +DataArrayDoubleTuple::DataArrayDoubleTuple(double *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp) { - if(da) - { - _nb_of_compo=da->getNumberOfComponents(); - _pt=da->getPointer()-_nb_of_compo; - } } -void DataArrayDoubleTuple::next() -{ - _pt+=_nb_of_compo; -} std::string DataArrayDoubleTuple::repr() const { @@ -2570,6 +2585,13 @@ std::string DataArrayDoubleTuple::repr() const return oss.str(); } +double DataArrayDoubleTuple::doubleValue() const throw(INTERP_KERNEL::Exception) +{ + if(_nb_of_compo==1) + return *_pt; + throw INTERP_KERNEL::Exception("DataArrayDoubleTuple::doubleValue : DataArrayDoubleTuple instance has not exactly 1 component -> Not possible to convert it into a double precision float !"); +} + DataArrayInt *DataArrayInt::New() { return new DataArrayInt; @@ -2608,6 +2630,25 @@ void DataArrayInt::setInfoAndChangeNbOfCompo(const std::vector& inf _info_on_compo=info; } +/*! + * This method returns the only one value in 'this', if and only if number of elements (nb of tuples * nb of components) is equal to 1, and that 'this' is allocated. + * If one or more conditions is not fulfilled an exception will be thrown. + */ +int DataArrayInt::intValue() const throw(INTERP_KERNEL::Exception) +{ + if(isAllocated()) + { + if(getNbOfElems()==1) + { + return *getConstPointer(); + } + else + throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is allocated but number of elements is not equal to 1 !"); + } + else + throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is not allocated !"); +} + /*! * This method should be called on an allocated DataArrayInt instance. If not an exception will be throw ! * This method checks the number of tupes. If it is equal to 0, it returns true, if not false is returned. @@ -4834,12 +4875,17 @@ void DataArrayInt::finishUnserialization(const std::vector& tinyInfoI, cons } } -DataArrayIntIterator::DataArrayIntIterator(DataArrayInt *da):_da(da),_tuple(new DataArrayIntTuple(da)),_tuple_id(0),_nb_tuple(0) +DataArrayIntIterator::DataArrayIntIterator(DataArrayInt *da):_da(da),_tuple_id(0),_nb_comp(0),_nb_tuple(0),_pt(0) { if(_da) { _da->incrRef(); - _nb_tuple=da->getNumberOfTuples(); + if(_da->isAllocated()) + { + _nb_comp=da->getNumberOfComponents(); + _nb_tuple=da->getNumberOfTuples(); + _pt=da->getPointer(); + } } } @@ -4847,7 +4893,6 @@ DataArrayIntIterator::~DataArrayIntIterator() { if(_da) _da->decrRef(); - delete _tuple; } DataArrayIntTuple *DataArrayIntIterator::nextt() @@ -4855,25 +4900,16 @@ DataArrayIntTuple *DataArrayIntIterator::nextt() if(_tuple_id<_nb_tuple) { _tuple_id++; - _tuple->next(); - return _tuple; + DataArrayIntTuple *ret=new DataArrayIntTuple(_pt,_nb_comp); + _pt+=_nb_comp; + return ret; } else return 0; } -DataArrayIntTuple::DataArrayIntTuple(DataArrayInt *da):_pt(0),_nb_of_compo(0) +DataArrayIntTuple::DataArrayIntTuple(int *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp) { - if(da) - { - _nb_of_compo=da->getNumberOfComponents(); - _pt=da->getPointer()-_nb_of_compo; - } -} - -void DataArrayIntTuple::next() -{ - _pt+=_nb_of_compo; } std::string DataArrayIntTuple::repr() const @@ -4884,3 +4920,10 @@ std::string DataArrayIntTuple::repr() const oss << _pt[_nb_of_compo-1] << ")"; return oss.str(); } + +int DataArrayIntTuple::intValue() const throw(INTERP_KERNEL::Exception) +{ + if(_nb_of_compo==1) + return *_pt; + throw INTERP_KERNEL::Exception("DataArrayIntTuple::intValue : DataArrayIntTuple instance has not exactly 1 component -> Not possible to convert it into an integer !"); +} diff --git a/src/MEDCoupling/MEDCouplingMemArray.hxx b/src/MEDCoupling/MEDCouplingMemArray.hxx index 3fb4d1952..aadcca145 100644 --- a/src/MEDCoupling/MEDCouplingMemArray.hxx +++ b/src/MEDCoupling/MEDCouplingMemArray.hxx @@ -138,6 +138,7 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT bool isAllocated() const; MEDCOUPLING_EXPORT void checkAllocated() const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void setInfoAndChangeNbOfCompo(const std::vector& info) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT double doubleValue() const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT bool empty() const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayDouble *deepCpy() const; MEDCOUPLING_EXPORT DataArrayDouble *performCpy(bool deepCpy) const; @@ -284,20 +285,21 @@ namespace ParaMEDMEM DataArrayDoubleTuple *nextt(); private: DataArrayDouble *_da; - DataArrayDoubleTuple *_tuple; + double *_pt; int _tuple_id; + int _nb_comp; int _nb_tuple; }; class MEDCOUPLING_EXPORT DataArrayDoubleTuple { public: - DataArrayDoubleTuple(DataArrayDouble *da); - void next(); + DataArrayDoubleTuple(double *pt, int nbOfComp); std::string repr() const; int getNumberOfCompo() const { return _nb_of_compo; } const double *getConstPointer() const { return _pt; } double *getPointer() { return _pt; } + double doubleValue() const throw(INTERP_KERNEL::Exception); private: double *_pt; int _nb_of_compo; @@ -312,6 +314,7 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT bool isAllocated() const; MEDCOUPLING_EXPORT void checkAllocated() const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void setInfoAndChangeNbOfCompo(const std::vector& info) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT int intValue() const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT bool empty() const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayInt *deepCpy() const; MEDCOUPLING_EXPORT DataArrayInt *performCpy(bool deepCpy) const; @@ -455,20 +458,21 @@ namespace ParaMEDMEM DataArrayIntTuple *nextt(); private: DataArrayInt *_da; - DataArrayIntTuple *_tuple; + int *_pt; int _tuple_id; + int _nb_comp; int _nb_tuple; }; class MEDCOUPLING_EXPORT DataArrayIntTuple { public: - DataArrayIntTuple(DataArrayInt *da); - void next(); + DataArrayIntTuple(int *pt, int nbOfComp); std::string repr() const; int getNumberOfCompo() const { return _nb_of_compo; } const int *getConstPointer() const { return _pt; } int *getPointer() { return _pt; } + int intValue() const throw(INTERP_KERNEL::Exception); private: int *_pt; int _nb_of_compo; diff --git a/src/MEDCoupling_Swig/MEDCoupling.i b/src/MEDCoupling_Swig/MEDCoupling.i index 63ebd1c16..d776bf0da 100644 --- a/src/MEDCoupling_Swig/MEDCoupling.i +++ b/src/MEDCoupling_Swig/MEDCoupling.i @@ -299,11 +299,11 @@ using namespace INTERP_KERNEL; %ignore ParaMEDMEM::MEDCouplingGaussLocalization::fillWithValues; %ignore ParaMEDMEM::MEDCouplingGaussLocalization::buildNewInstanceFromTinyInfo; %ignore ParaMEDMEM::DataArrayIntIterator::nextt; -%ignore ParaMEDMEM::DataArrayIntTuple::next; %ignore ParaMEDMEM::DataArrayIntTuple::repr; +%ignore ParaMEDMEM::DataArrayIntTuple::intValue; %ignore ParaMEDMEM::DataArrayDoubleIterator::nextt; -%ignore ParaMEDMEM::DataArrayDoubleTuple::next; %ignore ParaMEDMEM::DataArrayDoubleTuple::repr; +%ignore ParaMEDMEM::DataArrayDoubleTuple::doubleValue; %ignore ParaMEDMEM::DataArrayDouble::writeVTK; %ignore ParaMEDMEM::DataArrayInt::writeVTK; %ignore ParaMEDMEM::DataArrayDouble::SetArrayIn; @@ -1629,7 +1629,7 @@ namespace ParaMEDMEM { DataArrayDoubleTuple *ret=self->nextt(); if(ret) - return SWIG_NewPointerObj(SWIG_as_voidptr(ret),SWIGTYPE_p_ParaMEDMEM__DataArrayDoubleTuple,0|0); + return SWIG_NewPointerObj(SWIG_as_voidptr(ret),SWIGTYPE_p_ParaMEDMEM__DataArrayDoubleTuple,SWIG_POINTER_OWN|0); else { PyErr_SetString(PyExc_StopIteration,"No more data."); @@ -1644,6 +1644,11 @@ namespace ParaMEDMEM { return self->repr(); } + + double __float__() const throw(INTERP_KERNEL::Exception) + { + return self->doubleValue(); + } PyObject *__getitem__(PyObject *obj) throw(INTERP_KERNEL::Exception) { @@ -1868,6 +1873,23 @@ namespace ParaMEDMEM return self->repr(); } + double __float__() const throw(INTERP_KERNEL::Exception) + { + return self->doubleValue(); + } + + int __len__() const throw(INTERP_KERNEL::Exception) + { + if(self->isAllocated()) + { + return self->getNumberOfTuples(); + } + else + { + throw INTERP_KERNEL::Exception("DataArrayDouble::__len__ : Instance is NOT allocated !"); + } + } + DataArrayDoubleIterator *__iter__() { return self->iterator(); @@ -2951,6 +2973,11 @@ namespace ParaMEDMEM { return self->repr(); } + + int __int__() const throw(INTERP_KERNEL::Exception) + { + return self->intValue(); + } PyObject *__getitem__(PyObject *obj) throw(INTERP_KERNEL::Exception) { @@ -3175,7 +3202,7 @@ namespace ParaMEDMEM { DataArrayIntTuple *ret=self->nextt(); if(ret) - return SWIG_NewPointerObj(SWIG_as_voidptr(ret),SWIGTYPE_p_ParaMEDMEM__DataArrayIntTuple,0|0); + return SWIG_NewPointerObj(SWIG_as_voidptr(ret),SWIGTYPE_p_ParaMEDMEM__DataArrayIntTuple,SWIG_POINTER_OWN | 0); else { PyErr_SetString(PyExc_StopIteration,"No more data."); @@ -3195,9 +3222,7 @@ namespace ParaMEDMEM { if(self->isAllocated()) { - if(self->getNumberOfComponents()==1) - return self->getNumberOfTuples(); - throw INTERP_KERNEL::Exception("DataArrayInt::__len__ : len is not defined here because number of components is not equal to 1 !"); + return self->getNumberOfTuples(); } else { @@ -3205,6 +3230,11 @@ namespace ParaMEDMEM } } + int __int__() const throw(INTERP_KERNEL::Exception) + { + return self->intValue(); + } + DataArrayIntIterator *__iter__() { return self->iterator(); diff --git a/src/MEDCoupling_Swig/MEDCouplingBasicsTest.py b/src/MEDCoupling_Swig/MEDCouplingBasicsTest.py index 9005631de..d889e3c4a 100644 --- a/src/MEDCoupling_Swig/MEDCouplingBasicsTest.py +++ b/src/MEDCoupling_Swig/MEDCouplingBasicsTest.py @@ -6709,6 +6709,60 @@ class MEDCouplingBasicsTest(unittest.TestCase): self.assertEqual(da.getValues(),[7,7,7,3,8,8,7,7,7,9,14,20,12,17,26,7,7,7,18,23,38,21,26,44,24,29,70,27,32,76]) pass + def testSwigDAIOp3(self): + da=DataArrayInt.New() + self.assertRaises(InterpKernelException,da.__len__) + self.assertRaises(InterpKernelException,da.__int__) + for elt in da: + self.assertTrue(False) + pass + da.alloc(12,3) + da.rearrange(1) ; da.fillWithZero() + l1=list(da) + self.assertEqual(36,len(da)); + da.rearrange(3) + tmp=da[0] + self.assertRaises(InterpKernelException,tmp.__int__) + self.assertEqual(12,len(da)); + l=list(da) + for elt in enumerate(l): + elt[1][2]=elt[0] + pass + ref=[0,0,0,0,0,1,0,0,2,0,0,3,0,0,4,0,0,5,0,0,6,0,0,7,0,0,8,0,0,9,0,0,10,0,0,11] + self.assertEqual(ref,da.getValues()); + da.rearrange(1) + l=[int(elt) for elt in l1] + self.assertEqual(ref,da.getValues()); + self.assertEqual(11,int(da[-1:])) + pass + + def testSwigDADOp3(self): + da=DataArrayDouble.New() + self.assertRaises(InterpKernelException,da.__len__) + self.assertRaises(InterpKernelException,da.__float__) + for elt in da: + self.assertTrue(False) + pass + da.alloc(12,3) + da.rearrange(1) ; da.fillWithZero() + l1=list(da) + self.assertEqual(36,len(da)); + da.rearrange(3) + tmp=da[0] + self.assertRaises(InterpKernelException,tmp.__float__) + self.assertEqual(12,len(da)); + l=list(da) + for elt in enumerate(l): + elt[1][2]=elt[0] + pass + ref=[0.,0.,0.,0.,0.,1.,0.,0.,2.,0.,0.,3.,0.,0.,4.,0.,0.,5.,0.,0.,6.,0.,0.,7.,0.,0.,8.,0.,0.,9.,0.,0.,10.,0.,0.,11.] + self.assertEqual(ref,da.getValues()); + da.rearrange(1) + l=[float(elt) for elt in l1] + self.assertEqual(ref,da.getValues()); + self.assertEqual(11.,float(da[-1:])) + pass + def testSwigDataArrayIntIterator1(self): da=DataArrayInt.New() da.alloc(12,1)