... another tool for game development, see more on my youtube channel.
python-catalin
Python tutorials with source code, examples, guides, and tips and tricks for Windows and Linux development.
Wednesday, May 6, 2026
Python 3.13.0 : mimesis python example.
Mimesis is a powerful data generator for Python that can produce a wide range of fake data in multiple languages. This tool is useful for populating testing databases, creating fake API endpoints, generating custom structures in JSON and XML files, and anonymizing production data, among other things. With Mimesis, developers can obtain realistic, randomized data easily to facilitate development and testing.
This python module can be install with pip tool easy.
See this simple example:
from mimesis import Person, Address, Text, Datetime
from mimesis.enums import Gender
def test_mimesis(locale: str, sex: str):
person = Person(locale)
address = Address(locale)
text = Text(locale)
dt = Datetime()
gender = Gender.MALE if sex == "male" else Gender.FEMALE
data = {
"first_name": person.first_name(gender=gender),
"last_name": person.last_name(),
"full_name": person.full_name(gender=gender),
"email": person.email(),
"telephone": person.telephone(),
"occupation": person.occupation(),
"address": address.address().replace("\n", ", "),
"city": address.city(),
"postal_code": address.postal_code(),
"country": address.country(),
"birth_date": dt.date(start=1970, end=2005),
"bio": text.text(quantity=2),
}
return data
if __name__ == "__main__":
npc = test_mimesis("en", "female")
for k, v in npc.items():
print(f"{k}: {v}")The result is:
python_313 test_mimesis.py
first_name: Nisha
last_name: Rocha
full_name: Hertha Wynn
email: stakeholders2063@protonmail.com
telephone: +14172413972
occupation: Medical Physicist
address: 865 Cooper Highway
city: Elkhart
postal_code: 69168
country: France
birth_date: 2004-06-11
bio: It is also a garbage-collected runtime system. Do you come here often?
Posted by
Cătălin George Feștilă
Labels:
2026,
mimesis,
module,
modules,
packages,
programming,
python,
python modules,
python packages,
python3,
tutorial,
tutorials
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'.
Posted by
Cătălin George Feștilă
Labels:
2026,
2D,
module,
modules,
nuitka,
packages,
programming,
python,
python modules,
python packages,
python3,
tutorial,
tutorials
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())
Posted by
Cătălin George Feștilă
Labels:
2026,
2D,
artificial intelligence,
json,
module,
modules,
os,
packages,
programming,
PyQt6,
python,
python modules,
python packages,
python3,
subprocess,
tutorial,
tutorials
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.pyYou 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
Posted by
Cătălin George Feștilă
Labels:
2026,
artificial intelligence,
ComfyUI,
python,
python 3,
tutorial,
tutorials
Wednesday, April 29, 2026
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, ...
Posted by
Cătălin George Feștilă
Labels:
2026,
2D,
module,
modules,
packages,
programming,
pygame,
PyQt6,
python,
python modules,
python packages,
python3,
tutorial,
tutorials
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.
Posted by
Cătălin George Feștilă
Labels:
2026,
2026 news,
Colab,
Google Colab,
ipywidgets,
news,
python,
python 3
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.mdOr use -o to specify the output file:
markitdown path-to-file.pdf -o document.mdYou can also pipe content:
cat path-to-file.pdf | markitdownThe 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
Posted by
Cătălin George Feștilă
Labels:
2026,
markitdown,
module,
modules,
packages,
python,
python 3,
python modules,
python packages,
tutorial,
tutorials,
video tutorial
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:
Posted by
Cătălin George Feștilă
Labels:
2026,
2D,
module,
modules,
packages,
programming,
PyQt6,
python,
python modules,
python packages,
python3,
tutorial,
tutorials
Subscribe to:
Posts (Atom)