analitics

Pages

Tuesday, May 5, 2026

News : Pythono and nuitka best optimization.

Nuitka is the optimizing Python compiler written in Python that creates executables that run without a separate installer. Data files can both be included or put alongside.
You can read more on the official website.
The install is easy with pip tool, then you can use this command.
python -m nuitka --help
Usage: python.exe -m nuitka [--mode=compilation_mode] [--run] [options] main_module.py

    Note: For general plugin help (they often have their own
    command line options too), consider the output of
    '--help-plugins'.

Options:
  --help                show this help message and exit
  --version             Show version information and important details for bug
                        reports, then exit. Defaults to off.
This python package need to have the Visual Studio Build Tools 2022 and need to use:
  • Desktop development with C++
  • MSVC v143 build tools
  • Windows 10/11 SDK
  • C++ CMake tools
  • C++ ATL/MFC (optional but useful)
Let's install it.
I used this simple example:
import sys
from PyQt6.QtWidgets import QApplication, QLabel, QWidget, QVBoxLayout

def main():
    app = QApplication(sys.argv)

    window = QWidget()
    window.setWindowTitle("PyQt6 + Nuitka Demo")

    layout = QVBoxLayout()
    label = QLabel("Hello! This is a PyQt6 application compiled with Nuitka.")
    layout.addWidget(label)

    window.setLayout(layout)
    window.show()

    sys.exit(app.exec())

if __name__ == "__main__":
    main()
Use this command to see all plugins:
nuitka --plugin-list
                 The following plugins are available in Nuitka
--------------------------------------------------------------------------------
 delvewheel        Required by 'delvewheel' using packages. (core)
 implicit-imports  Provide implicit imports of package as per package configuration files. (core) [auto-enabled]
 data-files        Include data files specified by package configuration files. (core, feature)
 dll-files         Include DLLs as per package configuration files. (core, feature)
 anti-bloat        Patch stupid imports out of widely used library modules source codes. (core, feature, package-support) [auto-enabled]
 options-nanny     Inform user about potential problems as per package configuration files. (core, package-support) [auto-enabled]
 pylint-warnings   Support PyLint / PyDev linting source markers. (feature)
 upx               Compress created binaries with UPX automatically. (integration)
 dill-compat       Required by 'dill' and 'cloudpickle' packages. (package-support) [has detector]
 eventlet          Required by 'eventlet' package. (package-support) [auto-enabled]
 gevent            Required by 'gevent' package. (package-support)
 gi                Required by 'gi' package. (package-support) [auto-enabled]
 glfw              Required by 'glfw' and 'PyOpenGL' packages. (package-support)
 kivy              Required by 'kivy' package. (package-support)
 matplotlib        Required by 'matplotlib' package. (package-support)
 multiprocessing   Required by 'multiprocessing' package. (package-support) [auto-enabled]
 no-qt             Disable inclusion of all Qt bindings. (package-support)
 pbr-compat        Required by 'pbr' package. (package-support)
 pkg-resources     Required by 'pkg_resources' package. (package-support) [auto-enabled]
 playwright        Required by 'playwright' package. (package-support)
 pmw-freezer       Required by 'Pmw' package. (package-support) [has detector]
 pywebview         Required by 'webview' package. (package-support)
 spacy             Required by 'spacy' package. (package-support)
 tk-inter          Required by 'tkinter' package. (package-support) [has detector]
 transformers      Required by 'transformers' package. (package-support) [auto-enabled]
 enum-compat       Required by 'enum' package on Python2. (package-support, python2)
 pyqt5             Required by 'PyQt5' package. (package-support, qt-binding) [has detector]
 pyqt6             Required by 'PyQt6' package. (package-support, qt-binding) [has detector]
 pyside2           Required by 'PySide2' package. (package-support, qt-binding) [has detector]
 pyside6           Required by 'PySide6' package. (package-support, qt-binding) [has detector]
... and standalone build process:
nuitka --standalone --enable-plugin=pyqt6 test_app.py
Nuitka-Options: Used command line options:
Nuitka-Options:   --standalone --enable-plugin=pyqt6 test_app.py
Nuitka-Plugins:pyqt6: Support for PyQt6 is not perfect, e.g. Qt threading does not work, so prefer
Nuitka-Plugins:pyqt6: PySide6 if you can.
Nuitka: Starting Python compilation with:
Nuitka:   Version '4.0.8' on Python 3.10 (flavor 'CPython Official')
Nuitka:   commercial grade 'not installed'.
Nuitka-Plugins:pyqt6: Including Qt plugins 'iconengines,imageformats,platforms,styles,tls' below
Nuitka-Plugins:pyqt6: 'PyQt6\Qt6\plugins'.
Nuitka: Completed Python level compilation and optimization.
Nuitka: Generating source code for C backend compiler.
Nuitka: Running data composer tool for optimal constant value handling.
Nuitka: Running C compilation via Scons.
Nuitka will use gcc from MinGW64 of winlibs to compile on Windows.

Is it OK to download and put it in local user cache.

Fully automatic, cached. Proceed and download? [Yes]/No :
Nuitka: Downloading
Nuitka: 'https://github.com/brechtsanders/winlibs_mingw/releases/download/14.2.0posix-19.1.1-12.0.0-msvcrt-r2/winlibs-x86_64-posix-seh-gcc-14.2.0-llvm-19.1.1-mingw-w64msvcrt-12.0.0-r2.zip'.
Nuitka: Extracting to
Nuitka: 'C:\Users\CATALI~1\AppData\Local\Nuitka\Nuitka\Cache\DOWNLO~1\gcc\x86_64\14.2.0posix-19.1.1-12.0.0-msvcrt-r2\mingw64\bin\gcc.exe'
Nuitka-Scons: Backend C compiler: gcc (gcc 14.2.0).
Nuitka-Scons: Backend C linking with 9 files (no progress information available for this stage).
Nuitka-Scons: Compiled 9 C files using ccache.
Nuitka-Scons: Cached C files (using ccache) with result 'cache miss': 9
Nuitka: Keeping build directory 'test_app.build'.
Nuitka: Successfully created 'C:\lucru\PyQt6\test_nuitka\test_app.dist\test_app.exe'.

Python Qt : python alias manager tool.

This script allow you to add alias commands on each python install.
NOTE : If this script find some python.exe and not works, it means that this python.exe is not a full Python installation, but only a launcher or an embedded runtime that is designed to run inside a virtual environment or a complete Python directory structure.
I used artificial intelligence, tested and works well, lets see the source code:
import sys
import os
import json
import subprocess
from PyQt6.QtWidgets import (
    QApplication, QWidget, QVBoxLayout, QPushButton,
    QTableWidget, QTableWidgetItem, QFileDialog, QMessageBox
)
from PyQt6.QtCore import Qt

CONFIG_FILE = "python_aliases.json"
ALIAS_DIR = os.path.join(os.environ["LOCALAPPDATA"], "Microsoft", "WindowsApps")

# ------------------------------
# Persistență JSON
# ------------------------------

def load_aliases():
    if os.path.isfile(CONFIG_FILE):
        try:
            with open(CONFIG_FILE, "r") as f:
                return json.load(f)
        except:
            return []
    return []

def save_aliases(data):
    with open(CONFIG_FILE, "w") as f:
        json.dump(data, f, indent=4)


# ------------------------------
# Detectare Python
# ------------------------------

def detect_where_python():
    """Detectează instalările Python folosind 'where python'."""
    found = []
    try:
        out = subprocess.check_output(["where", "python"], stderr=subprocess.STDOUT)
        lines = out.decode().splitlines()
        for line in lines:
            if line.lower().endswith("python.exe"):
                found.append(line.strip())
    except:
        pass
    return found


def search_python_in_folder_recursive(folder):
    """Caută python.exe în folder și în toate subfolderele recursiv."""
    found = []
    for root, dirs, files in os.walk(folder):
        if "python.exe" in files:
            found.append(os.path.join(root, "python.exe"))
    return found

# ------------------------------
# Detectare aliasuri existente
# ------------------------------

def detect_existing_aliases():
    """Caută aliasuri existente (*.cmd) în WindowsApps."""
    aliases = {}
    if not os.path.isdir(ALIAS_DIR):
        return aliases

    for file in os.listdir(ALIAS_DIR):
        if file.endswith(".cmd"):
            alias_name = file[:-4]
            cmd_path = os.path.join(ALIAS_DIR, file)

            try:
                with open(cmd_path, "r") as f:
                    line = f.readline().strip()
                    if line.startswith("@\"") and line.endswith("%*"):
                        python_path = line[2:-3].strip('"')
                        aliases[alias_name] = python_path
            except:
                pass

    return aliases

# ------------------------------
# Creare alias
# ------------------------------

def create_alias(alias_name, python_path):
    """Creează un fișier .cmd în WindowsApps pentru alias."""
    cmd_path = os.path.join(ALIAS_DIR, alias_name + ".cmd")

    try:
        with open(cmd_path, "w") as f:
            f.write(f'@"{python_path}" %*\n')
        return True
    except Exception as e:
        print("Eroare alias:", e)
        return False

# ------------------------------
# Interfață PyQt6
# ------------------------------

class PythonAliasManager(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Python Alias Manager – PyQt6")
        self.resize(800, 550)

        layout = QVBoxLayout(self)

        self.table = QTableWidget(0, 2)
        self.table.setHorizontalHeaderLabels(["Path Python", "Alias (editabil)"])
        self.table.horizontalHeader().setStretchLastSection(True)
        layout.addWidget(self.table)

        btn_detect = QPushButton("Detectează instalări (where python)")
        btn_detect.clicked.connect(self.detect_where)
        layout.addWidget(btn_detect)

        btn_add_folder = QPushButton("Adaugă folder custom (recursiv)")
        btn_add_folder.clicked.connect(self.add_folder)
        layout.addWidget(btn_add_folder)

        btn_search_folder = QPushButton("Caută python.exe recursiv în folder selectat")
        btn_search_folder.clicked.connect(self.search_folder)
        layout.addWidget(btn_search_folder)

        btn_aliases = QPushButton("Afișează aliasuri existente")
        btn_aliases.clicked.connect(self.show_existing_aliases)
        layout.addWidget(btn_aliases)

        btn_apply = QPushButton("Aplică aliasuri în Windows")
        btn_apply.clicked.connect(self.apply_aliases)
        layout.addWidget(btn_apply)

        self.data = load_aliases()
        self.refresh_table()

    # --------------------------
    # Tabel
    # --------------------------

    def refresh_table(self):
        self.table.setRowCount(0)
        for entry in self.data:
            row = self.table.rowCount()
            self.table.insertRow(row)

            self.table.setItem(row, 0, QTableWidgetItem(entry["path"]))

            alias_item = QTableWidgetItem(entry["alias"])
            alias_item.setFlags(alias_item.flags() | Qt.ItemFlag.ItemIsEditable)
            self.table.setItem(row, 1, alias_item)

    # --------------------------
    # Detectare instalări
    # --------------------------

    def detect_where(self):
        paths = detect_where_python()
        for p in paths:
            self.add_entry(p)
        self.refresh_table()
        save_aliases(self.data)

    def add_folder(self):
        folder = QFileDialog.getExistingDirectory(self, "Selectează folder Python")
        if folder:
            paths = search_python_in_folder_recursive(folder)
            for p in paths:
                self.add_entry(p)
            self.refresh_table()
            save_aliases(self.data)

    def search_folder(self):
        folder = QFileDialog.getExistingDirectory(self, "Selectează folder pentru scanare")
        if folder:
            paths = search_python_in_folder_recursive(folder)
            for p in paths:
                self.add_entry(p)
            self.refresh_table()
            save_aliases(self.data)

    # --------------------------
    # Aliasuri existente
    # --------------------------

    def show_existing_aliases(self):
        aliases = detect_existing_aliases()
        if not aliases:
            QMessageBox.information(self, "Aliasuri", "Nu există aliasuri în WindowsApps.")
            return

        msg = "\n".join([f"{a} → {p}" for a, p in aliases.items()])
        QMessageBox.information(self, "Aliasuri existente", msg)

    # --------------------------
    # Adăugare în listă
    # --------------------------

    def add_entry(self, path):
        if not any(e["path"] == path for e in self.data):
            alias = "python_" + os.path.basename(os.path.dirname(path)).replace(".", "_")
            self.data.append({"path": path, "alias": alias})

    # --------------------------
    # Aplicare aliasuri
    # --------------------------

    def apply_aliases(self):
        # actualizează aliasurile din tabel
        for row in range(self.table.rowCount()):
            self.data[row]["path"] = self.table.item(row, 0).text()
            self.data[row]["alias"] = self.table.item(row, 1).text()

        save_aliases(self.data)

        ok = 0
        for entry in self.data:
            if create_alias(entry["alias"], entry["path"]):
                ok += 1

        QMessageBox.information(
            self,
            "Aliasuri aplicate",
            f"Aliasuri create: {ok}\nAcum poți folosi comenzile în CMD/PowerShell."
        )

# ------------------------------
# Main
# ------------------------------

if __name__ == "__main__":
    app = QApplication(sys.argv)
    win = PythonAliasManager()
    win.show()
    sys.exit(app.exec())

News : the new python 3.15.0a8.

The Python programming language expected the new version 3.15.0a8 to come with this changelog and release date: XXXX-XX-XX.
Major features and changes
1. Interpreter and JIT optimizations
  • Much improved JIT with optimizations for int, float, list, and tuple operations.
  • Reduces redundant reference counting and adds new specializations (for example for enum.Enum and concatenations).
  • Supports unwinding JIT frames in GDB and GNU backtrace, and sets frame pointers for better profiling.
  • Free-threading improvements remove bottlenecks in sys.intern(), PyObject_SetAttr(), PyMutex, and PyDict_Watch(), improving multi-thread scaling.
  • Garbage collector returns to generational GC as the default and exposes new APIs for external GC monitoring.
  • Runtime optimizations reduce stack usage and fix O(N²) behavior in constant folding, and speed up yield from, bytes.replace(), and memoryview.cast().
2. Security hardening
  • Updates bundled cryptography libraries (for example newer OpenSSL versions in some builds).
  • Fixes path traversal issues in shutil.unpack_archive().
  • Hardens remote debugging related code paths.
  • Addresses crashes and recursion issues in xml.parsers.expat.
  • Adds stricter validation in http.cookies, webbrowser, configparser, and related modules.
  • Introduces tighter limits for TOML keys and canonical Base64 handling.
3. Standard library enhancements
  • Command-line tools like argparse, pdb, regrtest, pickletools, tokenize, calendar, timeit, and http.server gain extended colorized output.
  • The inspect command-line interface is significantly improved.
  • timeit adds a --target-time option for more predictable benchmarking.
  • Typing gains support for features such as disjoint base decorators and richer TypeVarTuple options (bound, covariant, contravariant).
  • ForwardRef representations become clearer and easier to read.
  • Regular expression APIs move toward re.prefixmatch() instead of re.match().
  • array and memoryview support complex number formats like Zf and Zd.
  • frozendict is better integrated with dataclasses, plistlib, and dictionary merging.
  • UserDict.popitem() now behaves in a predictable, ordered way.
  • json adds an array_hook for more flexible decoding.
  • email, IDNA, and importlib.metadata receive fixes for Unicode handling and corrupted metadata.
  • asyncio adds TaskGroup.cancel(), improves debugging, shutdown behavior, and event loop performance.
  • The profiling.sampling module gains dump snapshots, --jsonl output, and --diff-flamegraph for visual comparisons.
4. C API and extension changes
  • Implements a unified slot system for types, simplifying extension type definitions.
  • Adds a stable ABI variant for free-threaded builds (abi3t).
  • Introduces new, safer functions for garbage collector traversal.
  • Makes PyCriticalSection part of the Stable ABI.
  • Provides hooks like PyInterpreterState_SetEvalFrameAllowSpecialization for controlling specialization behavior.
5. Build system and platforms
  • Windows builds adopt a new layout and support free-threaded configurations.
  • Updates to toolchains such as WASI SDK and modern compilers.
  • Improves performance on AArch64 and x86_64 architectures.
  • Fixes issues with PGO, Clang, and LLVM-based builds.
  • Adds options like --enable-static-libpython-for-interpreter for more flexible embedding.
6. Developer experience and ergonomics
  • More extensive colorization in command-line tools and error messages.
  • Better suggestions and messages for AttributeError and similar exceptions.
  • More robust REPL behavior and nicer pretty-printing, including support for new string forms.
  • Smarter import-related completions and diagnostics for everyday workflows.

Saturday, May 2, 2026

Python 3.10.x : Install ComfyUI tool with python and Krita.

This is a basic install of ComfyUI tool with python 3.10 version.
git clone https://github.com/comfyanonymous/ComfyUI
cd ComfyUI
python -m pip install -r requirements.txt
...
Successfully installed blake3-1.0.8 comfy-aimdo-0.3.0 comfy-kitchen-0.2.8 comfyui-embedded-docs-0.4.4 comfyui-frontend-package-1.42.15 comfyui-workflow-templates-0.9.66 comfyui-workflow-templates-core-0.3.221 comfyui-workflow-templates-media-api-0.3.73 comfyui-workflow-templates-media-image-0.3.133 comfyui-workflow-templates-media-other-0.3.187 comfyui-workflow-templates-media-video-0.3.83 glfw-2.10.0 kornia-0.8.2 kornia_rs-0.1.10 sentencepiece-0.2.1 simpleeval-1.0.7 spandrel-0.4.2 torchsde-0.2.6 trampoline-0.1.2
python main.py
You don't have all nodes for running, for example if you want to use with Krita then use this:

git clone https://github.com/comfyanonymous/ComfyUI
cd ComfyUI

echo ================================================
echo   Install all need for ComfyUI
echo ================================================
python -m pip install -r requirements.txt

echo ================================================
echo   Install nodes Krita AI Diffusion
echo ================================================
cd custom_nodes

REM --- ControlNet Preprocessors ---
if not exist comfyui_controlnet_aux (
    git clone https://github.com/Fannovel16/comfyui_controlnet_aux
)

REM --- IP-Adapter Plus ---
if not exist ComfyUI_IPAdapter_plus (
    git clone https://github.com/cubiq/ComfyUI_IPAdapter_plus
)

REM --- Tooling Nodes ---
if not exist comfyui-tooling-nodes (
    git clone https://github.com/Acly/comfyui-tooling-nodes
)

REM --- Inpaint Nodes ---
if not exist comfyui-inpaint-nodes (
    git clone https://github.com/Acly/comfyui-inpaint-nodes
)

cd ..

echo ================================================
echo   Install nodes
echo ================================================

REM --- ControlNet Aux ---
if exist custom_nodes\comfyui_controlnet_aux\requirements.txt (
    python -m pip install -r custom_nodes\comfyui_controlnet_aux\requirements.txt
)

REM --- IPAdapter Plus ---
if exist custom_nodes\ComfyUI_IPAdapter_plus\requirements.txt (
    python -m pip install -r custom_nodes\ComfyUI_IPAdapter_plus\requirements.txt
)

REM --- Tooling Nodes ---
if exist custom_nodes\comfyui-tooling-nodes\requirements.txt (
    python -m pip install -r custom_nodes\comfyui-tooling-nodes\requirements.txt
)

REM --- Inpaint Nodes ---
if exist custom_nodes\comfyui-inpaint-nodes\requirements.txt (
    python -m pip install -r custom_nodes\comfyui-inpaint-nodes\requirements.txt
)

echo ================================================
echo   Install packages
echo ================================================
python -m pip install blake3 comfy-aimdo comfy-kitchen comfyui-embedded-docs ^
comfyui-frontend-package comfyui-workflow-templates ^
comfyui-workflow-templates-core comfyui-workflow-templates-media-api ^
comfyui-workflow-templates-media-image comfyui-workflow-templates-media-other ^
comfyui-workflow-templates-media-video glfw kornia kornia_rs sentencepiece ^
simpleeval spandrel torchsde trampoline

echo ================================================
echo   Start ComfyUI
echo ================================================
python main.py

Thursday, April 23, 2026

Tuesday, April 21, 2026

Python Qt : sprites tool idea with ffmpeg.

This is a simple tool created in a minute with artificial intelligence to help me create sprites with a blend effect based on a map for ffmpeg. I used Python version 3.13.0, pyqt6, pygame, ...

Monday, April 20, 2026

Python 3.12.13 : Colab example with Ipywidgets.

Ipywidgets are interactive HTML widgets for Jupyter notebooks and the IPython kernel that allow users to create GUIs (sliders, text boxes, checkboxes) to visualize and control data in real time. They enable dynamic data exploration and parameter tuning, with over 30 built-in, customizable controls for building interactive dashboards directly in Python code.
You can see on my GitHub Colab repo.

Tuesday, April 14, 2026

Python 3.12.13 : kernel CUDA for Tesla T4 in colab google - part 055.

Today, I will show a source code for a simple CUDA kernel for Tesla T4 in colab google with Python version 3.12.13.
The source code works very well, I will make an video with the results.
The T4 has thousands of CUDA Cores. The kernel divides the image into "Blocks" (16x16 pixel squares) and distributes them across these cores.
This source code is a high-performance image processing pipeline that bridges Python and CUDA (C++) to create a dynamic video effect. By using PyTorch's load_inline feature, it compiles custom GPU code on the fly to manipulate pixels at massive scale.
Loading the Image: It reads the image and moves it from the CPU (System RAM) to the GPU (Video RAM) using .cuda().
Loading the Image: It reads the image and moves it from the CPU (System RAM) to the GPU (Video RAM) using .cuda().
It runs a loop for each video frame, calculating where the "Zoom Ball" should be at that specific millisecond.
The code inside cuda_source is a Kernel, a special function designed to run on thousands of GPU cores simultaneously.
Instead of processing one pixel at a time (like a CPU would), the GPU assigns a specific thread to every single pixel in the image. If your image has 1 million pixels, 1 million threads start working at the same time.
If a pixel is inside the ball's radius, the thread "re-maps" its coordinate. It looks at the original image but pulls a pixel from closer to the center of the ball.
Because the zoom calculation for the top-left pixel doesn't depend on the bottom-right pixel, the GPU completes the entire frame transformation in microseconds.
Let's see the source code:
import torch
from torch.utils.cpp_extension import load_inline
from PIL import Image
import numpy as np
import cv2 # Pentru a salva animația ca video
from google.colab import files # Pentru a descărca rezultatul
import os
import shutil

# --- 0. Curățare și Pregătire Mediu ---
# Instalăm ninja dacă nu există
!pip install ninja -q

# Ștergem cache-ul vechi pentru a forța recompilarea curată
extensions_dir = '/root/.cache/torch_extensions/py312_cu128/swim_animator'
if os.path.exists(extensions_dir):
shutil.rmtree(extensions_dir)
print(f"Cache șters: {extensions_dir}")

# Verificăm GPU
print(f"GPU disponibil: {torch.cuda.is_available()}")
if torch.cuda.is_available():
print(f"Nume GPU: {torch.cuda.get_device_name(0)}")


# --- 1. Codul CUDA (Efect de Bilă de Zoom) ---
cuda_source = r"""
#include <torch/extension.h>
#include <cuda.h>
#include <cuda_runtime.h>
#include <math.h>

__global__ void zoom_ball_kernel(
const unsigned char* __restrict__ input,
unsigned char* __restrict__ output,
int width, int height, float ball_center_x, float max_zoom)
{
int x = blockIdx.x * blockDim.x + threadIdx.x;
int y = blockIdx.y * blockDim.y + threadIdx.y;

if (x < width && y < height) {
float ball_center_y = height / 2.0f;
float ball_radius = height / 2.0f; // Bila e înaltă cât imaginea

// 1. Calculăm distanța de la pixel la centrul bilei
float dx = x - ball_center_x;
float dy = y - ball_center_y;
float distance = sqrtf(dx*dx + dy*dy);

float src_x = (float)x;
float src_y = (float)y;

// 2. Dacă pixelul e în interiorul bilei, aplicăm zoom sferic
if (distance < ball_radius) {
// Factor de atenuare: 1 în centru, 0 la margine (smooth)
float norm_dist = distance / ball_radius;
float falloff = cosf(norm_dist * 3.14159f * 0.5f); // Smooth curve

// Calculăm zoom-ul local (maxim în centru, 1 la margine)
float current_zoom = 1.0f + (max_zoom - 1.0f) * falloff;

// Coordonate sursă modificate sferic față de centrul bilei
src_x = ball_center_x + (dx / current_zoom);
src_y = ball_center_y + (dy / current_zoom);
}

// 3. Limităm coordonatele la dimensiunea imaginii (handling edge cases)
int isrc_x = max(0, min(width - 1, (int)src_x));
int isrc_y = max(0, min(height - 1, (int)src_y));

int out_idx = (y * width + x) * 3;
int src_idx = (isrc_y * width + isrc_x) * 3;

output[out_idx] = input[src_idx]; // R
output[out_idx + 1] = input[src_idx + 1]; // G
output[out_idx + 2] = input[src_idx + 2]; // B
}
}

torch::Tensor apply_zoom_ball_effect(torch::Tensor input, float ball_center_x, float max_zoom) {
const int height = input.size(0);
const int width = input.size(1);
auto output = torch::empty_like(input);

dim3 block_dim(16, 16);
dim3 grid_dim((width + block_dim.x - 1) / block_dim.x,
(height + block_dim.y - 1) / block_dim.y);

zoom_ball_kernel<<<grid_dim, block_dim>>>(
input.data_ptr<unsigned char>(),
output.data_ptr<unsigned char>(),
width, height, ball_center_x, max_zoom);

return output;
}
"""

# Header C++ necesar
cpp_source = """
#include <torch/extension.h>
torch::Tensor apply_zoom_ball_effect(torch::Tensor input, float ball_center_x, float max_zoom);
"""

# --- 2. Compilare (JIT) ---
print("Compilăm kernel-ul CUDA... (poate dura 30-60 secunde)")
swim_module = load_inline(
name="swim_animator",
cpp_sources=cpp_source,
cuda_sources=cuda_source,
functions=["apply_zoom_ball_effect"],
extra_cuda_cflags=["-arch=sm_75"],
verbose=False
)
print("Compilare reușită!")


# --- 3. Funcția de procesare animație ---
def create_zoom_ball_video(image_path, output_video="bila_zoom.mp4"):
# Încărcare imagine
if not os.path.exists(image_path):
print(f"Eroare: Imaginea {image_path} nu există.")
return

img_pil = Image.open(image_path).convert('RGB')
width, height = img_pil.size
img_tensor = torch.from_numpy(np.array(img_pil)).cuda()

# Configurare video
fps = 30
duration_sec = 5 # Puțin mai lung pentru a vedea toată traversarea
num_frames = fps * duration_sec
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
video_writer = cv2.VideoWriter(output_video, fourcc, fps, (width, height))

print(f"Generăm {num_frames} cadre pe GPU...")

# Parametrii efectului
max_zoom = 2.5 # Cât de puternic e zoom-ul în centrul bilei
ball_radius = height / 2.0

# Calculăm traiectoria: din dreapta-afară în stânga-afară
# Start: width + radius, End: -radius
start_x = width + ball_radius
end_x = -ball_radius

for i in range(num_frames):
# Progresul animației de la 0.0 la 1.0
progress = i / (num_frames - 1)

# Poziția X curentă a bilei (interpolare liniară)
current_ball_x = start_x + (end_x - start_x) * progress

# Apelăm kernel-ul CUDA
frame_tensor = swim_module.apply_zoom_ball_effect(img_tensor, current_ball_x, max_zoom)

# Înapoi pe CPU și în format OpenCV (BGR)
frame_np = frame_tensor.cpu().numpy()
frame_bgr = cv2.cvtColor(frame_np, cv2.COLOR_RGB2BGR)
video_writer.write(frame_bgr)

video_writer.release()
print("Video salvat!")

# --- 4. Execuție ---
# Descărcăm o imagine de test mai lată pentru a vedea efectul de traversare
#!wget -O peisaj.jpg https://upload.wikimedia.org/wikipedia/commons/thumb/c/c8/Altja_j%C3%B5gi_Lahemaal.jpg/1280px-Altja_j%C3%B5gi_Lahemaal.jpg
!wget -O peste.jpg https://upload.wikimedia.org/wikipedia/commons/thumb/7/7f/Balantiocheilos_melanopterus_-_Karlsruhe_Zoo_02_%28cropped%29.jpg/960px-Balantiocheilos_melanopterus_-_Karlsruhe_Zoo_02_%28cropped%29.jpg
create_zoom_ball_video("peste.jpg")

# Descarcă rezultatul
files.download("bila_zoom.mp4")

Python 3.13.0 : converting documents to Markdown.

Python tool for converting files and office documents to Markdown.
Easy to use:
markitdown path-to-file.pdf > document.md
Or use -o to specify the output file:
markitdown path-to-file.pdf -o document.md
You can also pipe content:
cat path-to-file.pdf | markitdown
The project can be found on this GitHub repo.
Let's install with these commands:
git clone https://github.com/microsoft/markitdown.git
Cloning into 'markitdown'...
remote: Enumerating objects: 2168, done.
remote: Counting objects: 100% (6/6), done.
remote: Compressing objects: 100% (6/6), done.
remote: Total 2168 (delta 0), reused 0 (delta 0), pack-reused 2162 (from 2)
Receiving objects: 100% (2168/2168), 4.15 MiB | 2.50 MiB/s, done.
Resolving deltas: 100% (1238/1238), done.
Updating files: 100% (161/161), done.

cd markitdown

python -m pip install -e "packages/markitdown[all]"
Obtaining file:///C:/Python313_64bit/markitdown/packages/markitdown
...
Successfully installed XlsxWriter-3.2.9 azure-ai-documentintelligence-1.0.2 azure-core-1.39.0 azure-identity-1.25.3 
cobble-0.1.4 coloredlogs-15.0.1 humanfriendly-10.0 isodate-0.7.2 magika-0.6.3 mammoth-1.11.0 markdownify-1.2.2 
markitdown-0.1.6b2 msal-1.36.0 msal-extensions-1.3.1 olefile-0.47 onnxruntime-1.20.1 pdfminer-six-20251230 
pdfplumber-0.11.9 pypdfium2-5.7.0 python-pptx-1.0.2 speechrecognition-3.16.0 standard-aifc-3.13.0 standard-chunk-3.13.0 
xlrd-2.0.2 youtube-transcript-api-1.0.3

Python Qt : manages python packages from web.

Today, I created a script that looks for updates and manages them along with the already installed packages.
The script relies on three categories of data sources, all of them public, stable, and widely used in the Python ecosystem.
  • PyPI RSS Feeds (Official Python Package Index)
    • These are the official feeds published by PyPI.
    • 1. New packages feed
      • https://pypi.org/rss/packages.xml
      • This feed lists brand‑new packages uploaded to PyPI.
    • 2. Updated packages feed
      • https://pypi.org/rss/updates.xml
      • This feed lists new releases of existing packages.
    • These feeds are the most authoritative source for real‑time package activity.
  • Libraries.io Atom Feeds (Per‑package version history)
    • For each installed package, the script uses:
    • https://libraries.io/pypi/{PACKAGE_NAME}/versions.atom
    • This feed provides:
      • version history
      • release timestamps
      • links to source repositories
      • metadata about each release
    • Libraries.io aggregates data from PyPI, GitHub, GitLab, Bitbucket, and more.
  • Local Python Installation (importlib.metadata)
    • The script reads the list of packages installed on your system using:
    • importlib.metadata.distributions()
    • This gives:
      • installed package names
      • installed versions
      • metadata from the local environment
    • This is how the script knows whether to show Install or Update buttons.
  • SQLite Local Database (packages.db)
    • The script maintains a small local database that stores:
      • package name
      • installed version
      • last update timestamp
    • This allows the UI to:
      • remember previous states
      • show consistent information
      • track updates over time
What the Script Actually Does
  • On startup
    • Reads all installed Python packages
    • Synchronizes them into a SQLite database
    • Loads the three main tabs:
      • PyPI New Packages
      • PyPI Updated Packages
      • Libraries.io Installed Packages
  • In the PyPI tabs
    • For every RSS entry:
      • Extracts the package name
      • Checks if it is installed locally
      • Shows:
        • Title
        • Publish date
        • Link to PyPI
        • Install button (if not installed)
        • Update button (if installed)
    • This turns the PyPI feed into a package manager dashboard.
  • In the Libraries.io tab
    • For every installed package:
      • Builds the Libraries.io feed URL
      • Fetches version history
      • Displays:
        • Installed version
        • Release history
        • Links to releases
        • Update button
    • This tab becomes a per‑package release monitor.
  • When you click Install or Update
    • A confirmation dialog appears
    • If confirmed:
      • Runs python -m pip install PACKAGE
      • Or python -m pip install --upgrade PACKAGE
      • Runs pip in a background thread
      • Updates the SQLite database
      • Refreshes the UI
    • This makes the script a GUI package manager for Python.
See this demo real from my youtube channel:

Monday, April 13, 2026

Python 3.13.0 : bypasses pygame‑ce and use directly to Windows with ctypes.

Today, I test bypasses pygame‑ce and use directly to Windows, because the Python 3.13 + pygame‑ce 2.5.7, where DPI functions are missing.
You can read more about this idea on my pygame blogger, see the blogger post.
Windows exposes thousands of functions through: user32.dll, gdi32.dll, shcore.dll, kernel32.dll, dwmapi.dll.
If the OS provides the feature → Python can call it via ctypes.
Python can call Windows API functions directly whenever the OS provides a stable API, and you only perform operations that are safe at the OS level.
These are always safe to do from Python using ctypes, because they only interact with the OS, not with internal memory of another library.
  • Reading information
    • DPI
    • monitor list
    • window position
    • window size
    • screen resolution
    • system metrics
    • OS version
    • keyboard/mouse state
    • window styles
    • process info
  • Calling OS-level functions that modify the window
    • move window
    • resize window
    • change window title
    • change window transparency
    • change window z-order
    • set DPI awareness
    • toggle fullscreen
    • minimize / maximize
  • Creating new OS objects
    • timers
    • threads
    • windows (if you want)
    • file handles
    • pipes
    • events
  • Using OS-level graphics
    • GDI drawing
    • DWM effects
    • Aero shadow
    • blur behind window
  • Unsafe
    • Writing into internal memory of SDL2, Python, or any DLL
    • Overwriting function pointers
    • Injecting hooks
    • Modifying struct layouts
    • Freeing memory you don’t own
This is just one part of source code:
import pygame
import pygame._sdl2 as sdl2
import ctypes
import sys

pygame.init()

# Windows DPI API
user32 = ctypes.windll.user32
shcore = ctypes.windll.shcore

# Enable per-monitor DPI awareness
try:
    shcore.SetProcessDpiAwareness(2)
except:
    pass
...
user32.EnumDisplayMonitors(0, 0, MonitorEnumProc(_monitor_enum_proc), 0)
...

Python 3.13.0 : testing streamlit Python framework for data scientists and AI/ML engineers.

Streamlit is an open-source Python framework for data scientists and AI/ML engineers to deliver interactive data apps – in only a few lines of code.
I run the module streamlit directly, even if Windows cannot find the streamlit command:
python -m pip install streamlit
Collecting streamlit
  Downloading streamlit-1.56.0-py3-none-any.whl.metadata (9.8 kB)
...
Successfully installed altair-6.0.0 gitdb-4.0.12 gitpython-3.1.46 pydeck-0.9.1 smmap-5.0.3 streamlit-1.56.0
Let's test it:
python -m streamlit hello

      Welcome to Streamlit!

      If you'd like to receive helpful onboarding emails, news, offers, promotions,
      and the occasional swag, please enter your email address below. Otherwise,
      leave this field blank.

      Email: ←[0m

  You can find our privacy policy at https://streamlit.io/privacy-policy

  Summary:
  - This open source library collects usage statistics.
  - We cannot see and do not store information contained inside Streamlit apps,
    such as text, charts, images, etc.
  - Telemetry data is stored in servers in the United States.
  - If you'd like to opt out, add the following to %userprofile%/.streamlit/config.toml,
    creating that file if necessary:

    [browser]
    gatherUsageStats = false


  Welcome to Streamlit. Check out our demo in your browser.

  Local URL: http://localhost:8501
  Network URL: http://192.168.1.75:8501

  Ready to create your own Python apps super quickly?
  Head over to https://docs.streamlit.io

  May you create awesome apps!
... and result is this: