Extension of Python by C or C ++ (when there are multiple arguments, when passing a list from the Python side)

I made a little bit of it myself, so make a note

It was used when running a genetic algorithm. I feel better. .. .. As a bonus, I made a simple decimal-binary conversion and Gray code conversion. It's easy to use bitstring, but with the meaning of practice.

First of all, C code (part). The indentation is broken, but I wrote the same process many times, but the naming convention is random, but as a starting point. It's a little long, but it's the same.

By the way, I passed the List from the Python side and received it on the C side. Program is difficult ...

Reference (mainly API related) http://stackoverflow.com/questions/5079570/writing-a-python-c-extension-how-to-correctly-load-a-pylistobject

http://rokujyouhitoma.hatenablog.com/entry/20100704/1278216557

http://www.hexacosa.net/documents/python-extending/

Reference (bit operation, etc.) http://saeki-ce.xsrv.jp/index.html

Other wiki etc.

cbinary.c


#include <Python.h>

#define LOWER_BOUND    0
#define UPPER_BOUND    1000
#define MAX_BIT_LENGTH 10

int binaryToValue(int *);

static PyObject *
valueToGray(PyObject *self, PyObject *args)
{
  //return gray code
  int i, n, m, len;
  unsigned int num;
  int b[MAX_BIT_LENGTH];
  PyListObject *binary;
  binary = (PyListObject *) PyList_New(MAX_BIT_LENGTH);

  if (!PyArg_ParseTuple(args, "i", &num)){
    return NULL;
  }
  n = (num >> 1) ^ num; //Convert to gray code

  //Convert to binary
  for (i=0; n>0; i++){
    m=n%2;   //Divided by 2
    n=n/2;  //Divide by 2
    b[i] = m;
  }

  len = i; //Length when converted to binary number of integer

  //Add 0 to Niketsu so that it becomes 10bit
  for (i=len; i<MAX_BIT_LENGTH; i++ ){
    b[i] = 0;
  }
 
  //Copy the bit string that was in reverse order in binary order
  n = 0;
  for (i=MAX_BIT_LENGTH-1; i>=0; i--){
  //Put an int type value in gray one bit at a time
    PyList_SET_ITEM(binary, n++, Py_BuildValue("i", b[i]));
  }

  return Py_BuildValue("O", binary);
}


static PyObject *
make_individual(PyObject *self, PyObject *args)
{

  int b[MAX_BIT_LENGTH];
  int m,n,i,len;
  unsigned int min, max;
  unsigned int random_int;
  unsigned int gray_int;

  PyListObject *gray; //Representing a python list object
  gray = (PyListObject *) PyList_New(MAX_BIT_LENGTH); //Size is MAX~Make a list of

  if (!PyArg_ParseTuple(args, "ii", &min, &max)){ //When there are multiple arguments, write them side by side like ii
    return NULL;
  }

  if (min < LOWER_BOUND){
    exit(0);
  }
  else if (max > UPPER_BOUND){
    exit(0);
  }
  //Randomly generate an integer
  random_int = min + (int)(rand()*(max-min+1.0)/(1.0+RAND_MAX));
  gray_int = (random_int >> 1) ^ random_int; //Convert to gray code

  n = gray_int;
  //Convert to binary
  for (i=0; n>0; i++){
    m=n%2;   //Divided by 2
    n=n/2;  //Divide by 2
    b[i] = m;
  }

  len = i; //Length when converted to binary number of integer

  //Add 0 to Niketsu so that it becomes 10bit
  for (i=len; i<MAX_BIT_LENGTH; i++ ){
    b[i] = 0;
  }
 
  //Copy the bit string that was in reverse order in binary order
  n = 0;
  for (i=MAX_BIT_LENGTH-1; i>=0; i--){
  //Put an int type value in gray one bit at a time
    PyList_SET_ITEM(gray, n++, Py_BuildValue("i", b[i]));
  }

  return Py_BuildValue("O", gray);
}

static PyObject *
grayToBinary(PyObject *self, PyObject *args)
{

  unsigned int num;
  unsigned int mask;
  int m,n,i,len;
  int b[MAX_BIT_LENGTH], inputed_binary[MAX_BIT_LENGTH];
  PyListObject *binary; //Representing a python list object
  PyObject *get_list;
  binary = (PyListObject *) PyList_New(MAX_BIT_LENGTH); 

  if (!PyArg_ParseTuple(args, "O", &get_list )){
    return NULL;
  }
  if PyList_Check(get_list) {
      for (i=0; i<PyList_Size(get_list); i++){
	//Extract the contents of the list object while converting it so that it can be seen in C?(No confidence)
	inputed_binary[i] = PyInt_AsSsize_t(PyList_GetItem(get_list, (Py_ssize_t)i)); //ok
      }
    }
  
  num = binaryToValue(inputed_binary);
  
  for (mask = num >> 1; mask != 0; mask = mask >> 1){
    //Undo from gray code
    num = num ^ mask;
  }
  
  n = num;
  //Convert to binary
  for (i=0; n>0; i++){
    m=n%2;   //Divided by 2
    n=n/2;  //Divide by 2
    b[i] = m;
  }

  len = i; //Length when converted to binary number of integer

  //Add 0 to Niketsu so that it becomes 10bit
  for (i=len; i<MAX_BIT_LENGTH; i++ ){
    b[i] = 0;
  }
  
  //Copy the bit string that was in reverse order in binary order
  n = 0;
  for (i=MAX_BIT_LENGTH-1; i>=0; i--){
    //Put an int type value in binary one bit at a time
    PyList_SET_ITEM(binary, n++, Py_BuildValue("i", b[i]));
  }

  return Py_BuildValue("O", binary);
}


int binaryToValue(int *b){
  //Convert a binary number to an integer
  int i,n;
  i=0; n=0;

  while(i < MAX_BIT_LENGTH){
    if (b[i] == 1) n+=1;
    i+=1;
    if (i == MAX_BIT_LENGTH) break;
    n=n*2;
    //printf("%d\n", n);
  }
  return n;
}

static PyObject *
binaryToPtype(PyObject *self, PyObject *args)
{

  int i,n;
  int inputed_binary[MAX_BIT_LENGTH];
  PyListObject *binary; //Representing a python list object
  PyObject *get_list;

  if (!PyArg_ParseTuple(args, "O", &get_list )){ //Pass the python object as is
    return NULL;
  }
  
  if PyList_Check(get_list) {
      for (i=0; i<PyList_Size(get_list); i++){
	inputed_binary[i] = PyInt_AsSsize_t(PyList_GetItem(get_list, (Py_ssize_t)i)); //ok
      }
    }
  
  i=0; n=0;

  while(i < MAX_BIT_LENGTH){
    if (inputed_binary[i] == 1) n+=1;
    i+=1;
    if (i == MAX_BIT_LENGTH) break;
    n=n*2;
    //printf("%d\n", n);
  }
  return Py_BuildValue("i", n);
}


static PyObject *
hello(PyObject *self)
{
    printf("Hello World!!\n");
    Py_RETURN_NONE;
}

static char ext_doc[] = "C extention module example\n";

static PyMethodDef methods[] = {
  {"hello", (PyCFunction)hello, METH_NOARGS, "print hello world.\n"},
  {"value_to_gray", valueToGray, METH_VARARGS, "return gray obj.\n"},
  {"make_individual", make_individual, METH_VARARGS, "return gray code.\n"},
  {"gray_to_binary", grayToBinary, METH_VARARGS, "return binary code.\n"},
  {"binary_to_ptype", binaryToPtype, METH_VARARGS, "return ptype value.\n"},
  {NULL, NULL, 0, NULL}
};

void initcbinarymethods(void)
{
    Py_InitModule3("cbinarymethods", methods, ext_doc);
}

As usual? Write setup.py.

setup.py


from distutils.core import setup, Extension

module1 = Extension('cbinarymethods',
                    sources = ['cbinary.c'])

setup (name = 'cbinarymethods',
       version = '1.0',
       description = 'This is a demo package',
       ext_modules = [module1])

Again, build on the command line as usual.

$ python setup.py build_ext --inplace #--Add in place to make it current.It seems that so can be done

If you can build successfully, you have cbinarymethods.so.

Let's import it with python and use it

>>> import cbinarymethods as cbm
>>> i = cbm.make_individual(200, 250)
>>> i
[0, 0, 1, 0, 0, 0, 1, 0, 1, 1]
>>> a = cbm.gray_to_binary([0,0,1,0,1,0,0,1,0,1])
>>> a
[0, 0, 1, 1, 0, 0, 0, 1, 1, 0]

Recommended Posts

Extension of Python by C or C ++ (when there are multiple arguments, when passing a list from the Python side)
Python points from the perspective of a C programmer
[Python] Display only the elements of the list side by side [Vertical, horizontal]
Pass a list by reference from Python to C ++ with pybind11
How to write a string when there are multiple lines in python
Make a copy of the list in Python
[Python] Solution to the problem that elements are linked when copying a list
"Cython" tutorial to make Python explosive: Handling when a function on the C ++ side is passed by reference.
Sort tuple list in Python by specifying the ascending / descending order of multiple keys
Get the value of a specific key in a list from the dictionary type in the list with Python
How to write a string when there are multiple lines in python
Python classes are slow
Half-width katakana characters are not garbled when using python + selenium execute_script
Extension of Python by C or C ++ (when there are multiple arguments, when passing a list from the Python side)
Creating an alias (when there are multiple arguments) [Comparison between Bash and PowerShell]
How python classes and magic methods are working.
[Python] Ravel () is convenient when drawing multiple graphs
I can't click the Selenium checkbox Python VBA
Multiple graphs are displayed in one window (python)
What are you using when testing with Python?
Group by consecutive elements of a list in Python
There are two interpretations of VBScript a = b = c
A library that monitors the life and death of other machines by pinging from Python
Python> Get a list of files in multiple directories> Use glob | Sort by modification time
__init__ called by wxPython or Tkinter was a __init__ call of the inheriting class in Python
When I created an ECR scan from a CDK, I could see the back side of the scan
Not surprisingly known! ?? What about the arguments of built-in functions? What school are you from? [Python]
[Python] How to make a list of character strings character by character
Different from the import type of python. from A import B meaning
Add a list of numpy library functions little by little --c
Get the number of specific elements in a python list
Points to note when deleting multiple elements from the List
Python: Create a dictionary from a list of keys and values
Extract the value of dict or list as a string
Extract the value closest to a value from a Python list element
"Cython" tutorial to make Python explosive: When a function on the C ++ side has an overload.
[Python] A program that compares each element of list one by one and wins or loses. zip ()
[Python] How to use the for statement. A method of extracting by specifying a range or conditions.
python Note: Determine if command line arguments are in the list
Format when passing a long string as an argument of python
Precautions when using a list or dictionary as the default argument
Read the standard output of a subprocess line by line in Python
[Python] Get the update date of a news article from HTML
When you want to sort a multidimensional list by multiple lines
List of disaster dispatches from the Sapporo City Fire Department [Python]
[Python] A program that rotates the contents of the list to the left
Existence from the viewpoint of Python
python / Make a dict from a list.
About the basics list of Python basics
[AtCoder explanation] Control the A, B, C problems of ABC182 with Python!
[Introduction to Python] How to sort the contents of a list efficiently with list sort
[Python memo] Be careful when creating a two-dimensional array (list of lists)
[AtCoder explanation] Control the A, B, C problems of ABC185 with Python!
Receive a list of the results of parallel processing in Python with starmap
[AtCoder explanation] Control the A, B, C problems of ABC187 with Python!
How to format a list of dictionaries (or instances) well in Python
From a book that makes the programmer's way of thinking interesting (Python)
[AtCoder explanation] Control the A, B, C problems of ABC184 with Python!
Try to find the probability that it is a multiple of 3 and not a multiple of 5 when one is removed from a card with natural numbers 1 to 100 using Ruby and Python.