analitics

Pages

Showing posts with label python3. Show all posts
Showing posts with label python3. Show all posts

Saturday, July 5, 2025

Python 3.13.5 : the groq tested with basic example !

About groq you can find on the official Grok website .
Today I tested the groq A.P.I. with the basic example :
import os

from groq import Groq

client = Groq(
    api_key="gsk_..."
)

chat_completion = client.chat.completions.create(
    messages=[
        {
            "role": "user",
            "content": "explain what groq is",
        }
    ],
    model="llama-3.3-70b-versatile",
)

print(chat_completion.choices[0].message.content)
The result of : "explain what groq is" is that :
Groq is a relatively new and innovative technology company that focuses on developing high-performance, artificial intelligence (AI) computing hardware and software solutions. Founded in 2016 by Jonathan Ross, a former Google engineer, Groq aims to provide faster, more efficient, and scalable AI computing capabilities to various industries. Groq's primary product is a tensor processing unit (TPU) chip designed specifically for machine learning (ML) and deep learning (DL) workloads. This TPU is optimized for high-performance, low-latency, and low-power consumption, making it suitable for applications that require rapid processing of vast amounts of data, such as: 1. **Computer Vision**: Image and video recognition, object detection, and tracking. 2. **Natural Language Processing (NLP)**: Text analysis, sentiment analysis, and language translation. 3. **Speech Recognition**: Voice command processing and speech-to-text applications. Groq's innovative architecture and design philosophy are centered around the following key aspects: 1. **High-Bandwidth Memory**: Groq's TPU features high-bandwidth memory, which enables fast data transfer and processing. 2. **Scalable Architecture**: The TPU is designed to scale horizontally, allowing for easy expansion to meet growing computational demands. 3. **Low-Latency**: Groq's architecture minimizes latency, ensuring fast response times and real-time processing capabilities. 4. **Software-Defined**: The TPU is software-defined, allowing for flexibility and customization to support a wide range of AI applications and frameworks. Groq's technology has the potential to accelerate AI adoption in various industries, including: 1. **Autonomous Vehicles**: Enhanced computer vision and sensor processing for safer and more efficient autonomous driving. 2. **Healthcare**: Faster medical image analysis and diagnosis, as well as improved personalized medicine and treatment planning. 3. **Financial Services**: Enhanced risk analysis, portfolio optimization, and fraud detection using AI-powered systems. While Groq is still a relatively new company, its innovative approach to AI computing has garnered significant attention and interest from the tech industry, investors, and potential customers. As AI continues to transform various aspects of our lives, Groq's technology is poised to play a significant role in shaping the future of artificial intelligence and machine learning.

Tuesday, July 1, 2025

Python 3.13.5 : use the jupyterlab, notebook and voila - part 001.

JupyterLab is the latest web-based interactive development environment for notebooks, code, and data. Its flexible interface allows users to configure and arrange workflows in data science, scientific computing, computational journalism, and machine learning. A modular design invites extensions to expand and enrich functionality.
Let's test with these python modules: jupyterlab, notebook and voila.
First, I install with pip tool the jupyterlab python module:
pip install jupyterlab
Collecting jupyterlab
...
Successfully installed anyio-4.9.0 argon2-cffi-25.1.0 argon2-cffi-bindings-21.2.0 arrow-1.3.0 asttokens-3.0.0 async-lru-2.0.5
attrs-25.3.0 babel-2.17.0 bleach-6.2.0 cffi-1.17.1 comm-0.2.2 debugpy-1.8.14 defusedxml-0.7.1 executing-2.2.0 
fastjsonschema-2.21.1 fqdn-1.5.1 h11-0.16.0 httpcore-1.0.9 httpx-0.28.1 ipykernel-6.29.5 ipython-9.4.0 
ipython-pygments-lexers-1.1.1 isoduration-20.11.0 jedi-0.19.2 json5-0.12.0 jsonpointer-3.0.0 jsonschema-4.24.0 
jsonschema-specifications-2025.4.1 jupyter-client-8.6.3 jupyter-core-5.8.1 jupyter-events-0.12.0 jupyter-lsp-2.2.5 
jupyter-server-2.16.0 jupyter-server-terminals-0.5.3 jupyterlab-4.4.4 jupyterlab-pygments-0.3.0 jupyterlab-server-2.27.3 
matplotlib-inline-0.1.7 mistune-3.1.3 nbclient-0.10.2 nbconvert-7.16.6 nbformat-5.10.4 nest-asyncio-1.6.0 notebook-shim-0.2.4
overrides-7.7.0 pandocfilters-1.5.1 parso-0.8.4 platformdirs-4.3.8 prometheus-client-0.22.1 prompt_toolkit-3.0.51 
psutil-7.0.0 pure-eval-0.2.3 pycparser-2.22 python-json-logger-3.3.0 pywin32-310 pywinpty-2.0.15 pyyaml-6.0.2 pyzmq-27.0.0
referencing-0.36.2 rfc3339-validator-0.1.4 rfc3986-validator-0.1.1 rpds-py-0.26.0 send2trash-1.8.3 sniffio-1.3.1 
stack_data-0.6.3 terminado-0.18.1 tinycss2-1.4.0 tornado-6.5.1 traitlets-5.14.3 types-python-dateutil-2.9.0.20250516 
uri-template-1.3.0 wcwidth-0.2.13 webcolors-24.11.1 webencodings-0.5.1 websocket-client-1.8.0
Next, the install of the notebook python module
pip install notebook
Collecting notebook
...
Installing collected packages: notebook
Successfully installed notebook-7.4.4
This python package named voila will help us to use online graphic user interfaces:
pip install voila
Collecting voila
...
Successfully installed voila-0.5.8 websockets-15.0.1
The voila package need to work with ipywidgets python package:
pip install ipywidgets
Collecting ipywidgets
...
Successfully installed ipywidgets-8.1.7 jupyterlab_widgets-3.0.15 widgetsnbextension-4.0.14
Let's start the jupiter tool with this command:
jupyter notebook
I used an default python example with a slider:
import ipywidgets as widgets
from IPython.display import display

slider = widgets.IntSlider(value=5, min=0, max=10)
display(slider)
This command will start the web with the slider using the voila command:
voila test.ipynb
The result is this:

Friday, June 27, 2025

Python 3.13.5 : the manim python module - part 001.

I used this package few days ago and now I wrote about how can used it.
Update the new release of pip is available: 25.0.1 -> 25.1.1 , run this command:
python.exe -m pip install --upgrade pip
The documentation can be found on the official website.
pip install manim
Collecting manim
  Downloading manim-0.19.0-py3-none-any.whl.metadata (11 kB)
...
Successfully installed Pillow-11.2.1 Pygments-2.19.1 audioop-lts-0.2.1 av-13.1.0 beautifulsoup4-4.13.4 click-8.2.1 cloup-3.0.7 colorama-0.4.6 decorator-5.2.1 glcontext-3.0.0 isosurfaces-0.1.2 manim-0.19.0 manimpango-0.6.0 mapbox-earcut-1.0.3 markdown-it-py-3.0.0 mdurl-0.1.2 moderngl-5.12.0 moderngl-window-3.1.1 networkx-3.5 numpy-2.3.0 pycairo-1.28.0 pydub-0.25.1 pyglet-2.1.6 pyglm-2.8.2 rich-14.0.0 scipy-1.15.3 screeninfo-0.8.1 skia-pathops-0.8.0.post2 soupsieve-2.7 srt-3.5.3 svgelements-1.9.6 tqdm-4.67.1 typing-extensions-4.14.0 watchdog-6.0.0
Let's see how can be used to see the help area:
python.exe -m manim render --help
Manim Community v0.19.0

Usage: python -m manim render ...
Let's use this source code:
from manim import *

class AdvancedAnimation(Scene):
    def construct(self):
        # Scene 1: Introduction
        title = Text("Advanced Animation with Manim").scale(0.76)
        self.play(FadeIn(title))
        self.wait(2)

        # Scene 2: Custom Animation
        circle = Circle().set_fill(color=BLUE, opacity=0.5)
        square = Square().set_fill(color=RED, opacity=0.5)
        self.add(circle, square)
        self.play(
            Rotate(circle, angle=TAU),
            Rotate(square, angle=-TAU),
            run_time=2,
            rate_func=linear
        )
        self.wait()

        # Scene 3: Text Animation
        text = Text("This is a custom text animation", font_size=40).to_edge(UP)
        self.play(Write(text), run_time=2)
        self.wait()

        # Scene 4: Shapes Manipulation
        triangle = Triangle().shift(RIGHT * 2)
        self.play(GrowFromCenter(triangle), run_time=1.5)
        self.wait()

        # Scene 5: Transition to next scene
        self.play(Uncreate(triangle), FadeOut(text))

        # Scene 6: Final Animation
        final_text = Text("This is the end of our animation", font_size=50).to_edge(DOWN)
        self.play(FadeIn(final_text), run_time=1.5)
        self.wait(2)

# Run the animation
AdvancedAnimation()
Use this command to render:
python.exe -m manim render manim_test_001.py AdvancedAnimation -p
AdvancedAnimation -p
Manim Community v0.19.0

[06/27/25 19:52:43] INFO     Animation 0 : Partial movie file      scene_file_writer.py:588
                             written in
                             'D:\PythonProjects\manim_projects\med
                             ia\videos\manim_test_001\1080p60\part
                             ial_movie_files\AdvancedAnimation\397
                             7891868_355746014_223132457.mp4'
...
[06/27/25 19:53:56] INFO     Previewed File at:                             file_ops.py:237
                             'D:\PythonProjects\manim_projects\media\videos
                             \manim_test_001\1080p60\AdvancedAnimation.mp4'
The result comes with many files, see this 1080p60 video result:

Tuesday, June 24, 2025

Python 3.13.5 : Get bookmarks from Edge browser with python.

Today I tested with these python modules json and pathlib.
This python script will get all bookmarks from Edge browser:
import json
from pathlib import Path

bookmark_path = Path.home() / "AppData/Local/Microsoft/Edge/User Data/Default/Bookmarks"

with open(bookmark_path, "r", encoding="utf-8") as f:
    data = json.load(f)

# Exemplu: listăm toate titlurile bookmark-urilor
def extract_bookmarks(bookmark_node):
    bookmarks = []
    if "children" in bookmark_node:
        for child in bookmark_node["children"]:
            bookmarks.extend(extract_bookmarks(child))
    elif bookmark_node.get("type") == "url":
        bookmarks.append((bookmark_node["name"], bookmark_node["url"]))
    return bookmarks

all_bookmarks = extract_bookmarks(data["roots"]["bookmark_bar"])
for name, url in all_bookmarks:
    print(f"{name}: {url}")

Friday, June 20, 2025

Python 3.13.5 : testing with flask, request and playwright python module.

Today some testing with these python modules: flask, request and playwright.
I used pip to install flask python package:
pip install flask
Collecting flask
  Downloading flask-3.1.1-py3-none-any.whl.metadata (3.0 kB)
...
Installing collected packages: markupsafe, itsdangerous, blinker, werkzeug, jinja2, flask
Successfully installed blinker-1.9.0 flask-3.1.1 itsdangerous-2.2.0 jinja2-3.1.6 markupsafe-3.0.2 werkzeug-3.1.3
pip install requests
...
Installing collected packages: urllib3, idna, charset_normalizer, certifi, requests
Successfully installed certifi-2025.6.15 charset_normalizer-3.4.2 idna-3.10 requests-2.32.4 urllib3-2.5.0
pip install playwright
Collecting playwright
...
Installing collected packages: pyee, greenlet, playwright
Successfully installed greenlet-3.2.3 playwright-1.52.0 pyee-13.0.0
...
playwright install
Downloading Chromium 136.0.7103.25 ...
This will download a lot fo files and the will install the playwright tool.
First script is simple one will try to get cloudflare header on default ip:
from flask import Flask, request

app = Flask(__name__)

@app.route("/")
def detecteaza_ipuri():
    ip_client = request.headers.get('CF-Connecting-IP', 'Necunoscut')
    ip_cloudflare = request.remote_addr
    return (
        f"IP real vizitator: {ip_client}
" f"IP Cloudflare (vizibil de server): {ip_cloudflare}" ) if __name__ == "__main__": app.run(debug=True)
The next one will check more ...
from flask import Flask, request
import requests
import ipaddress

app = Flask(__name__)

def este_ip_cloudflare(ip):
    try:
        raspuns = requests.get("https://www.cloudflare.com/ips-v4")
        raspuns.raise_for_status()
        subneturi = raspuns.text.splitlines()

        for subnet in subneturi:
            if ipaddress.ip_address(ip) in ipaddress.ip_network(subnet):
                return True
        return False
    except Exception as e:
        return f"Eroare la verificarea IP-ului Cloudflare: {e}"

@app.route("/")
def detecteaza_ipuri():
    ip_client = request.headers.get('CF-Connecting-IP', 'Necunoscut')
    ip_cloudflare = request.remote_addr
    rezultat = este_ip_cloudflare(ip_cloudflare)

    return (
        f"IP real vizitator: {ip_client}
" f"IP Cloudflare (forwarder): {ip_cloudflare}
" f"Este IP-ul din rețeaua Cloudflare? {'DA' if rezultat == True else 'NU' if rezultat == False else rezultat}" ) if __name__ == "__main__": app.run(host="0.0.0.0", port=5000)
Now, the script with the request python module:
import requests

url = "https://cobalt.tools"
headers = {
    "User-Agent": "Mozilla/5.0",  # Simulează un browser real
}

try:
    r = requests.get(url, headers=headers, timeout=10)
    content = r.text.lower()

    print(f"Cod răspuns HTTP: {r.status_code}")

    if "cloudflare" in content or "cf-ray" in content or "attention required" in content:
        print("Cloudflare a intermediat cererea sau a blocat-o cu o pagină specială.")
    else:
        print("Cererea a fost servită normal.")
except Exception as e:
    print(f"Eroare la conexiune: {e}")
The last one will use the playwright python module:
import sys
import re
from urllib.parse import urlparse
from pathlib import Path
from playwright.sync_api import sync_playwright

def converteste_url_in_nume_fisier(url):
    parsed = urlparse(url)
    host = parsed.netloc.replace('.', '_')
    path = parsed.path.strip('/').replace('/', '_')
    if not path:
        path = 'index'
    return f"{host}_{path}.txt"

if len(sys.argv) != 2:
    print("Utilizare: python script.py https://exemplu.com")
    sys.exit(1)

url = sys.argv[1]
fisier_output = converteste_url_in_nume_fisier(url)

with sync_playwright() as p:
    browser = p.chromium.launch(headless=True)
    pagina = browser.new_page()
    pagina.goto(url, wait_until='networkidle')
    continut = pagina.content()
    Path(fisier_output).write_text(continut, encoding='utf-8')
    browser.close()

print(f"Conținutul a fost salvat în: {fisier_output}")
This will create a file with the source code of web page.

Sunday, December 29, 2024

Python 3.13.0 : Only the unstructured library in Fedora 41 ...

The unstructured library provides open-source components for ingesting and pre-processing images and text documents, such as PDFs, HTML, Word docs, and many more. The use cases of unstructured revolve around streamlining and optimizing the data processing workflow for LLMs. unstructured modular functions and connectors form a cohesive system that simplifies data ingestion and pre-processing, making it adaptable to different platforms and efficient in transforming unstructured data into structured outputs.
I used pip tool to install this python package:
mythcat@fedora:~$ pip install unstructured
Defaulting to user installation because normal site-packages is not writeable
Collecting unstructured
  Downloading unstructured-0.11.8-py3-none-any.whl.metadata (26 kB)
...
Successfully installed aiofiles-24.1.0 annotated-types-0.7.0 anyio-4.7.0 backoff-2.2.1 beautifulsoup4-4.12.3 chardet-5.2.0 click-8.1.8 cryptography-44.0.0 dataclasses-json-0.6.7 emoji-2.14.0 eval-type-backport-0.2.2 filetype-1.2.0 h11-0.14.0 httpcore-1.0.7 httpx-0.28.1 jsonpath-python-1.0.6 langdetect-1.0.9 marshmallow-3.23.2 mypy-extensions-1.0.0 nest-asyncio-1.6.0 nltk-3.9.1 pydantic-2.9.2 pydantic-core-2.23.4 pypdf-5.1.0 python-iso639-2024.10.22 python-magic-0.4.27 rapidfuzz-3.11.0 requests-toolbelt-1.0.0 sniffio-1.3.1 soupsieve-2.6 tabulate-0.9.0 tqdm-4.67.1 typing-extensions-4.12.2 typing-inspect-0.9.0 unstructured-0.11.8 unstructured-client-0.28.1 wrapt-1.17.0
But I got error on the unstructured-inference:
pip install unstructured-inference
Collecting unstructured-inference
...
  note: This error originates from a subprocess, and is likely not a problem with pip.
  ERROR: Failed building wheel for onnx
Failed to build onnx
ERROR: ERROR: Failed to build installable wheels for some pyproject.toml based projects (onnx)
... and errors on unstructured[pdf]:
mythcat@fedora:~$ pip install unstructured[pdf]
...
  note: This error originates from a subprocess, and is likely not a problem with pip.
  ERROR: Failed building wheel for onnx
Failed to build onnx
ERROR: ERROR: Failed to build installable wheels for some pyproject.toml based projects (onnx)

Saturday, March 9, 2024

News : All Books Bundle from Michael Driscoll

  • Get a copy of all my self-published Python eBooks :
  • Python 101 - 2nd Edition
  • Python 201: Intermediate Python
  • ReportLab: PDF Processing with Python
  • Jupyter Notebook 101
  • Creating GUI Applications with Python
  • Pillow: Image Processing with Python
  • Automating Excel with Python
  • The Python Quiz Book

News : Website for Python users.

Here is a site called clcoding.com for those who use the python language with many simple examples and even a test fairy: python coding challenge day.

Friday, October 13, 2023

Python tool oletools.

The recommended Python version to run oletools is the latest Python 3.x (3.9 for now). Python 2.7 is still supported for the moment, even if it reached end of life in 2020 (for projects still using Python 2/PyPy 2 such as ViperMonkey). It is highly recommended to switch to Python 3 if possible.
You can find it on this GitHub project.
See the all tools : mraptor, msodde, olebrowse, oledir, oleid, olemap, olemeta, oleobj, oletimes, olevba, pyxswf, rtfobj.

Saturday, August 12, 2023

Python 3.10.12 : My colab tutorials and news from colab - part 036.

Today I recapitulated a bit the artificial intelligence part and a simple example for google drive.
I created two notebooks in collaboration and added them to my github repo.
The most interesting is the one with textgenrnn.
textgenrnn is an modern neural network architecture which utilizes new techniques as attention-weighting and skip-embedding to accelerate training
The last notebook colab is catafest_045.

Thursday, August 10, 2023

Python 3.10.12 : My colab tutorials and news from colab - part 035.

In this notebook I will show you how to use python to run a program written in the programming language for CUDA.
This allows you to use NVIDIA CUDA Compiler Driver NVCC, see this official webpage.
NVCC Plugin for Jupyter Notebook by https://github.com/andreinechaev/nvcc4jupyter.
The example I tested is simple:
# This is formatted as CUDA code
__global__ void cuda_hello(){
    printf("Hello World from GPU!\n");
}

int main() {
    cuda_hello<<<1,1>>>();
    return 0;
}

Tuesday, July 11, 2023

Python 3.8.10 : My colab tutorials and news from colab - part 034.

I add a new colab notebook with a simple source code to list all running VM processes from the colab notebook
You can see more examples on my GitHub colab google repo.
This is the source code:
%%sh
echo "List all running VM processes."
ps -ef
echo "Done"

Sunday, June 11, 2023

Python Qt6 : Download for youtube with PyQt6.

Simple example with PyQt6 to create an interface to download a video using a URL from youtube.
This simple example has some limitations, the filtering of the results is done according to the possibilities of the pytube mode and only after video, it does not use multithread and it does not have multiple selection possibilities and options. In conclusion, it offers a simple download functionality.
You can see more on my GitHub account.
import sys
from PyQt6.QtWidgets import QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout, QLineEdit, QPushButton, QProgressBar, QDialog, QComboBox, QLabel, QMessageBox
from PyQt6.QtGui import QIcon, QPixmap
from pytube import YouTube
from PyQt6.QtCore import Qt
from PyQt6.QtWidgets import QDialogButtonBox


class FormatChecker:
    def __init__(self, url):
        self.url = url

    def check_formats(self):
        try:
            yt = YouTube(self.url)
            formats = []
            streams = yt.streams.filter(only_video=True)
            for stream in streams:
                if stream.url:
                    format_info = {
                        'resolution': stream.resolution,
                        'file_extension': stream.mime_type.split("/")[-1]
                    }
                    formats.append(format_info)
                    print(" format_info ",format_info)
            return formats
        except Exception as e:
            print("Error:", str(e))
            return []


class FormatInfo:
    def __init__(self, resolution, file_formats):
        self.resolution = resolution
        self.file_formats = file_formats


class ResolutionDialog(QDialog):
    def __init__(self, formats, parent=None):
        super().__init__(parent)
        self.setWindowTitle("Select Resolution and File Format")
        self.formats = formats

        layout = QVBoxLayout(self)

        self.resolution_combo = QComboBox(self)
        for format_info in formats:
            resolution = format_info.resolution
            self.resolution_combo.addItem(resolution)
        layout.addWidget(self.resolution_combo)

        self.file_format_combo = QComboBox(self)
        self.update_file_formats(self.resolution_combo.currentText())
        layout.addWidget(self.file_format_combo)

        button_box = QDialogButtonBox(QDialogButtonBox.StandardButton.Ok | QDialogButtonBox.StandardButton.Cancel)
        button_box.accepted.connect(self.accept)
        button_box.rejected.connect(self.reject)
        layout.addWidget(button_box)

        self.resolution_combo.currentIndexChanged.connect(self.on_resolution_changed)

    def update_file_formats(self, resolution):
        self.file_format_combo.clear()
        for format_info in self.formats:
            if format_info.resolution == resolution:
                file_formats = format_info.file_formats
                self.file_format_combo.addItems(file_formats)

    def selected_resolution(self):
        return self.resolution_combo.currentText()

    def selected_file_format(self):
        return self.file_format_combo.currentText()

    def on_resolution_changed(self, index):
        resolution = self.resolution_combo.currentText()
        self.update_file_formats(resolution)


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("YouTube Downloader - selected - only_video =True")
        self.setFixedWidth(640)

        central_widget = QWidget(self)
        self.setCentralWidget(central_widget)

        layout = QVBoxLayout(central_widget)

        self.url_edit = QLineEdit()
        layout.addWidget(self.url_edit)

        download_button = QPushButton("Download")
        download_button.clicked.connect(self.show_resolution_dialog)
        layout.addWidget(download_button)

        progress_layout = QHBoxLayout()
        layout.addLayout(progress_layout)

        self.progress_bar = QProgressBar()
        self.progress_bar.setTextVisible(True)
        progress_layout.addWidget(self.progress_bar)

        self.progress_icon_label = QLabel(self)
        pixmap = QPixmap("youtube.png")  # Înlocuiți "path_to_icon.png" cu calea către iconul dorit
        self.progress_icon_label.setPixmap(pixmap)
        progress_layout.addWidget(self.progress_icon_label)

    def show_resolution_dialog(self):
        url = self.url_edit.text()
        if url:
            format_checker = FormatChecker(url)
            formats = format_checker.check_formats()
            format_infos = []
            for format in formats:
                resolution = format['resolution']
                file_extension = format['file_extension']
                format_info = next((info for info in format_infos if info.resolution == resolution), None)
                if format_info:
                    format_info.file_formats.append(file_extension)
                else:
                    format_info = FormatInfo(resolution, [file_extension])
                    format_infos.append(format_info)

            dialog = ResolutionDialog(format_infos, self)
            if dialog.exec() == QDialog.DialogCode.Accepted:
                resolution = dialog.selected_resolution()
                file_format = dialog.selected_file_format()
                self.download_video(url, resolution, file_format)
        else:
            print("Please enter a valid YouTube URL.")

    def download_video(self, url, resolution, file_format):
        try:
            yt = YouTube(url)
            stream = yt.streams.filter(only_video=True, resolution=resolution, mime_type="video/" + file_format).first()
            if stream:
                stream.download()
                print("Download completed!")
                QMessageBox.question(self, "Download Completed", "The video has been downloaded successfully.", QMessageBox.StandardButton.Ok)
            else:
                print("Error: The selected video format is not available for download.")
                QMessageBox.question(self, "Download Error", "The selected video format is not available for download.", QMessageBox.StandardButton.Ok)
        except Exception as e:
            print("Error:", str(e))
            QMessageBox.question(self, "Download Error", "An error occurred during the download.", QMessageBox.StandardButton.Ok)


def main():
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec())


if __name__ == "__main__":
    main()

Thursday, March 9, 2023

Python 3.11.0 : The yattag python package.

Yattag is a Python library for generating HTML or XML in a pythonic way.
You can find more information on the official webpage.
Installation can be done easily with the pip utility:
pip install yattag --user
I test a simple example code from the official documentation and works well:
from yattag import Doc

doc, tag, text = Doc(
    defaults = {
        'title': 'Untitled',
        'contact_message': 'You just won the lottery!'
    },
    errors = {
        'contact_message': 'Your message looks like spam.'
    }
).tagtext()

with tag('h1'):
    text('Contact form')
with tag('form', action = ""):
    doc.input(name = 'title', type = 'text')
    with doc.textarea(name = 'contact_message'):
        pass
    doc.stag('input', type = 'submit', value = 'Send my message')

print(doc.getvalue())

Sunday, March 5, 2023

Python Qt5 : OpenStreetMap with PyQtWebEngine.

You need to install the PyQtWebEngine python package and to have the PyQt5 python package installed.
PyQt6 works in the same way as PyQt5 but with small differences ...
pip install PyQtWebEngine --user
Collecting PyQtWebEngine
  Downloading PyQtWebEngine-5.15.6-cp37-abi3-win_amd64.whl (182 kB)
     ---------------------------------------- 182.7/182.7 kB 580.6 kB/s eta 0:00:00
...
     ---------------------------------------- 60.0/60.0 MB 655.7 kB/s eta 0:00:00
...
Installing collected packages: PyQtWebEngine-Qt5, PyQtWebEngine
Successfully installed PyQtWebEngine-5.15.6 PyQtWebEngine-Qt5-5.15.2
import sys
from PyQt5.QtWebEngineWidgets import QWebEngineView
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout

class MapWidget(QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)

        # Create a QWebEngineView object to display the map
        self.map = QWebEngineView()
        self.map.setHtml("""
            <!DOCTYPE html>
            <html>
                <head>
                    <meta name="viewport" content="width=device-width, initial-scale=1.0">
                    <style>
                        #map {
                            height: 100%;
                        }
                    </style>
                </head>
                <body>
                    <div id="map"></div>
                    <script src="https://openlayers.org/en/v4.6.5/build/ol.js"></script>
                    <script>
                        var map = new ol.Map({
                            target: 'map',
                            layers: [
                                new ol.layer.Tile({
                                    source: new ol.source.OSM()
                                })
                            ],
                            view: new ol.View({
                                center: ol.proj.fromLonLat([0, 0]),
                                zoom: 2
                            })
                        });
                    </script>
                </body>
            </html>
        """)

        # Create a QVBoxLayout to hold the map widget
        layout = QVBoxLayout()
        layout.addWidget(self.map)
        self.setLayout(layout)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    widget = MapWidget()
    widget.show()
    sys.exit(app.exec_())
The run of this python script will show a window with the OpenStreetMap map.

Sunday, March 13, 2022

Python : Issues with python install - part 001.

I use python as an additional programming language for useful little things, testing for tutorials, and because I use the Blender 3D program.
This involves using it in Visual Code and command line with various versions of python that require separate installations.
Although the development team of the python program makes major changes to maintain and improve these separate installations on various versions, especially on the Windows operating system, they put their management in trouble.
There are plenty of examples on the web with questions and answers.
Here's a simple one, if you run the python command line and the Windows store opens then some settings are not set correctly
Use the Start button and on the Windows search bar to find Manage application run aliases.
There should be two python aliases, deselect them, this will allow the usual python aliases python and python3.
This deselect will delete two files on this folder:
cd %localappdata%\Microsoft\WindowsApps

C:\Users\YOUR_USER\AppData\Local\Microsoft\WindowsApps>dir python*
If you select these the file will be in that folder.
To solve this issue you need to deselect all python or remove the python files from the folder: \YOUR_USER\AppData\Local\Microsoft\WindowsApps.
After that, you need to go on Add or remove programs windows settings area from your operating system and repair select your python install press Modify button and select: Add python to environment variables.
This will fix the path for your python installation.
Now the python 3.10.2 installer come with one update feature, see the next screenshot:
If I run the python command python --version to see my python install on folder C:\Python310, the result is this: Python 3.10.2.
When you enter the python command, it searches the directories listed in your path environment variables page from top to bottom.
Will be great if these python installations will be managed, updated, and fixed properly by the installer, I see something similar in the Unity 3D Hub.
Let's see another example that shows us why it needs well-managed software for python versions.
If you try to install gravityai python package then you can do it easy on colab google with python version 3.7.12.
The bad part comes when you can try to use this version with a simple python windows installer because not all Windows executable installers are available for this python version.
This research needs time and finally, I found a good python version 3.7.9 for this package.
First I got this error:
C:\Python379>python.exe -m pip install --upgrade pip
Requirement already satisfied: pip in c:\users\
...
ERROR: Exception:
...
ValueError: Unable to find resource t64.exe in package pip._vendor.distlib
WARNING: You are using pip version 21.1.3; however, version 22.0.4 is available.
You should consider upgrading via the 'C:\Python379\python.exe -m pip install --upgrade pip' command.
I uninstall the setuptools with this command because python is set to the old install python 3.10.2 and give that error:
python -m pip uninstall pip setuptools
Found existing installation: pip 21.1.3
Uninstalling pip-21.1.3:
...
Uninstalling setuptools-57.2.0:
I upgrade with the pip tool my new python version 3.7.9 version.
python.exe -m pip install --upgrade pip
Requirement already satisfied: pip in c:\python379\lib\site-packages (22.0.4)
The last step is to use python.exe not the python command from my Python379 folder to install the gravityai python package.
C:\Python379>python.exe -m pip install gravityai
Collecting gravityai
  Using cached gravityai-0.1.3.post1.tar.gz (6.5 kB)
  Preparing metadata (setup.py) ... done
Collecting pathlib~=1.0.1
  Using cached pathlib-1.0.1.tar.gz (49 kB)
  Preparing metadata (setup.py) ... done
Collecting websockets~=9.1
  Downloading websockets-9.1-cp37-cp37m-win_amd64.whl (90 kB)
     ---------------------------------------- 90.2/90.2 KB 850.2 kB/s eta 0:00:00
Collecting asyncio~=3.4.3
  Downloading asyncio-3.4.3-py3-none-any.whl (101 kB)
     ---------------------------------------- 101.8/101.8 KB 1.2 MB/s eta 0:00:00
...
Successfully built gravityai pathlib
Installing collected packages: pathlib, asyncio, websockets, gravityai
Successfully installed asyncio-3.4.3 gravityai-0.1.3.post1 pathlib-1.0.1 websockets-9.1
Now I can use this package with python and python.exe commands in the Python379 folder.
Another useful command to have a good image of the install for pip tool is this:
python -m pip install --no-cache-dir  --force-reinstall -Iv gravityai
...
full command: 'C:\Python310\python.exe' -c '
...
exec(compile(setup_py_code, filename, "exec"))
This full output will give you information about the steps for installing the package, in this case, the uninstall and install the setuptools.
This option for the install process is --ignore-installed and let you install a new version of the package and keep the old one, see example command for gravityai package.
pip install gravityai --ignore-installed

Sunday, July 4, 2021

Python Qt5 : Parse files and show image with QPixmap .

This tutorial is about how to create a simple script in python with a few features:
You can see I used these python packages: argparse, PIL, glob, io, PyQt5 to fulfill the issue.
The PIL python package is used to use PNG images.
The argparse python package is used to get inputs from arguments.
The glob python package is used to parse folders and files.
The io python package is used to open images:
The PyQt5 python package is used to show images on canvas:
This is the source code in python I used to parse a folder with images and show one image:
import os
import io
import sys
import glob

from PIL import Image
from PIL import UnidentifiedImageError

from PyQt5.QtGui import QPixmap
from PyQt5.QtWidgets import QMainWindow, QApplication, QLabel

import argparse
from pathlib import Path

parser = argparse.ArgumentParser()

parser.add_argument("files_path", type=Path, help='PATH of folder with files ')
parser.add_argument('-p','--print_files', action='store_true', 
    help='Print files from folder ')
parser.add_argument('-s','--show', action='store_true', 
    help='Show image in PyQt5 canvas!')
args = vars(parser.parse_args())

p = parser.parse_args()
print(p.files_path, type(p.files_path), p.files_path.exists())
print(p.show)
files = os.listdir(p.files_path)
file_list = []
image_list = []
bad_files_list =[]

if args['print_files']: 
    print("These are files from folder "+str(p.files_path))
    for f in file_list:
	    print(f)

images_ext = str(Path(p.files_path))+'/*.png'
print("images_ext: "+images_ext)
for filename in glob.glob(images_ext): #assuming png
    try:
        f = open(filename, 'rb')
        file = io.BytesIO(f.read())
        im = Image.open(file)
        image_list.append(filename)
        print(str(len(image_list))+" good file is"+filename)
    except Image.UnidentifiedImageError:
        bad_files_list.append(str(p.files_path)+"/"+str(filename))

for f in bad_files_list:
	print("bad file is : " + f)


if args['show']:
    value = input("Please enter the index of PNG image :\n")
    try:
        int(value)
        print("Image number select default : " + value)      
        value = int(value)
        if value &lt= len(image_list):
            value = int(value)
        else:
            print("The number image selected is greater then len of list images!")
            value = len(image_list)
    except:
        print("This is not a number, I set first image number.")
        value = 1

    class MainWindow(QMainWindow):

        def __init__(self):
            super(MainWindow, self).__init__()
            self.title = "Image Viewer"
            self.setWindowTitle(self.title)

            label = QLabel(self)
            pixmap = QPixmap(image_list[int(value)])
            label.setPixmap(pixmap)
            self.setCentralWidget(label)
            self.resize(pixmap.width(), pixmap.height())

    app = QApplication(sys.argv)
    w = MainWindow()
    w.show()
    sys.exit(app.exec_())
These are the output of the script:
[mythcat@desk PIL001]$ python  tool001.py 
usage: tool001.py [-h] [-p] [-s] files_path
tool001.py: error: the following arguments are required: files_path
[mythcat@desk PIL001]$ python  tool001.py ~/Pictures/
/home/mythcat/Pictures  True
False
images_ext: /home/mythcat/Pictures/*.png
1 good file is/home/mythcat/Pictures/keyboard.png
2 good file is/home/mythcat/Pictures/Fedora_The_Pirate_CaribbeanHunt.png
3 good file is/home/mythcat/Pictures/website.png
4 good file is/home/mythcat/Pictures/Screenshot from 2021-02-19 19-24-32.png
...
97 good file is/home/mythcat/Pictures/Screenshot from 2021-07-03 17-31-23.png
98 good file is/home/mythcat/Pictures/Screenshot from 2021-07-03 17-46-05.png
bad file is : /home/mythcat/Pictures//home/mythcat/Pictures/Screenshot from 2021-02-07 14-58-56.png
bad file is : /home/mythcat/Pictures//home/mythcat/Pictures/evolution_logo.png
[mythcat@desk PIL001]$ python  tool001.py ~/Pictures/ -p
/home/mythcat/Pictures  True
False
These are files from folder /home/mythcat/Pictures
images_ext: /home/mythcat/Pictures/*.png
1 good file is/home/mythcat/Pictures/keyboard.png
2 good file is/home/mythcat/Pictures/Fedora_The_Pirate_CaribbeanHunt.png
3 good file is/home/mythcat/Pictures/website.png
...
97 good file is/home/mythcat/Pictures/Screenshot from 2021-07-03 17-31-23.png
98 good file is/home/mythcat/Pictures/Screenshot from 2021-07-03 17-46-05.png
bad file is : /home/mythcat/Pictures//home/mythcat/Pictures/Screenshot from 2021-02-07 14-58-56.png
bad file is : /home/mythcat/Pictures//home/mythcat/Pictures/evolution_logo.png
[mythcat@desk PIL001]$ python  tool001.py ~/Pictures/ -s
/home/mythcat/Pictures  True
True
images_ext: /home/mythcat/Pictures/*.png
...
97 good file is/home/mythcat/Pictures/Screenshot from 2021-07-03 17-31-23.png
98 good file is/home/mythcat/Pictures/Screenshot from 2021-07-03 17-46-05.png
bad file is : /home/mythcat/Pictures//home/mythcat/Pictures/Screenshot from 2021-02-07 14-58-56.png
bad file is : /home/mythcat/Pictures//home/mythcat/Pictures/evolution_logo.png
Please enter the index of PNG image :
6
Image number select default : 6

Saturday, October 10, 2020

Python 3.9.0 : Union and in-place union operators

Python introduces two new operators for dictionaries named union used in code with pipe operator | and in-place union used in python code with this |=.

I this tutorial I will show you how can be used:
[mythcat@desk ~]$ python3.9 
Python 3.9.0 (default, Oct  6 2020, 00:00:00) 
[GCC 10.2.1 20200723 (Red Hat 10.2.1-1)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> step_one = {"worker_one":"task_one", "worker_two":"task_two"}
>>> step_two = {"worker_three":"task_one", "worker_fouw":"task_two"}
>>> merged_step_one_step_two = {**step_one, **step_two}
>>> empty = {}
>>> empty |= step_one
>>> empty
{'worker_one': 'task_one', 'worker_two': 'task_two'}
>>> step_one 
{'worker_one': 'task_one', 'worker_two': 'task_two'}
>>> step_two
{'worker_three': 'task_one', 'worker_fouw': 'task_two'}
>>> all = step_one | step_two 
>>> all 
{'worker_one': 'task_one', 'worker_two': 'task_two', 'worker_three': 'task_one', 'worker_fouw': 'task_two'} 
>>> copy_step_one = empty | step_one
>>> copy_step_one 
{'worker_one': 'task_one', 'worker_two': 'task_two'} 
>>> copy_step_one |= [("manager", "steps")]
>>> copy_step_one 
{'worker_one': 'task_one', 'worker_two': 'task_two', 'manager': 'steps'}
You can easily see how to use these operators with the dictionaries created and how to add lists to dictionaries. Operations with these operators always result in a dictionary. The order of these operations is important, see example:
>>> numbers = {0: "zero", 1: "one"}
>>> numbers_one = {0: "zero", 1: "one"}
>>> numbers_two = {0: "zero", 2: "two"}
>>> numbers_one | numbers_two
{0: 'zero', 1: 'one', 2: 'two'}
>>> numbers_two | numbers_one
{0: 'zero', 2: 'two', 1: 'one'}
>>> numbers_three = {0: 'zero', 11: 'error 1', 22: 'error 2', 33:'error 3'}
>>> numbers_three | numbers_one
{0: 'zero', 11: 'error 1', 22: 'error 2', 33: 'error 3', 1: 'one'}
>>> numbers_one | numbers_three
{0: 'zero', 1: 'one', 11: 'error 1', 22: 'error 2', 33: 'error 3'}
You can see how the dictionaries are overwritten by the union operation. These operations are implemented through dunder operations for most the dictionary objects except abstract classes. Dunder or magic methods in Python are the methods having two prefix and suffix underscores in the method name. You can find on this page.

Python 3.9.0 : Introduction to release 3.9.0.

This is a short introduction to release 3.9.0. 
Five days ago, a new release of version 3.9 appeared with a series of improvements and new python packages, see the official website
You can install easily on Fedora 32 with dnf tool.
[root@desk mythcat]# dnf install  python39.x86_64
...
Installing:
 python39                x86_64                3.9.0-1.fc32
...
Installed:
  python39-3.9.0-1.fc32.x86_64                                                                             

Complete!
A new article written about this release shows some of the advantages of this programming language, you can read it here
You can run easily with this command;
[root@desk mythcat]# python3.9
Python 3.9.0 (default, Oct  6 2020, 00:00:00) 
[GCC 10.2.1 20200723 (Red Hat 10.2.1-1)] on linux
Type "help", "copyright", "credits" or "license" for more information. 
You can configure python with this command, see an example:
[root@desk mythcat]# python3.9-x86_64-config --libs 
 -lcrypt -lpthread -ldl  -lutil -lm -lm 
This release of Python 3.9 uses a new parser, based on parsing expression grammar (PEG) instead of LL(1) know as LL parser (Left-to-right, Leftmost derivation). PEG parsers are more powerful than LL(1) parsers and avoid the need for special hacks. This the same abstract syntax tree (AST) as the old LL(1) parser. The PEG parser is the default, but you can run your program using the old parser, see the next example:
[mythcat@desk ~]$ python3.9 -X oldparser my_script_name.py
...
One of the most important improvements for me is PEP 614 -- Relaxing Grammar Restrictions On Decorators. In Python 3.9, these restrictions are lifted and you can now use any expression. 
For example including one accessing items in a dictionary, like this simple example:

buttons = {
  "hello": QPushButton("hello word!"),
  "bye": QPushButton("bye word!"),
  "buy": QPushButton("buy!!"),
}
...
@buttons["hello"].clicked.connect
def speak_hello():
... 
Yes, comes with another Python Enhancement Proposals - PEP 615 with support for the IANA Time Zone Database in the Standard Library. This acronym is similar to I.A.N.A known as the Internet Assigned Numbers Authority, but it is not the same. 
In this case, the zoneinfo module provides a concrete time zone implementation to support the IANA time zone database. 
This support contains code and data that represent the history of local time for many representative locations around the globe. Many features for math, strings, union operator for the dictionary, HTTP codes, and more. 
Completion of variable and module names is automatically enabled at interpreter startup so that the Tab key invokes the completion function. 
You can see a simple example with zoneinfo python module and completion feature.
[mythcat@desk ~]$ python3.9
Python 3.9.0 (default, Oct  6 2020, 00:00:00) 
[GCC 10.2.1 20200723 (Red Hat 10.2.1-1)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from zoneinfo import ZoneInfo
>>> import zoneinfo
>>> zoneinfo.available_timezones()
{'Hongkong', 'America/Iqaluit', 'America/Indianapolis', 'America/Louisville', 'America/New_York', 
'America/Mazatlan', 'Australia/Yancowinna', 'Africa/Ndjamena', 'Portugal', 'Africa/Bujumbura', 
'America/Rosario', 'America/Antigua','America/Indiana/Tell_City', 'America/Managua', 
'Europe/Paris', 'Europe/Oslo', 
...
>>> tz = ZoneInfo("Europe/Bucharest")
>>> tz.
tz.clear_cache(  tz.from_file(    tz.key           tz.tzname(       
tz.dst(          tz.fromutc(      tz.no_cache(     tz.utcoffset(    
>>> tz. 
On my desktop I got this result:
[mythcat@desk ~]$ python var_access_benchmark.py 
Variable and attribute read access:
   6.0 ns	read_local
   6.5 ns	read_nonlocal
  10.7 ns	read_global
  10.7 ns	read_builtin
  25.2 ns	read_classvar_from_class
  23.4 ns	read_classvar_from_instance
  34.3 ns	read_instancevar
  29.4 ns	read_instancevar_slots
  26.8 ns	read_namedtuple
  42.4 ns	read_boundmethod

Variable and attribute write access:
   6.6 ns	write_local
   7.0 ns	write_nonlocal
  23.3 ns	write_global
  54.1 ns	write_classvar
  46.4 ns	write_instancevar
  39.4 ns	write_instancevar_slots

Data structure read access:
  26.1 ns	read_list
  28.1 ns	read_deque
  27.5 ns	read_dict
  25.8 ns	read_strdict

Data structure write access:
  29.6 ns	write_list
  31.7 ns	write_deque
  34.4 ns	write_dict
  31.7 ns	write_strdict

Stack (or queue) operations:
  55.5 ns	list_append_pop
  49.7 ns	deque_append_pop
  51.0 ns	deque_append_popleft

Timing loop overhead:
   0.4 ns	loop_overhead

Tuesday, September 29, 2020

Python Qt5 : Use QStandardItem with Images.

This tutorial show you how to use QStandardItem with Images.

The source code is simple to understand.

import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QTreeView
from PyQt5.QtCore import  Qt
from PyQt5.QtGui import QFont, QColor, QImage, QStandardItemModel, QStandardItem

class ItemImage(QStandardItem):
    def __init__(self, txt='', image_path='', set_bold=False, color=QColor(0, 0, 0)):
        super().__init__()

        self.setEditable(False)
        self.setForeground(color)
        self.setText(txt)

        if image_path:
            image = QImage(image_path)
            self.setData(image, Qt.DecorationRole)

class MyApp(QMainWindow):
    def __init__(self):
        super().__init__()
        self.resize(1200, 1200)

        treeView = QTreeView()
        treeView.setHeaderHidden(True)
        treeView.header().setStretchLastSection(True)

        treeModel = QStandardItemModel()
        rootNode = treeModel.invisibleRootItem()

        robots = ItemImage('Robots', '', set_bold=True)

        aaa = ItemImage('aaa.jpg', 'aaa.jpg', 14)
        robots.appendRow(aaa)

        bbb = ItemImage('bbb.jpg', 'bbb.jpg', 16)
        robots.appendRow(bbb)

        robots2 = ItemImage('Robots 2', '', set_bold=False)

        aaa = ItemImage('ccc.png', 'ccc.png', 14)
        robots2.appendRow(aaa)

        bbb = ItemImage('ddd.jpg', 'ddd.jpg', 16)
        robots2.appendRow(bbb)

        rootNode.appendRow(robots)
        rootNode.appendRow(robots2)
        treeView.setModel(treeModel)
        treeView.expandAll()

        self.setCentralWidget(treeView)

app = QApplication(sys.argv)        
demo = MyApp()
demo.show()
sys.exit(app.exec_())

The result is this: