3

In my module there is a method that takes python list and divides it by double

static PyObject *st_div_r(PyObject *self, PyObject *args){
  PyObject *pList;

  Py_ssize_t n;
  double x;
  int i;

  if (!PyArg_ParseTuple(args, "O!d", &PyList_Type, &pList, &x)) {
    PyErr_SetString(PyExc_TypeError, "parameters are wrong.");
    return NULL;
    }



  n = PyList_Size(pList);
  for(i=0;i<n;i++)
  {
    PyList_SetItem(pList,i,Py_BuildValue("d",PyFloat_AsDouble(PyList_GetItem(pList,i))/x));
        };
  Py_INCREF(pList);
  return pList;
}

It works like this

my_mod.st_div_r([1,2,3],0.5)
[2,4,6]

I would like to use st_div_r in another method in my module, that takes list of lists, divides it's first element by double and returns it

static PyObject *det(PyObject *self, PyObject *args){ 
  PyObject *pList;
  double d = 2.0;

  if (!PyArg_ParseTuple(args, "O!", &PyList_Type, &pList)) {
    PyErr_SetString(PyExc_TypeError, "parameters are  wrong.");
    return NULL;
    }


  PyList_SetItem(pList,0,st_div_r(pList,(PyList_GetItem(pList,0),Py_BuildValue("d",d))));

  Py_INCREF(pList);


  return pList;
}

It should work like this

my_mod.det([[1,2],[3,4]])
[[0.5,1],[3,4]]

But this doesn't work

 TypeError: parameters are wrong

So, the question is how to call st_div_r inside det and what to pass as self. Would appreciate any help. Thank you

1 Answer 1

3

You must create a PyTuple as second argument of your own function(st_div_r)!

There are 2 main ways to do that!

First Way

PyObject *first_list = PyList_GetItem(pList, 0)
//PyObject *divider = Py_BuildValue("d", d)

//PyObject *tuple_with_list_and_divider = Py_BuildValue("(Od)", first_list, divider);

PyObject *tuple_with_list_and_divider = Py_BuildValue("(Od)", first_list, d);

PyObject *list_after_division = st_div_r(pList, tuple_with_list_and_divider)

PyList_SetItem(pList , 0, list_after_division);

Second Way

PyObject *first_list = PyList_GetItem(pList, 0)
PyObject *divider = Py_BuildValue("d", d)

PyObject *tuple_with_list_and_divider = PyTuple_New(2);

PyTuple_SetItem(tuple_with_list_and_divider, 0, first_list);
PyTuple_SetItem(tuple_with_list_and_divider, 1, divider);

PyObject *list_after_division = st_div_r(pList, tuple_with_list_and_divider)

PyList_SetItem(pList , 0, list_after_division);

In first example I forgot that Py_BuildValue converts d to Py_Double.

Sorry for my Bad English!

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks! The second way works well, the first way gives [[inf, inf], [3, 4]]
The first way did be PyObject *tuple_with_list_and_divider = Py_BuildValue("(Od)", first_list, d); I think. @alehax if you had any error checking in your code you would probably get a more sensible message.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.