Detecting all prime numbers in given range is supposed to be performed by C++ code below as a procedure invoked from Python. Tested with both Python 3.9.5 and Python 3.10 (beta) via Python API. Refactoring code proposed in python-cpp-extension @github
Vectors are part of STL. Vectors in C++ are sequence containers representing arrays that can change their size during runtime . They use contiguous storage locations for their elements just as efficiently as in arrays, which means that their elements can also be accessed using offsets on regular pointers to its elements.
Procedure primesList(int lim_down,int lim_up) has type of std::vector<int> and accept 2 parameters rather then 1 in original version. Logic itself of primesList is different from the one implemented in "sieve_of_eratosthenes" in original code.
#include <vector>
#include <cstddef>
namespace xps {
std::vector<int> primesList(int lim_down,int lim_up) ;} // namespace xps
(.env) [boris@sever33fedora PRIMESPLUS]$ cat test.cpp
#include <Python.h>
#include <iostream>
#include "test.h"
namespace xps {
std::vector<int> primesList(int lim_down,int lim_up)
{
std::vector<int> result;
int i,prime,n;
for(n=lim_down; n <= lim_up; n++)
{
prime = 1;
for(i=2; i<n; i++)
if(n%i == 0)
{
prime = 0;
break;
}
if(prime)
{
result.push_back(n);
}
}
return result;
}
} //namespace
// Our Python binding to our C function
// This will take two non-keyword arguments
extern "C"{}
namespace {
static PyObject *primes(PyObject* self, PyObject* args)
{
// PyArg_ParseTuple accepts two integer arguments
// to obtain all prime numbers between "k" and "m"
int m,k;
if(!PyArg_ParseTuple(args,"ii",&k,&m))
return NULL;
std::vector<int> primes = xps::primesList(k,m);
PyObject* result = PyList_New(primes.size());
for(int i = 0; i < primes.size(); i++) {
PyList_SetItem(result, i, PyLong_FromLong(primes[i]));
}
return result;
}
// Our Module's Function Definition struct
// We require this `NULL` to signal the end of our method
// definition
static PyMethodDef myMethods[] = {
{ "primes", primes, METH_VARARGS, "Calculate prime numbers" },
{ NULL, NULL, 0, NULL }
};
// Our Module Definition struct
static struct PyModuleDef myModule = {
PyModuleDef_HEAD_INIT,
"myModule",
"Test Module",
-1,
myMethods
};
// Initializes our module using our above struct
PyMODINIT_FUNC PyInit_myModule(void)
{
return PyModule_Create(&myModule);
};
} // namespace
(.env) [boris@sever33fedora PRIMESPLUS]$ cat setup.py
from distutils.core import setup, Extension
import sysconfig
language = 'c++'
std = 'c++20'
default_compile_args = sysconfig.get_config_var('CFLAGS').split()
extra_compile_args = [f"-std={std}", "-Wall", "-Wextra", "-Werror", "-DNDEBUG", "-O3"]
setup(name = 'myModule', version = '1.0', \
ext_modules = [Extension('myModule', ['test.cpp'])])
drwxrwxr-x. 4 boris boris 63 Jun 25 01:19 build
-rw-rw-r--. 1 boris boris 144 Jun 25 00:06 MyProgList.py
-rw-rw-r--. 1 boris boris 280 Jun 24 22:26 MyProg.py
-rw-rw-r--. 1 boris boris 348 Jun 24 21:32 setup.py
-rw-rw-r--. 1 boris boris 1690 Jun 25 01:17 test.cpp
-rw-rw-r--. 1 boris boris 145 Jun 25 01:14 test.h
import myModule
b = int(input("\nInput down limit :"))
a = int(input("\nInput upper limit : "))
print(myModule.primes(b,a))
(.env) [boris@sever33fedora PRIMESPLUS]$ python3.10 MyProgList.py
Input down limit :100
Input upper limit : 500
[101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191
, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 28
3, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 4
01, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499]
No comments:
Post a Comment