A decorator that compiles C/C++ functions with Clang in Python
Like Numba, but Jerry-built and pre-alpha :)
pip install cooodecooo
Tested against Windows 10 / Python 3.10 / Anaconda
Here are 2 examples:
Find RGB colors
import cv2
import numpy as np
from cooodecooo import ccoo
# The name of the variable needs to be `clangpath`, if you change it, it won't work
clangpath = r"C:\Program Files\LLVM\bin\clang.exe"
# The names of the 2 functions (Python / C) need to be equal (colorsearch2 - colorsearch2)
@ccoo
def colorsearch2(**kwargs): # put here always **kwargs
# The variable that contains the C source code must be named - c_source_code -
c_source_code = r"""
__declspec(dllexport) void colorsearch2(unsigned char *pic, unsigned char *colors, int width, int totallengthpic, int totallengthcolor, int *outputx, int *outputy, int *lastresult) {
int counter = 0;
for (int i = 0; i <= totallengthcolor; i += 3) {
int r = i;
int g = i + 1;
int b = i + 2;
for (int j = 0; j <= totallengthpic; j += 3) {
if ((colors[r] == pic[j]) && (colors[g] == pic[j + 1]) && (colors[b] == pic[j + 2])) {
int dividend = j / 3;
int quotient = dividend / width;
int remainder = dividend % width;
int upcounter = counter;
outputx[upcounter] = quotient;
outputy[upcounter] = remainder;
lastresult[0] = upcounter;
counter++;
}
}
}
}
"""
# Where do you want to save the shared library? The name of the variable cannot be changed! It needs to be - c_save_path -
c_save_path = "cloop.so"
# That's it, no return value! Scroll down for more details.
def get_pixelcolor(pic, colors):
totallenghtpic = (pic.shape[0] * pic.shape[1] * pic.shape[2]) - 1
totallengthcolor = (colors.shape[0] * colors.shape[1]) - 1
outputx = np.zeros(totallenghtpic, dtype=np.int32)
outputy = np.zeros(totallenghtpic, dtype=np.int32)
lastresult = np.zeros(1, dtype=np.int32)
# Use the same signature as in the C function # unsigned char *pic, unsigned char *colors, int width, int totallengthpic, int totallengthcolor, int *outputx, int *outputy, int *lastresult
# Pointers only work when numpy arrays are passed to the function
varstopass = {
"pic": pic,
"colors": colors,
"width": pic.shape[1],
"totallengthpic": totallenghtpic,
"totallengthcolor": totallengthcolor,
"outputx": outputx,
"outputy": outputy,
"lastresult": lastresult,
}
# The compiled function doesn't return anything, it writes the results in given numpy arrays by using pointers
# In this example: outputx/outputy/lastresult
_ = colorsearch2(**varstopass)
return np.dstack([outputx[: lastresult[0] + 1], outputy[: lastresult[0] + 1]])[0]
picx = r"C:\Users\hansc\Downloads\pexels-alex-andrews-2295744.jpg"
pic = cv2.imread(picx)
colors = np.array(
[
(66, 71, 69),
(62, 67, 65),
(144, 155, 153),
(52, 57, 55),
(127, 138, 136),
(53, 58, 56),
(51, 56, 54),
(32, 27, 18),
(24, 17, 8),
],
dtype=np.uint8,
)
resu = get_pixelcolor(pic, colors)
Levenshtein Distance
import numpy as np
from cooodecooo import ccoo
clangpath = r"C:\Program Files\LLVM\bin\clang.exe"
@ccoo
def levenshtein_distance(**kwargs):
c_source_code = r"""
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int minim(int a, int b, int c)
{
int m = a;
if (b < m)
m = b;
if (c < m)
m = c;
return m;
}
__declspec(dllexport) void levenshtein_distance(char *s1, char *s2, int len1, int len2, int *resultsx)
{
//printf("%d %d\n", len1, len2);
int *d = (int *)malloc((len1 + 1) * (len2 + 1) * sizeof(int));
int i, j;
for (i = 0; i <= len1; i++)
d[i * (len2 + 1) + 0] = i;
for (j = 0; j <= len2; j++)
d[0 * (len2 + 1) + j] = j;
for (i = 1; i <= len1; i++)
{
for (j = 1; j <= len2; j++)
{
//printf("%c %c\n", s1[i - 1], s2[j - 1]);
//fflush(stdout);
int cost = (s1[i - 1] == s2[j - 1]) ? 0 : 1;
d[i * (len2 + 1) + j] = minim((d[(i - 1) * (len2 + 1) + j] + 1),
(d[i * (len2 + 1) + (j - 1)] + 1),
(d[(i - 1) * (len2 + 1) + (j - 1)] + cost));
}
}
resultsx[0] = d[len1 * (len2 + 1) + len2];
printf("%d\n", resultsx[0]);
free(d);
}
"""
c_save_path = "levete.so"
s01 = ("kitten").encode()
s02 = ("sitting").encode()
s1 = np.array(list(s01), dtype=np.uint8)
s2 = np.array(list(s02), dtype=np.uint8)
len1 = len(s1)
len2 = len(s2)
resultsx = np.array([0], dtype=np.int32)
_ = levenshtein_distance(s1=s1, s2=s2, len1=len1, len2=len2, resultsx=resultsx)
print(resultsx)
Metadata
Release files for cooodecooo 0.10
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| cooodecooo-0.10.tar.gz | 25.5 kB | Without provenance | Details for cooodecooo-0.10.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| cooodecooo-0.10-py3-none-any.whl | Python 3 | none | any | Details for cooodecooo-0.10-py3-none-any.whl |
Total release size: 51.8 kB
Release files / cooodecooo-0.10.tar.gz
| Download URL | cooodecooo-0.10.tar.gz |
|---|---|
| Size | 25.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
402fba6adcaba1750609e5eca2611848b8ae303f58676e141b639c8582cbe76a
|
|
BLAKE2b-256 checksum How to use checksums |
c95509555cf62d49c9f71fe4b2a0be0fdac9d3be5bf031e4e2f4271f2d945c76
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/4.0.2 CPython/3.10.10
|
Release files / cooodecooo-0.10-py3-none-any.whl
| Download URL | cooodecooo-0.10-py3-none-any.whl |
|---|---|
| Size | 26.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
d8d786990680242160939b50f75c146e8cc999857cae260d71974f9737b4f025
|
|
BLAKE2b-256 checksum How to use checksums |
ed13d56f63773154cec371b02975356fe2d0a2c45f5732c50c30c36a95233d53
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/4.0.2 CPython/3.10.10
|
Security for cooodecooo 0.10
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.