analitics

Pages

Showing posts with label tutorial. Show all posts
Showing posts with label tutorial. Show all posts

Wednesday, March 26, 2025

Python 3.11.11 : Colab simple test with CogVideoX-5B model and default example - part 050.

I tested this GitHub project from THUDM user on my colab google account and works well with CogVideoX-5B model.
You can find the default implementation on my colab GitHub repo.
The default example comes with thjs prompt:
prompt = ( "A panda, dressed in a small, red jacket and a tiny hat, sits on a wooden stool in a serene bamboo forest. " "The panda's fluffy paws strum a miniature acoustic guitar, producing soft, melodic tunes. Nearby, a few other " "pandas gather, watching curiously and some clapping in rhythm. Sunlight filters through the tall bamboo, " "casting a gentle glow on the scene. The panda's face is expressive, showing concentration and joy as it plays. " "The background includes a small, flowing stream and vibrant green foliage, enhancing the peaceful and magical " "atmosphere of this unique musical performance." )
The speed of rendering starts from :
38% ... 19/50 [30:54<50:57, 98.61s/it] using T4 GPU
... then run at :
100% ... 50/50 [1:26:09<00:00, 109.87s/it]
when the video render was 100% somehow google give this error, but the source code run well:
OutOfMemoryError: CUDA out of memory. Tried to allocate 1.32 GiB. GPU 0 has a total capacity of 14.74 GiB of which 654.12 MiB is free. Process 26970 has 14.10 GiB memory in use. Of the allocated memory 12.97 GiB is allocated by PyTorch, and 1.00 GiB is reserved by PyTorch but unallocated. If reserved but unallocated memory is large try setting PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True to avoid fragmentation. See documentation for Memory Management (https://pytorch.org/docs/stable/notes/cuda.html#environment-variables)
I think is need to set some extra memory on CUDA but this require to parse some documentation and is not a task for me now.

Saturday, March 22, 2025

Python 3.11.11 : Colab simple test with VGG16 - part 049.

VGG16 is a deep convolutional neural network (CNN) trained on a massive image dataset called ImageNet. This architecture is known for its remarkable performance in image classification tasks and is widely used in various computer vision applications.
You can find one simple example on my GitHub project.

Saturday, March 15, 2025

Python Qt6 : Dependency checker for python packages with pipdeptree and PyQt6.

Today I created this python script to test and check python package dependency.
You need to install the pipdeptree with the pip tool.
I used the Python 3.13.0rc1 version and the result is this:
This is the source code I used:
import sys
import subprocess
from PyQt6.QtWidgets import (
    QApplication, QMainWindow, QVBoxLayout, QTreeWidget, QTreeWidgetItem, QWidget
)
from PyQt6.QtWidgets import QHeaderView
from PyQt6.QtGui import QIcon
from PyQt6.QtWidgets import QStyle


class DependencyViewer(QMainWindow):
    def __init__(self):
        super().__init__()

        self.setWindowTitle("Dependency Checker")

        # Maximizarea ferestrei la lansare
        self.showMaximized()

        # Creează un QTreeWidget pentru afișarea dependențelor
        self.tree_widget = QTreeWidget()
        self.tree_widget.setHeaderLabels(["Dependency", "Status"])

        # Ajustează aliniamentul central pentru fiecare coloană
        for i in range(2):  # Pentru cele două coloane
            self.tree_widget.headerItem().setTextAlignment(i, Qt.AlignmentFlag.AlignCenter)

        # Configurarea automată a lățimii coloanelor
        self.tree_widget.header().setSectionResizeMode(QHeaderView.ResizeMode.ResizeToContents)

        # Layout
        layout = QVBoxLayout()
        layout.addWidget(self.tree_widget)

        container = QWidget()
        container.setLayout(layout)
        self.setCentralWidget(container)

        # Obține și afișează dependențele
        self.display_dependencies()

    def display_dependencies(self):
        try:
            # Rulează pipdeptree pentru a obține ierarhia dependențelor
            result = subprocess.run(['pipdeptree', '--warn', 'silence'], capture_output=True, text=True)
            dependencies = result.stdout.splitlines()

            for line in dependencies:
                # Determină nivelul de indentare pentru ierarhia dependențelor
                indent_level = len(line) - len(line.lstrip())
                dependency_name = line.strip()

                # Creează un item pentru fiecare dependență
                item = QTreeWidgetItem([dependency_name])

                # Atribuie iconițe pe baza compatibilității (exemplu simplificat)
                if "(*)" in dependency_name:  # Exemplu de incompatibilitate (poți schimba după caz)
                    item.setIcon(0, self.style().standardIcon(QStyle.StandardPixmap.SP_DialogCancelButton))
                    item.setText(1, "Incompatible")
                else:
                    item.setIcon(0, self.style().standardIcon(QStyle.StandardPixmap.SP_DialogApplyButton))
                    item.setText(1, "Compatible")

                # Adaugă item-ul în arbore
                if indent_level == 0:
                    self.tree_widget.addTopLevelItem(item)
                else:
                    # Alege ultimul item părinte și adaugă dependența ca sub-item
                    parent_item = self.tree_widget.topLevelItem(self.tree_widget.topLevelItemCount() - 1)
                    parent_item.addChild(item)

            # Extinde toate elementele din arbore
            self.tree_widget.expandAll()

        except Exception as e:
            error_item = QTreeWidgetItem(["Error", str(e)])
            error_item.setIcon(0, self.style().standardIcon(QStyle.StandardPixmap.SP_MessageBoxCritical))
            self.tree_widget.addTopLevelItem(error_item)


if __name__ == "__main__":
    from PyQt6.QtCore import Qt

    app = QApplication(sys.argv)
    viewer = DependencyViewer()
    viewer.show()
    sys.exit(app.exec())

Wednesday, March 12, 2025

Python 3.13.0rc1 : testing the new Kivy-2.3.1 with default examples.

Today I tested the Kivy-2.3.1 with Python 3.13.0rc1.
Read more on the official webpage.
The install step is easy with the pip tool:
python -m pip install kivy
Collecting kivy
...
Installing collected packages: kivy-deps.sdl2, kivy-deps.glew, kivy-deps.angle, filetype, pypiwin32, pygments, docutils, Kivy-Garden, kivy
Successfully installed Kivy-Garden-0.1.5 docutils-0.21.2 filetype-1.2.0 kivy-2.3.1 kivy-deps.angle-0.4.0 kivy-deps.glew-0.3.1 kivy-deps.sdl2-0.8.0 pygments-2.19.1 pypiwin32-223
Let's install the kivy examples source code:
python -m pip install --pre "kivy[base]" kivy_examples
Collecting kivy_examples
...
Installing collected packages: kivy_examples
Successfully installed kivy_examples-2.3.1
You can test these examples with this command into the python folder:
C:\Python313\share\kivy-examples>python demo\showcase\main.py
[WARNING] [Config      ] Older configuration version detected (0 instead of 27)
[WARNING] [Config      ] Upgrading configuration in progress.
[DEBUG  ] [Config      ] Upgrading from 0 to 1
This is the result:

Monday, March 10, 2025

News : Ollama-Adaptive-Image-Code-Gen project test - need more memory.

Python code that leverages a language model (such as LLaMA) to generate images featuring basic shapes in 2D or 3D. The script randomly selects shapes, colors, and areas to create diverse visuals. It continuously generates images based on AI-generated code, validates them, and provides feedback for iterative improvements.
This source code can be found on this GitHub project named Ollama-Adaptive-Image-Code-Gen.
You can download this and use these commands to run and test this feature of create and generate images with ollama.
NOTE: Compose up process might upto 20 - 25 Mins. first time. Because it will download all the respective ModelFiles
Let's start:
git clone https://github.com/jaypatel15406/Ollama-Adaptive-Image-Code-Gen.git
Cloning into 'Ollama-Adaptive-Image-Code-Gen'...
Resolving deltas: 100% (30/30), done.

cd Ollama-Adaptive-Image-Code-Gen

Ollama-Adaptive-Image-Code-Gen>pip3 install -r requirements.txt
Collecting ollama (from -r requirements.txt (line 1))
...
Installing collected packages: propcache, multidict, frozenlist, aiohappyeyeballs, yarl, aiosignal, ollama, 
aiohttp
Successfully installed aiohappyeyeballs-2.4.8 aiohttp-3.11.13 aiosignal-1.3.2 frozenlist-1.5.0 multidict-6.1.0
ollama-0.4.7 propcache-0.3.0 yarl-1.18.3

Ollama-Adaptive-Image-Code-Gen>python main.py
 utility : pull_model_instance : Instansiating 'llama3.1' ...
 utility : pull_model_instance : 'llama3.1' Model Fetching Status : pulling manifest
 utility : pull_model_instance : 'llama3.1' Model Fetching Status : pulling 667b0c1932bc
 
Seams to work but I need more memory:
Ollama-Adaptive-Image-Code-Gen>python main.py
 utility : pull_model_instance : Instansiating 'llama3.1' ...
 utility : pull_model_instance : 'llama3.1' Model Fetching Status : pulling manifest
 utility : pull_model_instance : 'llama3.1' Model Fetching Status : pulling 667b0c1932bc
 utility : pull_model_instance : 'llama3.1' Model Fetching Status : pulling 948af2743fc7
 utility : pull_model_instance : 'llama3.1' Model Fetching Status : pulling 0ba8f0e314b4
 utility : pull_model_instance : 'llama3.1' Model Fetching Status : pulling 56bb8bd477a5
 utility : pull_model_instance : 'llama3.1' Model Fetching Status : pulling 455f34728c9b
 utility : pull_model_instance : 'llama3.1' Model Fetching Status : verifying sha256 digest
 utility : pull_model_instance : 'llama3.1' Model Fetching Status : writing manifest
 utility : pull_model_instance : 'llama3.1' Model Fetching Status : success

=========================================================================================

 utility : get_prompt_response : Prompt : Choose the dimension of the shape: '2D' or '3D'. NOTE: Return only the chosen dimension.
ERROR:root: utility : get_prompt_response : Error : model requires more system memory (5.5 GiB) than is available (5.1 GiB) (status code: 500) ... 

Python 3.13.0rc1 : Python script as window 10 service.

The main reason I tested this python issues comes from this:
I have a strange usage of msedgewebview2.exe on my window 10.
The right way was to install but I cannot do that because is not my laptop.
I created a python script to make logs and kill this process:
import win32serviceutil
import servicemanager
import win32event
import win32service
import time
import logging
import psutil

class MyService(win32serviceutil.ServiceFramework):
    _svc_name_ = 'catafestService'
    _svc_display_name_ = 'My catafest Service tool'

    def __init__(self, args):
        win32serviceutil.ServiceFramework.__init__(self, args)
        self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)
        self.stop_requested = False
        logging.basicConfig(filename='D:\\PythonProjects\\catafest_services\\logfile.log', level=logging.DEBUG,
                            format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')

    def SvcStop(self):
        self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
        win32event.SetEvent(self.hWaitStop)
        self.stop_requested = True
        logging.info('Service stop requested')

    def SvcDoRun(self):
        servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,
                              servicemanager.PYS_SERVICE_STARTED,
                              (self._svc_name_, ''))
        logging.info('Service started')
        self.main()

    def main(self):
        while not self.stop_requested:
            try:
                # Check and terminate 'msedgewebview2.exe' process
                for proc in psutil.process_iter(['pid', 'name']):
                    if proc.info['name'] == 'msedgewebview2.exe':
                        proc.kill()
                        logging.info(f'Terminated process: {proc.info["name"]} (PID: {proc.info["pid"]})')
                logging.info('Service running...')
                time.sleep(10)  # Runs every 10 seconds
            except Exception as e:
                logging.error(f'Error occurred: {e}', exc_info=True)
                servicemanager.LogMsg(servicemanager.EVENTLOG_ERROR_TYPE,
                                      servicemanager.PYS_SERVICE_STOPPED,
                                      (self._svc_name_, f'Error occurred: {e}'))
                break
        logging.info('Service stopped')

if __name__ == '__main__':
    win32serviceutil.HandleCommandLine(MyService)
You need to install pyinstaller to make a exe file:
pip install pyinstaller
...
Successfully installed altgraph-0.17.4 pefile-2023.2.7 pyinstaller-6.12.0 pyinstaller-hooks-contrib-2025.1
pywin32-ctypes-0.2.3
The next step install the pywin32 python package:
pip install pywin32
... try to make executable:
pyinstaller --onefile catafest_services.py
... use the start:
catafest_services.exe start
Traceback (most recent call last):
  ...
  File "win32serviceutil.py", line 706, in HandleCommandLine
  File "win32serviceutil.py", line 624, in GetServiceClassString
ModuleNotFoundError: No module named 'win32timezone'
[PYI-6880:ERROR] Failed to execute script 'catafest_services' due to unhandled exception!
... this error comes from interaction on running with windows services:
try to fix with this:
pyinstaller --name=catafest_services --onefile catafest_services.py
Open the generated spec file catafest_services.spec and add the win32timezone module to the hidden imports. See:
# -*- mode: python ; coding: utf-8 -*-
block_cipher = None

a = Analysis(['catafest_services.py'],
             pathex=['D:\\PythonProjects\\catafest_services'],
             binaries=[],
             datas=[],
             hiddenimports=['win32timezone'],
             hookspath=[],
             runtime_hooks=[],
             excludes=[],
             win_no_prefer_redirects=False,
             win_private_assemblies=False,
             cipher=block_cipher,
             noarchive=False)
             
# The rest of the file remains unchanged
Rebuild the executable using the modified spec file:
pyinstaller catafest_services.spec
709 INFO: PyInstaller: 6.12.0, contrib hooks: 2025.1
711 INFO: Python: 3.13.0rc1
791 INFO: Platform: Windows-10-10.0.19045-SP0
791 INFO: Python environment: C:\Python313
...
Try again with start:
catafest_services.exe start
I got this output:
catafest_services.exe start
Starting service catafestService 
Error starting service: Access is denied.
Open the command prompt as administrator and try again:
catafest_services.exe start
Starting service catafestService
Error starting service: The service did not respond to the start or control request in a timely fashion.
Same interaction because try to kill a process and more ...
This not work, but is another good way to use it by using the debug:
catafest_services.exe debug
Debugging service catafestService - press Ctrl+C to stop.
I n f o   0 x 4 0 0 0 1 0 0 2   -   T h e   c a t a f e s t S e r v i c e   s   r v i c e   h a s   s t a r t e d .
 Stopping debug service.
Under debug all works well, some msedgewebview2 processes are gone.
I stop this run and I try to work on development ...
Next step: If all works then you can use install:
catafest_services.exe install
Installing service catafestService
Service installed
You can do more. Make sure the account running the service has the necessary permissions. You can specify a user account during service installation:
catafest_services.exe install --username your_domain\your_username --password your_password
You can use this command to see these info:
set user
Last step: You can open the Services Manager by typing services.msc in the Windows Run dialog. Use press Win + R keys to open the Run dialog.
Manage the service as any services. You can use even on command prompt:
catafest_services.exe
Usage: 'catafest_services.exe [options] install|update|remove|start [...]|stop|restart [...]|debug [...]'t_services>cd dist
Options for 'install' and 'update' commands only:
 --username domain\username : The Username the service is to run under
 --password password : The password for the username
 --startup [manual|auto|disabled|delayed] : How the service starts, default = manual
 --interactive : Allow the service to interact with the desktop.
 --perfmonini file: .ini file to use for registering performance monitor data
 --perfmondll file: .dll file to use when querying the service for
   performance data, default = perfmondata.dll
Options for 'start' and 'stop' commands only:
 --wait seconds: Wait for the service to actually start or stop.
                 If you specify --wait with the 'stop' option, the service
                 and all dependent services will be stopped, each waiting
                 the specified period.

Saturday, March 1, 2025

Python 3.13.0rc1 : testing the elevenlabs with artificial intelligence.

Today I teste the elevenlabs python package to use it with artifical inteligence to create sound.
I install this python package with pip tool, I created a python script file and the basic script run well with the api key from the official website.
pip install elevenlabs
Collecting elevenlabs
...
Installing collected packages: websockets, sniffio, pydantic-core, h11, annotated-types, pydantic, httpcore, anyio, httpx,
elevenlabs
Successfully installed annotated-types-0.7.0 anyio-4.8.0 elevenlabs-1.52.0 h11-0.14.0 httpcore-1.0.7 httpx-0.28.1 
pydantic-2.10.6the official website pydantic-core-2.27.2 sniffio-1.3.1 websockets-15.0
...
pip install playsound
Collecting playsound
...
Installing collected packages: playsound
Successfully installed playsound-1.3.0
...
python elevenlabs_test_001.py
Fișierul audio a fost salvat la generated_audio.mp3
This is the source code:
import io  # Importarea bibliotecii io
from elevenlabs import ElevenLabs
from playsound import playsound
import tempfile
import os

# API Key pentru ElevenLabs
api_key = "API_KEY"
voice_id = "JBFqnCBsd6RMkjVDRZzb"


# Configurarea clientului ElevenLabs
client = ElevenLabs(api_key=api_key )

# Textul pe care vrei să-l convertești în audio
text = 'Hello! This is a test without mpv.'

# Generarea audio
audio_generator = client.generate(text=text, voice=voice_id)

# Colectarea datelor din generator într-un obiect BytesIO
audio_data = io.BytesIO()
for chunk in audio_generator:
    audio_data.write(chunk)
audio_data.seek(0)  # Resetarea pointerului la începutul streamului

# Specificarea căii de salvare pentru fișierul audio
save_path = 'generated_audio.mp3'

# Salvarea audio într-un fișier temporar
with tempfile.NamedTemporaryFile(delete=False, suffix='.mp3') as temp_audio:
    temp_audio.write(audio_data.read())
    temp_audio_path = temp_audio.name

# Redarea fișierului audio utilizând playsound
playsound(temp_audio_path)

# Salvarea fișierului audio generat într-o locație specificată
with open(save_path, 'wb') as f:
    audio_data.seek(0)  # Resetarea pointerului la începutul streamului pentru a citi din nou datele
    f.write(audio_data.read())

print(f'Fișierul audio a fost salvat la {save_path}')

Saturday, February 8, 2025

Python 3.13.0rc1 : Testing python with Ollama local install.

I was very busy with development and testing for about two weeks and my laptop was stuck and I was working hard... Today I managed to test local background clipping on my laptop with a local Ollama installation separated by a Python module but with processing from the Python script. I also used Microsoft's Copilot artificial intelligence for python and it works well even though it is not theoretically specialized in development. The source code is quite large but the result is very good and fast:
import subprocess
import os
import json
from PIL import Image, ImageOps

class OllamaProcessor:
    def __init__(self, config_file):
        self.config_file = config_file
        self.model_methods = self.load_config()

    def load_config(self):
        try:
            with open(self.config_file, 'r') as file:
                config = json.load(file)
            print("Configuration loaded successfully.")
            return config
        except FileNotFoundError:
            print(f"Configuration file {self.config_file} not found.")
            raise
        except json.JSONDecodeError:
            print(f"Error decoding JSON from the configuration file {self.config_file}.")
            raise

    def check_ollama(self):
        try:
            result = subprocess.run(["ollama", "--version"], capture_output=True, text=True, check=True)
            print("Ollama is installed. Version:", result.stdout)
        except subprocess.CalledProcessError as e:
            print("Ollama is not installed or not found in PATH. Ensure it's installed and accessible.")
            raise
... 
Here is the result obtained after finishing running in the command line:
python ollama_test_001.py
Configuration file ollama_config.json created successfully.
Configuration loaded successfully.
Ollama is installed. Version: ollama version is 0.5.7

Available models: ['NAME']
pulling manifest
pulling 170370233dd5... 100% ▕██████████████▏ 4.1 GB
pulling 72d6f08a42f6... 100% ▕██████████████▏ 624 MB
pulling 43070e2d4e53... 100% ▕██████████████▏  11 KB
pulling c43332387573... 100% ▕██████████████▏   67 B
pulling ed11eda7790d... 100% ▕██████████████▏   30 B
pulling 7c658f9561e5... 100% ▕██████████████▏  564 B
verifying sha256 digest
writing manifest
success
Model llava pulled successfully for method process_images_in_folder.
Some "Command failed ..." but the result is cutting well and it has transparency !

Tuesday, February 4, 2025

Python 3.11.11 : Colab simple test with mistralai - part 048.

Two notebook on my colab repo project
One with xterm colab festure and another with hull-convex known as lattrice with OllamaFunctions.

Thursday, January 9, 2025

Python 3.10.12 : Simple test with diffusers to create texture.

Today I tested on colab a simple python script to generate a texture using: diffusers, torch and gradio.
I upload the notebook on my colab repo from GitHub.
The script is simple and works good:
import gradio as gr
from diffusers import StableDiffusionPipeline
import torch

model_id = "dream-textures/texture-diffusion"
pipe = StableDiffusionPipeline.from_pretrained(model_id, torch_dtype=torch.float16)
pipe = pipe.to("cuda")

def generate_image(prompt):
    image = pipe(prompt).images[0]
    image.save("result.png")
    return image

iface = gr.Interface(
    fn=generate_image,
    inputs="text",
    outputs="image",
    title="Stable Diffusion Image Generator",
    description="Introduceți un prompt pentru a genera o imagine folosind Stable Diffusion."
)

iface.launch()
The result for the pbr winter terrain is this image:

Tuesday, January 7, 2025

Python 3.10.12 : Simple tests with gradio python package.

This is a simple example with gradio python package on colab notebook.
I test some basic UI graphics interface edit text , selection , slider and upload feature for some files : image, audio, video, any file.
You can find more on my Github - colab notebook repo.

Python 3.13.0rc1 : Simple convert all webp files from folder.

Today, a simple script is used to convert WEBP to PNG files from a defined folder.
The script reads a folder path for each WEBP file that is opened and saved as a PNG file.
import os
import sys
from PIL import Image

def convert_webp_to_png(directory):
    for root, dirs, files in os.walk(directory):
        for file in files:
            if file.endswith(".webp"):
                webp_path = os.path.join(root, file)
                png_path = os.path.splitext(webp_path)[0] + ".png"
                with Image.open(webp_path) as img:
                    img.save(png_path, "PNG")
                print(f"webp to png file: {webp_path} -> {png_path}")

if __name__ == "__main__":
    if len(sys.argv) != 2:
        print("How to use: python convert.py path_to_folder_with_webp_files")
        sys.exit(1)

    directory = sys.argv[1]
    if not os.path.isdir(directory):
        print(f"{directory} folder is not valid.")
        sys.exit(1)

    convert_webp_to_png(directory)
    print("Finished !")

Monday, December 16, 2024

Python 3.12.8 : Install quil in Fedora 41.

The quil python package on Fedora 41 can be used with the 3.12.8 version of python :
Python 3.12.8 (main, Dec  6 2024, 00:00:00) [GCC 14.2.1 20240912 (Red Hat 14.2.1-3)] on linux
mythcat@localhost:~$ python3.12 -m pip install quil --user
First, install the python version then install the pip tool:
mythcat@localhost:~$ curl https://bootstrap.pypa.io/get-pip.py | python3.12 -
...
Installing collected packages: pip
Successfully installed pip-24.3.1
Next, install with the pip version:
mythcat@localhost:~$ python3.12 -m pip install quil --user
Collecting quil

Saturday, December 14, 2024

Python 3.13.0 : OpenCV - part 002.

The PyQt6 python package and Fedora works great. I tested today this source code with opencv, numpy, PyQt6 python packages.
I install opencv python package with dnf5 tool:
root@localhost:/home/mythcat# dnf5 install  python3-opencv.x86_64
The source code let you to open, change a image and save using sliders and a reset option.
This is the source code:
import sys
import cv2
import numpy as np
from PyQt6.QtWidgets import QApplication, QMainWindow, QWidget, QVBoxLayout, QLabel, QSlider, QFileDialog, QPushButton, QHBoxLayout
from PyQt6.QtGui import QImage, QPixmap
from PyQt6.QtCore import Qt, pyqtSlot

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Real-Time Color Selection")
        self.setGeometry(100, 100, 1200, 800)

        # Create central widget and main layout
        central_widget = QWidget()
        self.setCentralWidget(central_widget)
        main_layout = QVBoxLayout(central_widget)

        # Create image label
        self.image_label = QLabel()
        main_layout.addWidget(self.image_label)

        # Initialize sliders
        self.lower_h = QSlider(Qt.Orientation.Horizontal)
        self.lower_s = QSlider(Qt.Orientation.Horizontal)
        self.lower_v = QSlider(Qt.Orientation.Horizontal)
        self.upper_h = QSlider(Qt.Orientation.Horizontal)
        self.upper_s = QSlider(Qt.Orientation.Horizontal)
        self.upper_v = QSlider(Qt.Orientation.Horizontal)

        # Set slider ranges
        for slider in [self.lower_h, self.upper_h]:
            slider.setRange(0, 179)
        for slider in [self.lower_s, self.lower_v, self.upper_s, self.upper_v]:
            slider.setRange(0, 255)

        # Set initial slider values
        self.lower_h.setValue(50)
        self.lower_s.setValue(100)
        self.lower_v.setValue(50)
        self.upper_h.setValue(130)
        self.upper_s.setValue(255)
        self.upper_v.setValue(255)

        # Connect sliders to update function
        self.lower_h.valueChanged.connect(self.update_hsv_range)
        self.lower_s.valueChanged.connect(self.update_hsv_range)
        self.lower_v.valueChanged.connect(self.update_hsv_range)
        self.upper_h.valueChanged.connect(self.update_hsv_range)
        self.upper_s.valueChanged.connect(self.update_hsv_range)
        self.upper_v.valueChanged.connect(self.update_hsv_range)

        # Create slider layouts with labels
        sliders_layout = QVBoxLayout()
        
        # Add slider pairs with labels
        slider_pairs = [
            ("Lower Hue", self.lower_h),
            ("Lower Saturation", self.lower_s),
            ("Lower Value", self.lower_v),
            ("Upper Hue", self.upper_h),
            ("Upper Saturation", self.upper_s),
            ("Upper Value", self.upper_v)
        ]

        for label_text, slider in slider_pairs:
            row_layout = QHBoxLayout()
            label = QLabel(label_text)
            label.setMinimumWidth(120)
            row_layout.addWidget(label)
            row_layout.addWidget(slider)
            sliders_layout.addLayout(row_layout)

        main_layout.addLayout(sliders_layout)

        # Add buttons
        button_layout = QHBoxLayout()
        
        self.reset_button = QPushButton("Reset Values")
        self.reset_button.clicked.connect(self.reset_values)
        button_layout.addWidget(self.reset_button)

        self.open_image_button = QPushButton("Open Image")
        self.open_image_button.clicked.connect(self.open_image)
        button_layout.addWidget(self.open_image_button)

        self.save_button = QPushButton("Save Image")
        self.save_button.clicked.connect(self.save_image)
        button_layout.addWidget(self.save_button)
        main_layout.addLayout(button_layout)

        # Process initial image
        self.process_image()

    def process_image(self):
        image_bgr = cv2.imread("image.png")
        if image_bgr is None:
            image_bgr = cv2.imread("default_image.png")
        
        self.image_bgr = image_bgr
        self.image_hsv = cv2.cvtColor(image_bgr, cv2.COLOR_BGR2HSV)

        # Create initial mask using current slider values
        lower_values = np.array([self.lower_h.value(), self.lower_s.value(), self.lower_v.value()])
        upper_values = np.array([self.upper_h.value(), self.upper_s.value(), self.upper_v.value()])
        
        mask_test = cv2.inRange(self.image_hsv, lower_values, upper_values)
        image_bgr_masked = cv2.bitwise_and(image_bgr, image_bgr, mask=mask_test)
        self.image_rgb = cv2.cvtColor(image_bgr_masked, cv2.COLOR_BGR2RGB)
        self.update_image()

    def update_image(self):
        height, width, channel = self.image_rgb.shape
        bytes_per_line = width * channel
        q_image = QImage(self.image_rgb.data, width, height, bytes_per_line, QImage.Format.Format_RGB888)
        pixmap = QPixmap.fromImage(q_image)
        self.image_label.setPixmap(pixmap.scaled(700, 500, Qt.AspectRatioMode.KeepAspectRatio))

    def update_hsv_range(self):
        lower_values = np.array([self.lower_h.value(), self.lower_s.value(), self.lower_v.value()])
        upper_values = np.array([self.upper_h.value(), self.upper_s.value(), self.upper_v.value()])
        mask_test = cv2.inRange(self.image_hsv, lower_values, upper_values)
        image_bgr_masked = cv2.bitwise_and(self.image_bgr, self.image_bgr, mask=mask_test)
        self.image_rgb = cv2.cvtColor(image_bgr_masked, cv2.COLOR_BGR2RGB)
        self.update_image()

    def reset_values(self):
        self.lower_h.setValue(50)
        self.lower_s.setValue(100)
        self.lower_v.setValue(50)
        self.upper_h.setValue(130)
        self.upper_s.setValue(255)
        self.upper_v.setValue(255)

    def open_image(self):
        filename, _ = QFileDialog.getOpenFileName(self, "Select Image File", "", "Image Files (*.png *.jpg *.jpeg)")
        if filename:
            self.image_bgr = cv2.imread(filename)
            if self.image_bgr is not None:
                self.image_hsv = cv2.cvtColor(self.image_bgr, cv2.COLOR_BGR2HSV)
                self.update_hsv_range()  # This will apply current filter and update display

    def save_image(self):
        filename, _ = QFileDialog.getSaveFileName(self, "Save Image", "", "PNG Files (*.png);;JPEG Files (*.jpg)")
        if filename:
            # Make sure filename has an extension
            if not filename.endswith(('.png', '.jpg', '.jpeg')):
                filename += '.png'
            # Convert and save
            output_image = cv2.cvtColor(self.image_rgb, cv2.COLOR_RGB2BGR)
            cv2.imwrite(filename, output_image)

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

Sunday, November 24, 2024

Python 3.13.0 : emoji symbols with PIL.

Today I want to use emoji symbols and I wrote this python script:
from PIL import Image, ImageDraw, ImageFont
import os

# Font size and image dimensions
font_size = 88
width = 640
height = 480

# Use Symbola.ttf from current directory
font_path = "Symbola.ttf"

# Create image
img = Image.new('RGB', (width, height), color='white')
draw = ImageDraw.Draw(img)

# Get font
font = ImageFont.truetype(font_path, font_size)

# Emoji matrix
emoji_matrix = [
    ['😀', '😁', '😂', '🤣', '😃'],
    ['😄', '😅', '😆', '😇', '😈'],
    ['😉', '😊', '😋', '😌', '😍'],
    ['😎', '😏', '😐', '😑', '😒']
]

# Calculate spacing
x_spacing = font_size + 10
y_spacing = font_size + 10

# Calculate starting position to center the grid
start_x = (width - (len(emoji_matrix[0]) * x_spacing)) // 2
start_y = (height - (len(emoji_matrix) * y_spacing)) // 2

# Draw emojis
for i, row in enumerate(emoji_matrix):
    for j, emoji in enumerate(row):
        x = start_x + (j * x_spacing)
        y = start_y + (i * y_spacing)
        draw.text((x, y), emoji, font=font, fill='black')

# Save the image
img.save('emoji_art.png')
print("Emoji art has been created successfully! Check emoji_art.png")
The result image named emoji_art.png is this:

Wednesday, November 20, 2024

Python 3.13.0 : generates multiple deformed polygonal shapes .

Today I created this source code in python that generates eight random convex polygons. The idea was to create sprites for a 2D game: snowballs, boulders, or similar objects... Obviously I also used Sonet 3.5 artificial intelligence. You can find the source code on the pagure account in fedora.
#!/usr/bin/env python3
"""
SVG Polygon Generator

This script generates multiple deformed polygonal shapes and saves them as separate SVG files.
Each polygon maintains convex properties while having controlled random deformations.

Features:
    - Generates 8 unique polygonal shapes
    - Controls deformation through radial and angular factors
    - Maintains convex properties
    - Exports each shape to a separate SVG file
    - Uses random colors for visual distinction

Usage:
    python generate_svgs.py

Output:
    Creates 8 SVG files named 'polygon_1.svg' through 'polygon_8.svg'
"""

from lxml import etree
import random
import math
from pathlib import Path


def create_svg_root():
    """Create and return a base SVG root element with standard attributes."""
    root = etree.Element("svg")
    root.set("width", "500")
    root.set("height", "500")
    root.set("xmlns", "http://www.w3.org/2000/svg")
    return root


def calculate_points(center_x: float, center_y: float, radius: float, 
                    num_sides: int, deform_factor: float) -> list:
    """
    Calculate polygon points with controlled deformation.

    Args:
        center_x: X coordinate of polygon center
        center_y: Y coordinate of polygon center
        radius: Base radius of the polygon
        num_sides: Number of polygon sides
        deform_factor: Maximum allowed deformation factor

    Returns:
        List of tuples containing (x, y) coordinates
    """
    points = []
    angle_step = 2 * math.pi / num_sides
    
    for i in range(num_sides):
        angle = i * angle_step
        radial_deform = random.uniform(-deform_factor, deform_factor)
        angular_deform = random.uniform(-deform_factor/2, deform_factor/2)
        
        modified_angle = angle + angular_deform
        modified_radius = radius * (1 + radial_deform)
        
        x = center_x + modified_radius * math.cos(modified_angle)
        y = center_y + modified_radius * math.sin(modified_angle)
        points.append((x, y))
    
    return points


def generate_deformed_shapes():
    """Generate multiple deformed polygons and save them to separate SVG files."""
    # Base parameters
    num_sides = 8
    center_x = 250
    center_y = 250
    base_radius = 150
    max_deformation = 0.15
    output_dir = Path("generated_polygons")
    
    # Create output directory if it doesn't exist
    output_dir.mkdir(exist_ok=True)

    for i in range(8):
        root = create_svg_root()
        points = calculate_points(center_x, center_y, base_radius, 
                                num_sides, max_deformation)
        
        path = etree.SubElement(root, "path")
        path_data = f"M {points[0][0]} {points[0][1]}"
        path_data += "".join(f" L {p[0]} {p[1]}" for p in points[1:])
        path_data += " Z"
        
        path.set("d", path_data)
        path.set("fill", "none")
        path.set("stroke", f"#{random.randint(0, 16777215):06X}")
        path.set("stroke-width", "2")
        path.set("opacity", "0.7")

        # Save individual SVG file
        output_file = output_dir / f"polygon_{i+1}.svg"
        tree = etree.ElementTree(root)
        tree.write(str(output_file), pretty_print=True, 
                  xml_declaration=True, encoding='utf-8')
    
    print(f"Generated {num_sides} polygons in {output_dir}")

if __name__ == "__main__":
    generate_deformed_shapes()

Monday, November 18, 2024

Python 3.13.0 : Tested TinyDB on Fedora 41.

Today I tested the TinyDB python package on Fedora 41 Linux distro:
TinyDB is a lightweight document oriented database optimized for your happiness :) It’s written in pure Python and has no external dependencies. The target are small apps that would be blown away by a SQL-DB or an external database server.
The documentation for this python package can be found on the official website.
The install on Fedora 14 distro can be done with pip tool:
pip install tinydb
This is the source code I tested:
from tinydb import TinyDB, Query
import datetime

# Create a TinyDB instance
db = TinyDB('my_database.json')

# Define a schema for our documents
UserSchema = {
    'name': str,
    'email': str,
    'age': int,
    'created_at': datetime.datetime
}# Insert some sample data
users = [
    {'name': 'John Doe', 'email': 'john@example.com', 'age': 30},
    {'name': 'Jane Smith', 'email': 'jane@example.com', 'age': 25},
    {'name': 'Bob Johnson', 'email': 'bob@example.com', 'age': 35}
]

for user in users:
    db.insert(user)

# Querying all users
print("\nQuerying all users:")
all_users = db.all()
for user in all_users:
    print(f"Name: {user['name']}, Email: {user['email']}, Age: {user['age']}")

# Filtering data
print("\nFidig users older than 28:")
older_than_28 = db.search(Query().age > 28)
for user in older_than_28:
    print(f"Name: {user['name']}, Email: {user['email']}, Age: {user['age']}")

# Updating data
print("\nUpdatig John Doe's age:")
db.update({'age': 31}, Query().name == 'John Doe')

# Deleting data
print("\nDeletig Jane Smith:")
doc_ids = [doc.doc_id for doc in db.search(Query().email == 'jane@example.com')]
if doc_ids:
    db.remove(doc_ids=doc_ids)
else:
    print("No document found with email 'jane@example.com'")

# Adding a new field
print("\nAddig a 'city' field to all users:")
for user in db.all():
    user['city'] = 'New York'
    db.update(user, doc_ids=[doc.doc_id for doc in db.search(Query().name == user['name'])])

# Sorting data
print("\nSorting users by age:")
sorted_users = sorted(db.all(), key=lambda x: x['age'])
for user in sorted_users:
    print(f"Name: {user['name']}, Email: {user['email']}, Age: {user['age']}")

# Getting document count
print("\nTotal number of users:", len(db.all()))

# Closing the database connection
db.close()
This is the result:
$ python test_001.py 

Querying all users:
Name: John Doe, Email: john@example.com, Age: 31
Name: Bob Johnson, Email: bob@example.com, Age: 35
Name: John Doe, Email: john@example.com, Age: 31
Name: Bob Johnson, Email: bob@example.com, Age: 35
Name: John Doe, Email: john@example.com, Age: 31
Name: Bob Johnson, Email: bob@example.com, Age: 35
Name: John Doe, Email: john@example.com, Age: 31
Name: Bob Johnson, Email: bob@example.com, Age: 35
Name: John Doe, Email: john@example.com, Age: 31
Name: Bob Johnson, Email: bob@example.com, Age: 35
Name: John Doe, Email: john@example.com, Age: 31
Name: Bob Johnson, Email: bob@example.com, Age: 35
Name: John Doe, Email: john@example.com, Age: 31
Name: Bob Johnson, Email: bob@example.com, Age: 35
Name: John Doe, Email: john@example.com, Age: 31
Name: Bob Johnson, Email: bob@example.com, Age: 35
Name: John Doe, Email: john@example.com, Age: 31
Name: Bob Johnson, Email: bob@example.com, Age: 35
Name: John Doe, Email: john@example.com, Age: 31
Name: Bob Johnson, Email: bob@example.com, Age: 35
Name: John Doe, Email: john@example.com, Age: 30
Name: Jane Smith, Email: jane@example.com, Age: 25
Name: Bob Johnson, Email: bob@example.com, Age: 35

Fidig users older than 28:
Name: John Doe, Email: john@example.com, Age: 31
Name: Bob Johnson, Email: bob@example.com, Age: 35
Name: John Doe, Email: john@example.com, Age: 31
Name: Bob Johnson, Email: bob@example.com, Age: 35
Name: John Doe, Email: john@example.com, Age: 31
Name: Bob Johnson, Email: bob@example.com, Age: 35
Name: John Doe, Email: john@example.com, Age: 31
Name: Bob Johnson, Email: bob@example.com, Age: 35
Name: John Doe, Email: john@example.com, Age: 31
Name: Bob Johnson, Email: bob@example.com, Age: 35
Name: John Doe, Email: john@example.com, Age: 31
Name: Bob Johnson, Email: bob@example.com, Age: 35
Name: John Doe, Email: john@example.com, Age: 31
Name: Bob Johnson, Email: bob@example.com, Age: 35
Name: John Doe, Email: john@example.com, Age: 31
Name: Bob Johnson, Email: bob@example.com, Age: 35
Name: John Doe, Email: john@example.com, Age: 31
Name: Bob Johnson, Email: bob@example.com, Age: 35
Name: John Doe, Email: john@example.com, Age: 31
Name: Bob Johnson, Email: bob@example.com, Age: 35
Name: John Doe, Email: john@example.com, Age: 30
Name: Bob Johnson, Email: bob@example.com, Age: 35

Updatig John Doe's age:

Deletig Jane Smith:

Addig a 'city' field to all users:

Sorting users by age:
Name: John Doe, Email: john@example.com, Age: 31
Name: John Doe, Email: john@example.com, Age: 31
Name: John Doe, Email: john@example.com, Age: 31
Name: John Doe, Email: john@example.com, Age: 31
Name: John Doe, Email: john@example.com, Age: 31
Name: John Doe, Email: john@example.com, Age: 31
Name: John Doe, Email: john@example.com, Age: 31
Name: John Doe, Email: john@example.com, Age: 31
Name: John Doe, Email: john@example.com, Age: 31
Name: John Doe, Email: john@example.com, Age: 31
Name: John Doe, Email: john@example.com, Age: 31
Name: Bob Johnson, Email: bob@example.com, Age: 35
Name: Bob Johnson, Email: bob@example.com, Age: 35
Name: Bob Johnson, Email: bob@example.com, Age: 35
Name: Bob Johnson, Email: bob@example.com, Age: 35
Name: Bob Johnson, Email: bob@example.com, Age: 35
Name: Bob Johnson, Email: bob@example.com, Age: 35
Name: Bob Johnson, Email: bob@example.com, Age: 35
Name: Bob Johnson, Email: bob@example.com, Age: 35
Name: Bob Johnson, Email: bob@example.com, Age: 35
Name: Bob Johnson, Email: bob@example.com, Age: 35
Name: Bob Johnson, Email: bob@example.com, Age: 35

Total number of users: 22

Saturday, November 16, 2024

Python 3.13.0 : Test the gi python package on Fedora distro linux.

The gi (GObject Introspection) Python package is excellent! It provides Python bindings for GObject-based libraries like GTK, GLib, and Secret Service. It enables you to write native GNOME applications in Python and access system services seamlessly.
First, install these Fedora packages:
[mythcat@fedora ~]# dnf5 install python3-gobject libsecret-devel
...
Package "python3-gobject-3.48.2-3.fc41.x86_64" is already installed.
Package "libsecret-devel-0.21.4-3.fc41.x86_64" is already installed.
...
[mythcat@fedora ~]# dnf5 install gnome-shell gnome-keyring libsecret
...
I used this simple python source code to test the gi python package:
import gi

# Specify the version of Gio and Secret we want to use
gi.require_version('Gio', '2.0')
gi.require_version('Secret', '1')

from gi.repository import Gio, Secret, GLib

def check_schema(schema_name):
    try:
        Gio.Settings.new(schema_name)
        print(f"Schema '{schema_name}' is available")
        return True
    except GLib.GError as e:
        print(f"Schema '{schema_name}' is not installed: {str(e)}")
        return False

def store_secret():
    schema = Secret.Schema.new("org.example.Password",
        Secret.SchemaFlags.NONE,
        {
            "username": Secret.SchemaAttributeType.STRING,
        }
    )
    
    Secret.password_store_sync(schema, 
        {"username": "myuser"},
        Secret.COLLECTION_DEFAULT,
        "My secret item",
        "Hello, World!",
        None)
    
    print("Secret stored successfully")

def get_secret():
    schema = Secret.Schema.new("org.example.Password",
        Secret.SchemaFlags.NONE,
        {
            "username": Secret.SchemaAttributeType.STRING,
        }
    )
    
    password = Secret.password_lookup_sync(schema,
        {"username": "myuser"},
        None)
    
    if password is not None:
        print(f"Retrieved secret: {password}")
    else:
        print("No secret found")

if __name__ == "__main__":
    print("Starting secret operations...")
    store_secret()
    get_secret()
    print("Finished secret operations.")
The result is this:
$ python test_001.py 
Starting secret operations...
Secret stored successfully
Retrieved secret: Hello, World!
Finished secret operations.

Sunday, October 27, 2024

Python 3.13.0 : know this -OOt ?

Today, I follow the actions from NEMO the basic explorer files from linux and I found this: -OOt
This first source code:
#!/usr/bin/python3 -OOt
... this is new, and refers to Python compiler optimizations.
The -OOt par in the shebang line #!/usr/bin/python3 -OOt refers to Python compiler optimizations:
  1. -O: This flag enables basic optimizations. It tells the Python compiler to optimize constants and global variables.
  2. -O2: This flag enables more aggressive optimizations. It applies additional compiler passes to further optimize the code .
  3. -Ot: This flag optimizes for size. It reduces memory usage by eliminating unused variables and dead code.
So, -OOt combines three levels of optimization:
  • Basic optimization (-O)
  • More aggressive optimization (-O2)
  • Optimization for size (-Ot)