Thursday, August 5, 2021

Python Wrapper for C++ solving the recent YandexQ problem

 Problem itself

ABCDEF is a six-digit number. They are all different and are arranged from left to right in ascending order. The number is a complete square.

(.env) [boris@fedora33server VOICE]$ cat Strike.h

#pragma once

#include <cstddef>

#include <cstdio>

namespace abc {

    class Strike {

    public:

        double *mem;

        long fftSize;

        Strike(long fftSize);

        ~Strike();

        long filter(long freq);

        long CaughIt(int n);

    };

}

(.env) [boris@fedora33server VOICE]$ cat Strike.cpp

#include <cstdio>

#include <cstddef>

#include <string>

#include "Strike.h"

namespace abc

    Strike::Strike(long fftSize) {

        printf("c++ constructor of Strike\n");

        this->fftSize=fftSize;

        mem=new double[fftSize];

        } 

    Strike::~Strike() { delete [] mem; } 

    long Strike::filter(long freq) {

        printf("c++ Strike filter method\n");

        return (CaughIt(1000));

    }

    long Strike::CaughIt(int n) 

    { 

     for (int i=200; i < n; i++)

     {

     std::string ans = std::to_string(i*i);

      if ((int(ans[0])< int(ans[1])) && \ 

         (int(ans[1]) < int(ans[2])) && \

         (int(ans[2]) < int(ans[3])) && \

         (int(ans[3]) < int(ans[4])) && \

         (int(ans[4]) < int(ans[5])))    

             return (i*i);

     }

    }

}

(.env) [boris@fedora33server VOICE]$ cat strikeWrapper.cpp

#include <Python.h>

#include <cstdio>

#include <string.h>

#include "Strike.h"

using abc::Strike;

typedef struct {

    PyObject_HEAD

    Strike * ptrObj;

} PyStrike;

static PyModuleDef volumemodule = {

    PyModuleDef_HEAD_INIT,

    "volume",

    "Example module that wrapped a C++ object",

    -1,

    NULL, NULL, NULL, NULL, NULL

};

static int PyStrike_init(PyStrike *self, PyObject *args, PyObject *kwds)

// initialize PyStrike Object

{

    long fftSize;

    if (! PyArg_ParseTuple(args, "l", &fftSize))

        return -1;

    self->ptrObj=new Strike(fftSize);

    return 0;

}

static void PyStrike_dealloc(PyStrike * self)

// destruct the object

{

    delete self->ptrObj;

    Py_TYPE(self)->tp_free(self);

}

static PyObject * PyStrike_filter(PyStrike* self, PyObject* args)

{

    long freq;

    long retval;

    if (! PyArg_ParseTuple(args, "l", &freq))

        return Py_False;

    retval = (self->ptrObj)->filter(freq);

    return Py_BuildValue("l",retval);

}

static PyMethodDef PyStrike_methods[] = {

    { "filter", (PyCFunction)PyStrike_filter,METH_VARARGS,"filter the mem volume" },

    {NULL}  /* Sentinel */

};

static PyTypeObject PyStrikeType = { PyVarObject_HEAD_INIT(NULL, 0)

                                    "volume.Strike"   /* tp_name */

                                };

PyMODINIT_FUNC PyInit_volume(void)

// create the module

{

    PyObject* m;

    PyStrikeType.tp_new = PyType_GenericNew;

    PyStrikeType.tp_basicsize=sizeof(PyStrike);

    PyStrikeType.tp_dealloc=(destructor) PyStrike_dealloc;

    PyStrikeType.tp_flags=Py_TPFLAGS_DEFAULT;

    PyStrikeType.tp_doc="Strike objects";

    PyStrikeType.tp_methods=PyStrike_methods;

    //~ PyStrikeType.tp_members=Noddy_members;

    PyStrikeType.tp_init=(initproc)PyStrike_init;

    if (PyType_Ready(&PyStrikeType) < 0)

        return NULL;

    m = PyModule_Create(&volumemodule);

    if (m == NULL)

        return NULL;

    Py_INCREF(&PyStrikeType);

    PyModule_AddObject(m, "Strike", (PyObject *)&PyStrikeType); 

    return m;

}

(.env) [boris@fedora33server VOICE]$ cat setup.py

from distutils.core import setup, Extension

setup(name='volumePkg', version='1.0',  \

      ext_modules=[Extension('volume', ['strikeWrapper.cpp','Strike.cpp'])])

$ python setup.py install

running install

running build

running build_ext

building 'volume' extension

creating build

creating build/temp.linux-x86_64-3.9

gcc -pthread -Wno-unused-result -Wsign-compare -DDYNAMIC_ANNOTATIONS_ENABLED=1 -DNDEBUG -O2 -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fstack-protector-strong -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -D_GNU_SOURCE -fPIC -fwrapv -O2 -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fstack-protector-strong -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -D_GNU_SOURCE -fPIC -fwrapv -O2 -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fstack-protector-strong -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -D_GNU_SOURCE -fPIC -fwrapv -fPIC -I/home/boris/VOICE/.env/include -I/usr/include/python3.9 -c Strike.cpp -o build/temp.linux-x86_64-3.9/Strike.o

gcc -pthread -Wno-unused-result -Wsign-compare -DDYNAMIC_ANNOTATIONS_ENABLED=1 -DNDEBUG -O2 -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fstack-protector-strong -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -D_GNU_SOURCE -fPIC -fwrapv -O2 -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fstack-protector-strong -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -D_GNU_SOURCE -fPIC -fwrapv -O2 -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fstack-protector-strong -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -D_GNU_SOURCE -fPIC -fwrapv -fPIC -I/home/boris/VOICE/.env/include -I/usr/include/python3.9 -c strikeWrapper.cpp -o build/temp.linux-x86_64-3.9/strikeWrapper.o

creating build/lib.linux-x86_64-3.9

g++ -pthread -shared -Wl,-z,relro -Wl,--as-needed -Wl,-z,now -g -Wl,-z,relro -Wl,--as-needed -Wl,-z,now -g build/temp.linux-x86_64-3.9/Strike.o build/temp.linux-x86_64-3.9/strikeWrapper.o -L/usr/lib64 -o build/lib.linux-x86_64-3.9/volume.cpython-39-x86_64-linux-gnu.so

running install_lib

copying build/lib.linux-x86_64-3.9/volume.cpython-39-x86_64-linux-gnu.so -> /home/boris/VOICE/.env/lib64/python3.9/site-packages

running install_egg_info

Removing /home/boris/VOICE/.env/lib64/python3.9/site-packages/volumePkg-1.0-py3.9.egg-info

Writing /home/boris/VOICE/.env/lib64/python3.9/site-packages/volumePkg-1.0-py3.9.egg-info



A