analitics

Pages

Monday, April 11, 2022

Python 3.7.8 : Gym toolkit - part 001.

Today I tested the gym python package and both version of python: 3.7.8 and 3.10.4.
Gym is a toolkit for developing and comparing reinforcement learning algorithms. It supports teaching agents everything from walking to playing games like Pong or Pinball.
pip install gym
...
Successfully installed cloudpickle-2.0.0 gym-0.23.1 gym-notices-0.0.6 importlib-
metadata-4.11.3 numpy-1.21.5 typing-extensions-4.1.1 zipp-3.8.0
C:\Python378>pip install Pygame
...
Successfully installed Pygame-2.1.2
C:\Python378>python.exe
Python 3.7.8 (tags/v3.7.8:4b47a5b6ba, Jun 28 2020, 08:53:46) [MSC v.1916 64 bit
(AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import gym
You can see the gym python package is loaded.
Let's test the default python source code from the official webpage:
import gym
env = gym.make("CartPole-v1")
observation = env.reset()
for _ in range(1000):
  env.render()
  action = env.action_space.sample() # your agent here (this takes random actions)
  observation, reward, done, info = env.step(action)

  if done:
    observation = env.reset()
env.close()
I created a file name gym001.py and I run it with python.exe.
The result is a window like on the official webpage.
I tested with python version 3.10.4 with same example and works well:
C:\Python310>python.exe -m pip install gym
...
Installing collected packages: gym-notices, numpy, cloudpickle, gym
Successfully installed cloudpickle-2.0.0 gym-0.23.1 gym-notices-0.0.6 numpy-1.22.3
C:\Python310>python.exe -m pip install pygame
...
Successfully installed pygame-2.1.2
C:\Python310>python.exe gym001.py
...

Sunday, April 10, 2022

Python : PyFlow is visual scripting framework for python.

PyFlow is a general purpose visual scripting framework for python.
I install python version 3.7.8 and these python modules: PyQt5 and PySide.
pip install git+https://github.com/wonderworks-software/PyFlow.git@release
...
Requirement already satisfied: Qt.py in c:\python378\lib\site-packages (from PyF
low==2.0.1) (1.3.6)
Requirement already satisfied: blinker in c:\python378\lib\site-packages (from P
yFlow==2.0.1) (1.4)
Requirement already satisfied: nine in c:\python378\lib\site-packages (from PyFl
ow==2.0.1) (1.1.0)
Requirement already satisfied: docutils in c:\python378\lib\site-packages (from
PyFlow==2.0.1) (0.18.1)

C:\Python378>PyFlow
This is the default window for the PyFlow, see the next screenshot image:
One good feature of the PyFlow is the integration, you can see one example with DeepAi from Brandon Gilles, see this video example:

Saturday, April 9, 2022

Python : Starting learn with futurecoder online tool.

This website with online tool can be a good start for test and learn python language programming.
They come with this intro:
This is a 100% free and interactive course for people to teach themselves programming in Python, especially complete beginners at programming. It is carefully designed to reduce frustration and guide the user while still ensuring that they learn how to solve problems. The goal is for as many people as possible to learn programming.
You can try it out here: https://futurecoder.io .
Please consider contributing or donating!
You can see in the next video tutorial how this works:

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

Saturday, February 26, 2022

Python 3.7.12 : My colab tutorials - part 023.

NVIDIA announces TensorRT 8.2 and Integrations with PyTorch and TensorFlow on Dec 02, 2021.
This Torch-TensorRT is a high-performance deep learning inference optimizer and runtime that delivers low latency, high-throughput inference for AI applications. TensorRT is used across several industries including healthcare, automotive, manufacturing, internet/telecom services, financial services, and energy.
I tested today using my gavatar image on colab notebook with the GPU device.
Am prelucrat un cod sursa exemplu existent de pe internet cu o un model RESNET known as Deep Residual Learning for Image Recognition, see this website.
model = models.resnet50(pretrained=True).to("cuda")
I have a pretty good picture of the processing possibilities given for this topic and I can tell you today that this implementation of TensorRT is below my expectations.
However, there are some positive elements that can be used with this in the future.
The full exaemple and how can be used TensorRT with colab tool can be found on my GitHub repo with all colabs notebooks.

Tuesday, February 1, 2022

Python 3.10.0 : How to using wheels.

Wheels are the last component of the Python ecosystem that helps to make package installs easy.
Wheel and Egg are both packaging formats.
The Egg format was introduced by setuptools in 2004, whereas the Wheel format was introduced by PEP 427 in 2012.
You can use it easy with these commands:
C:\Python310>python.exe -m pip install wheel
Collecting wheel
  Downloading wheel-0.37.1-py2.py3-none-any.whl (35 kB)
Installing collected packages: wheel
  WARNING: The script wheel.exe is installed in 'C:\Python310\Scripts' which is not on PATH.
  Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.
Successfully installed wheel-0.37.1

C:\Python310>python.exe -m pip install --upgrade pip setuptools wheel
Requirement already satisfied: pip in c:\python310\lib\site-packages (21.3.1)
Collecting pip
  Downloading pip-22.0.2-py3-none-any.whl (2.1 MB)
     |████████████████████████████████| 2.1 MB 2.2 MB/s
Requirement already satisfied: setuptools in c:\python310\lib\site-packages (57.4.0)
Collecting setuptools
  Downloading setuptools-60.6.0-py3-none-any.whl (953 kB)
     |████████████████████████████████| 953 kB 6.8 MB/s
Requirement already satisfied: wheel in c:\python310\lib\site-packages (0.37.1)
Installing collected packages: setuptools, pip
  Attempting uninstall: setuptools
    Found existing installation: setuptools 57.4.0
    Uninstalling setuptools-57.4.0:
      Successfully uninstalled setuptools-57.4.0
  Attempting uninstall: pip
    Found existing installation: pip 21.3.1
    Uninstalling pip-21.3.1:
      Successfully uninstalled pip-21.3.1
  WARNING: The scripts pip.exe, pip3.10.exe and pip3.exe are installed in 'C:\Python310\Scripts' which is not on PATH.
  Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.
Successfully installed pip-22.0.2 setuptools-60.6.0

Friday, January 14, 2022

Python 3.10.1 : Django and channels on Fedora distro - sync and async features.

A consumer is a subclass of either channels.consumer.AsyncConsumer or channels.consumer.SyncConsumer.
Consumers do a couple of things in particular: 
  • Structures your code as a series of functions to be called whenever an event happens, rather than making you write an event loop. 
  • Allow you to write synchronous or async code and deals with handoffs and threading for you.
This is another tutorial about Django and channels, you can see the first one.
For testing area you need the postman tool and I install and used with snap tool.
[root@fedora mythcat]# dnf install snapd
Last metadata expiration check: 0:40:03 ago on Fri 14 Jan 2022 03:38:55 PM EET.
...
[root@fedora mythcat]# ln -s /var/lib/snapd/snap /snap
[root@fedora mythcat]# snap install postman
2022-01-14T16:22:15+02:00 INFO Waiting for automatic snapd restart...
postman (v9/stable) 9.8.3 from Postman, Inc. (postman-inc✓) installed
[mythcat@fedora ~]$ snap run postman
Let's go on the project folder:
[mythcat@fedora ~]$ cd djangotest001/
[mythcat@fedora djangotest001]$ cd website001/
In this folder I have two folders: appsite001 and website001.
In the appsite001 I add these scripts.
I create a new python script named consumers.py with this source code:
from channels.consumer import SyncConsumer, AsyncConsumer
from channels.exceptions import StopConsumer

class MySyncConsumer(SyncConsumer):
    def websocket_connect(self,event):
        print('Websocket Connected ...')
        self.send({
        'type':'websocket.accept',
        })
    def websocket_receive(self, event):
        print('Messaged Received ...')
        print(event['text'])
        self.send({
        'type':'websocket.send',
        'text':'Message sent to client'
        })
    def websocket_diconnect(self, event):
        print('Websocket Disconnected ...')
        raise StopConsumer
        
class MyAsyncConsumer(AsyncConsumer):
    async def websocket_connect(self,event):
        print('Websocket Connected ...')
    async def websocket_receive(self, event):
        print('Messaged Received ...')
    async def websocket_diconnect(self, event):
        print('Websocket Disconnected ...')
I created routing.py python script with this source code:
from django.urls import path
from . import consumers

websocket_urlpatterns = [
    path('ws/sc/',consumers.MySyncConsumer.as_asgi()),
    ]
In the website001 I change this script named asgi.py.
import os

from django.core.asgi import get_asgi_application

from channels.routing import ProtocolTypeRouter, URLRouter

import appsite001.routing

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'website001.settings')

application = ProtocolTypeRouter({
    'http':get_asgi_application(),
    'websocket':URLRouter(
        appsite001.routing.websocket_urlpatterns
    )
})
Run the Django project with :
[mythcat@fedora website001]$ python manage.py runserver
Watching for file changes with StatReloader
Performing system checks...

System check identified no issues (0 silenced).
January 14, 2022 - 15:32:29
Django version 4.0.1, using settings 'website001.settings'
Starting ASGI/Channels version 3.0.4 development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
WebSocket HANDSHAKING /ws/sc/ [127.0.0.1:33944]
Websocket Connected ...
WebSocket CONNECT /ws/sc/ [127.0.0.1:33944]
Messaged Received ...
This is a message from mythcat
...
Use postman tool with websocket to send this message to Django project:
This is a message from mythcat
You can see how this works:

Tuesday, January 11, 2022

News : Python as the programming language of 2021.

The TIOBE index is based on the number of search results for a programming language across popular search engines, which is pretty limited.
They say:
Python has won the prestigious TIOBE Programming Language of the Year award. Congratulations! This is the second time in a row. The award is given to the programming language that has gained the highest increase in ratings in one year. C# was on its way to get the title for the first time in history, but Python surpassed C# in the last month.

Saturday, January 8, 2022

Python 3.10.1 : Django and channels on Fedora distro.

Today I tested the Django version 4.0.1 with channels features on Fedora 35.
For the channels package, I used the pip tool and I install the version
The python package channels come with features like:
Channels augments Django to bring WebSocket, long-poll HTTP, task offloading, and other async support to your code, using familiar Django design patterns and a flexible underlying framework that lets you not only customize behaviors but also write support for your own protocols and needs. see the GitHub website.
Let's install the Django package
[mythcat@fedora ~]$ pip3 install django --user
Requirement already satisfied: django in /usr/local/lib/python3.10/site-packages (4.0.1)
Requirement already satisfied: sqlparse>=0.2.2 in /usr/local/lib/python3.10/site-packages (from django) (0.4.2)
Requirement already satisfied: asgiref<4>=3.4.1 in ./.local/lib/python3.10/site-packages (from django) (3.4.1)
The next step is to create the project named website001:
[mythcat@fedora ~]$ mkdir djangotest001
[mythcat@fedora ~]$ cd djangotest001/
[mythcat@fedora djangotest001]$ django-admin startproject website001
[mythcat@fedora djangotest001]$ cd website001/
[mythcat@fedora website001]$ python3 manage.py runserver
Watching for file changes with StatReloader
Performing system checks...

System check identified no issues (0 silenced).

You have 18 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.
Run 'python manage.py migrate' to apply them.
January 08, 2022 - 13:26:21
Django version 4.0.1, using settings 'website001.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
...
Let's create the application named appsite001:
[mythcat@fedora website001]$ django-admin startapp  appsite001
[mythcat@fedora website001]$ ls
appsite001  db.sqlite3  manage.py  website00
The apps.py file is this:
[mythcat@fedora website001]$ cat  appsite001/apps.py 
from django.apps import AppConfig

class Appsite001Config(AppConfig):
    default_auto_field = 'django.db.models.BigAutoField'
    name = 'appsite001'
Let's add this on the settings.py file config:
[mythcat@fedora website001]$ vi website001/settings.py
    
# Application definition

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'appsite001',
]
Use the migrate feature to fix all:
[mythcat@fedora website001]$ python manage.py migrate
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, sessions
Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  Applying admin.0001_initial... OK
  Applying admin.0002_logentry_remove_auto_add... OK
  Applying admin.0003_logentry_add_action_flag_choices... OK
  Applying contenttypes.0002_remove_content_type_name... OK
  Applying auth.0002_alter_permission_name_max_length... OK
  Applying auth.0003_alter_user_email_max_length... OK
  Applying auth.0004_alter_user_username_opts... OK
  Applying auth.0005_alter_user_last_login_null... OK
  Applying auth.0006_require_contenttypes_0002... OK
  Applying auth.0007_alter_validators_add_error_messages... OK
  Applying auth.0008_alter_user_username_max_length... OK
  Applying auth.0009_alter_user_last_name_max_length... OK
  Applying auth.0010_alter_group_name_max_length... OK
  Applying auth.0011_update_proxy_permissions... OK
  Applying auth.0012_alter_user_first_name_max_length... OK
  Applying sessions.0001_initial... OK
Create the superuser named admin with password admin and set the email address:
[mythcat@fedora website001]$ python manage.py createsuperuser
Username (leave blank to use 'mythcat'): admin
Email address: admin@server.com
Password: 
Password (again): 
The password is too similar to the username.
This password is too short. It must contain at least 8 characters.
This password is too common.
Bypass password validation and create user anyway? [y/N]: y
Superuser created successfully.

http://127.0.0.1:8000/admin/
...
Let's install the channels package for the Django project:
[mythcat@fedora website001]$ pip install channels
...
Successfully installed Automat-20.2.0 autobahn-21.11.1 channels-3.0.4 constantly-15.1.0 
daphne-3.0.2 hyperlink-21.0.0 incremental-21.3.0 pyasn1-0.4.8 pyasn1-modules-0.2.8 
service-identity-21.1.0 twisted-21.7.0 txaio-21.2.1 zope.interface-5.4.0
Add this package into the settinngs.py config file:
[mythcat@fedora website001]$ vi website001/settings.py
INSTALLED_APPS = [
    'channels',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'appsite001',
]
...
#WSGI_APPLICATION = 'website001.wsgi.application'
ASGI_APPLICATION = 'website001.asgi.application'
...
Make these changes to switch from wsgi to asgi features for channels package:
[mythcat@fedora website001]$ cp website001/wsgi.py website001/asgi.py 
[mythcat@fedora website001]$ vi website001/asgi.py 
import os

from django.core.asgi import get_asgi_application
from channels.routing import ProtocolTypeRouter
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'website001.settings')

application = ProtocolTypeRouter({
    'http':get_asgi_application(),
})
I tested on the admin area how the settings for this packet will work:
[mythcat@fedora website001]$ python3 manage.py runserver
Watching for file changes with StatReloader
Performing system checks...

System check identified no issues (0 silenced).
January 08, 2022 - 14:20:53
Django version 4.0.1, using settings 'website001.settings'
Starting ASGI/Channels version 3.0.4 development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
...
The result shows that it works:
The next theoretical steps would be to determine how the channels package will work and routing for access to appsite001.

Monday, January 3, 2022

Python Qt6 : The basic differences between PyQt5 and PyQt6.

Python Qt6 known as PyQt6 is a binding of the cross-platform GUI toolkit Qt, implemented as a Python plug-in with Qt 6 the latest version of Qt.
The PyQt6 first stable release was on 6 January 2021, developed by Riverbank Computing Ltd and the last release was on 2 December 2021 with the version PyQt v6.2.2.
This release is license GPL or commercial on Python 3 platform.
Let's see some differences between PyQt5 and PyQt6.
The .exec() method is used in Qt to start the event loop of your QApplication or dialog boxes. In Python 2.7 exec was a keyword and Python 3 removed the exec keyword.
The first difference as a result of PyQt6 .exec() calls are named just as in Qt.
If you read the documentation from the official webpage, then in your PyQt6 source code you need to use these changes:
QEvent.Type.MouseButtonPress
...
Qt.MouseButtons.RightButton
...
Both PyQt5 and PyQt6, although seemingly easy to use for complex applications, will require extra effort.

Sunday, December 26, 2021

Python 3.7.11 : My colab tutorials - part 022.

Here is another notebook with two python scripts.
You may be wondering why I add them here and the index of 022 blog posts does not match the 026 index of those on the GitHub website.
The answer is simple: here I post them when I have time for evaluation and there they are added when they are created and tested.
The posts here are for a share of those who want to learn simple python programming to solve common issues by anyone with minimal school knowledge and for supporting the python programming community.
In this notebook you will find a script that uses a python packet that does a simple search using Google and one that does an image search.

Tuesday, December 7, 2021

Python Qt5 : Simple browser with QWebEngineView.

This is a simple example with PyQt5 and QWebEngineView.
You can see this example and use it from my GitHub account.

Monday, December 6, 2021

Python Qt5 : QtWebEngineWidgets and button.

In this tutorial I will show you how to add a simple button to the application build with QtWebEngineWidgets using the addWidget to a QVBoxLayout with a lay variable.
The button named PyQt5 nothing button is not connected.
Let's see this default example:
import sys

from PyQt5.QtCore import QUrl
from PyQt5.QtWidgets import QApplication, QPushButton, QMainWindow, QVBoxLayout, QWidget
from PyQt5.QtWebEngineWidgets import QWebEnginePage, QWebEngineSettings, QWebEngineView

class Widget(QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.view = QWebEngineView()
        lay = QVBoxLayout(self)
        lay.addWidget(self.view)
        self.resize(640, 480)

class WebEnginePage(QWebEnginePage):
    def createWindow(self, _type):
        w = Widget()
        w.show()
        return w.view.page()

class MainWindow(QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent=None)

        self.setWindowTitle("PyQt5 ... another example !!")
        central_widget = QWidget()
        self.setCentralWidget(central_widget)
        
        button = QPushButton('PyQt5 nothing button', self)
        button.setToolTip('This is an example button')

        self.webview = QWebEngineView()
        self.page = WebEnginePage()
        self.webview.setPage(self.page)
        self.webview.settings().setAttribute(
            QWebEngineSettings.FullScreenSupportEnabled, True
        )

        self.webview.load(
            QUrl("https://www.youtube.com/watch?v=BVT3acNFzqc?rel=0&showinfo=0")
        )

        lay = QVBoxLayout(central_widget)
        lay.addWidget(button)
        lay.addWidget(self.webview)

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

if __name__ == "__main__":
    main()

Saturday, December 4, 2021

Python 3.6.9 : Unarchive a RAR file with UnRAR and python.

In this tutorial, I will show you how can unrar a RAR archive with and without a password.
First, go to this website and install the UnRAR.dll file.
After you install into default path: C:\Program Files (x86)\UnrarDLL you need to create and set a new environment variable named UNRAR_LIB_PATH.
You need to select the 32 or 64 paths to this environment variable, and this depends on the test archive.
Because I create a RAR archive with x64 version I used this path for the environment variable: C:\Program Files (x86)\UnrarDLL\x64\UnRAR64.dll.
The first test archive I created was named TestRAR.rar and I used a password 111 with encryption.
The second one is named TestRAR001.rar and has no password.
Let's install the unrar python module with the pip tool.
pip install unrar
Requirement already satisfied: unrar in c:\python39\lib\site-packages (0.4)
Let's see the source code in python version 3.6.9
from unrar import rarfile

print("-----------------")
#archiveRARFile = r"C:\\PythonProjects\\RARArchive\\TestRAR.rar"
archiveRARFile = r"C:\\PythonProjects\\RARArchive\\TestRAR001.rar"
extractPath = r"C:\\PythonProjects\\RARArchive"

files = []
#with rarfile.RarFile(archiveRARFile,"r","111") as rarFile:
with rarfile.RarFile(archiveRARFile,"r","") as rarFile:
    files = rarFile.namelist()
    rarFile.extractall(extractPath)

print("files ",files)

for file in files:
    pathFile = fr"{extractPath}+{file}"
    with open(file,"r") as f:
        data = f.readlines()
        for line in data:
            line = line.strip()
            print(line)
You can see I commented two rows for each archive in order to test each one:
After I tested, this is the result of each test and both work great.
C:\PythonProjects\RARArchive>python unrarFile.py
-----------------
files  ['TestRAR.txt']
This is a test for RAR archive.

C:\PythonProjects\RARArchive>python unrarFile.py
-----------------
files  ['TestRAR.txt']
This is a test for RAR archive.

Thursday, November 25, 2021

Python Qt5 : QtWebEngineWidgets and YouTube Video.

In this tutorial I will show you how to play a video from Youtube using PyQt5 and this standard URL type:
http://www.youtube.com/watch_popup?v=VIDEOID
I used this version of python, version 3.9.6.
python
Python 3.9.6 (tags/v3.9.6:db3ff76, Jun 28 2021, 15:26:21) [MSC v.1929 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
...
The source code is simple:
import time

import sys

from PyQt5.QtCore import QUrl
from PyQt5.QtWebEngineWidgets import QWebEngineView, QWebEngineProfile
from PyQt5.QtWebEngineWidgets import QWebEnginePage, QWebEngineSettings
from PyQt5.QtWidgets import QApplication

if __name__ == '__main__':


    app = QApplication(sys.argv)

    webview = QWebEngineView()
    profile = QWebEngineProfile("my_profile", webview)
    profile.defaultProfile().setPersistentCookiesPolicy(QWebEngineProfile.ForcePersistentCookies)
    webpage = QWebEnginePage(profile, webview)
    webpage.settings().setAttribute(QWebEngineSettings.PlaybackRequiresUserGesture, False)

    webview.setPage(webpage)
    webview.load(QUrl("http://www.youtube.com/watch_popup?v=aw4ZDQsFxv0"))
    webview.show()

    sys.exit(app.exec_())
The song is: SO EMOTIONAL- Olivia Rodrigo - Traitor | Allie Sherlock cover, see it on youtube.

Wednesday, November 17, 2021

Python 3.7.11 : My colab tutorials - part 021.

This is a simple notebook tutorial about how can test and get info from GPU on colab online tool.
This tutorial can be found on my GitHub account.

Tuesday, November 16, 2021

Python 3.7.11 : My colab tutorials - part 020.

The tutorial I created is a test and use of the Selenium WebDriver python package for to automate web browser interaction from Python.
This tutorial can be found on my GitHub account.

Friday, November 5, 2021

Python Qt5 : Drag and drop examples - part 001.

This tutorial si about drag and drop with PyQt5 and Python 3.9.6.
The drag and drop feature is very intuitive for the user.
The widgets should respond to the drag and drop events in order to store the data dragged into them. 
  • DragEnterEvent provides an event which is sent to the target widget as dragging action enters it.
  • DragMoveEvent is used when the drag and drop action is in progress.
  • DragLeaveEvent is generated as the drag and drop action leaves the widget.
  • DropEvent, on the other hand, occurs when the drop is completed. The event’s proposed action can be accepted or rejected conditionally.
Let's see two example, first is a drag and drop for one button:
#!/usr/bin/python
import sys
from PyQt5.QtCore import Qt, QMimeData
from PyQt5.QtGui import QDrag
from PyQt5.QtWidgets import QPushButton, QWidget, QApplication

class Button(QPushButton):

    def __init__(self, title, parent):
        super().__init__(title, parent)

    def mouseMoveEvent(self, e):

        if e.buttons() != Qt.RightButton:
            return

        mimeData = QMimeData()

        drag = QDrag(self)
        drag.setMimeData(mimeData)
        drag.setHotSpot(e.pos() - self.rect().topLeft())
        dropAction = drag.exec_(Qt.MoveAction)

    def mousePressEvent(self, e):
        super().mousePressEvent(e)
        if e.button() == Qt.LeftButton:
            print('press')


class Example(QWidget):

    def __init__(self):
        super().__init__()

        self.initUI()

    def initUI(self):

        self.setAcceptDrops(True)

        self.button = Button('Button', self)
        self.button.move(100, 65)

        self.setWindowTitle('Drag and drop with mouse - right click to move Button!')
        self.setGeometry(300, 300, 550, 450)

    def dragEnterEvent(self, e):
        e.accept()

    def dropEvent(self, e):
        position = e.pos()
        self.button.move(position)

        e.setDropAction(Qt.MoveAction)
        e.accept()

def main():
    
    app = QApplication(sys.argv)
    ex = Example()
    ex.show()
    app.exec_()

if __name__ == '__main__':
    main()
... this source code is for a drag and drop for a image file:
import sys, os
from PyQt5.QtWidgets import QApplication, QWidget, QLabel, QVBoxLayout
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QPixmap


class ImageLabel(QLabel):
    def __init__(self):
        super().__init__()

        self.setAlignment(Qt.AlignCenter)
        self.setText('\n\n Drop Image Here \n\n')
        self.setStyleSheet('''
            QLabel{
                border: 3px dashed #bbb
            }
        ''')

    def setPixmap(self, image):
        super().setPixmap(image)

class AppDemo(QWidget):
    def __init__(self):
        super().__init__()
        
        self.setWindowTitle('Drag and drop one image to this window!')
        self.setGeometry(300, 300, 550, 450)

        self.setAcceptDrops(True)

        mainLayout = QVBoxLayout()

        self.photoViewer = ImageLabel()
        mainLayout.addWidget(self.photoViewer)

        self.setLayout(mainLayout)

    def dragEnterEvent(self, event):
        if event.mimeData().hasImage:
            event.accept()
        else:
            event.ignore()

    def dragMoveEvent(self, event):
        if event.mimeData().hasImage:
            event.accept()
        else:
            event.ignore()

    def dropEvent(self, event):
        if event.mimeData().hasImage:
            event.setDropAction(Qt.CopyAction)
            file_path = event.mimeData().urls()[0].toLocalFile()
            self.set_image(file_path)

            event.accept()
        else:
            event.ignore()

    def set_image(self, file_path):
        self.photoViewer.setPixmap(QPixmap(file_path))

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

Saturday, October 30, 2021

Python 3.7.11 : My colab tutorials - part 019.

The tutorial I created is a test and use Probabilistic Graphical Models for the most basic problem the coin problem with the pgmpy python module.
This tutorial can be found on my GitHub account.

Sunday, October 10, 2021

News : The new python version 3.10.0.

Almost six days ago, the new version of python was released, version 3.10.0, see this.
Its installation on windows operating systems is done in the same way as the old installations, with the same steps and the same settings.
After installation, I turned it on and tested some of the new features.
C:\Python310>python
Python 3.10.0 (tags/v3.10.0:b494f59, Oct  4 2021, 19:00:18) [MSC v.1929 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
Python 3.10 comes with precise and constructive error messages like:
...
SyntaxError: '{' was never closed
...
>>> foo(a, b for b in range(5), c)
...
    foo(a, b for b in range(5), c)
           ^^^^^^^^^^^^^^^^^^^
SyntaxError: Generator expression must be parenthesized
...
>>> {a, b for (a, b) in zip("a", "b")}
...
    {a, b for (a, b) in zip("a", "b")}
     ^^^^
SyntaxError: did you forget parentheses around the comprehension target?
...
SyntaxError: expected ':'
...
SyntaxError: invalid syntax. Perhaps you forgot a comma?
...
SyntaxError: ':' expected after dictionary key
...
SyntaxError: expected 'except' or 'finally' block
...
SyntaxError: cannot assign to attribute here. Maybe you meant '==' instead of '='?
...
IndentationError: expected an indented block after 'if' statement in line ...
...
>>> import collections
>>> collections.namedtoplo
...
AttributeError: module 'collections' has no attribute 'namedtoplo'. Did you mean: 'namedtuple'?
...
>>> a = 0
>>> aa
...
NameError: name 'aa' is not defined. Did you mean: 'a'?
PEP 634: Structural Pattern Matching Structural 
... the pattern matching is a comprehensive addition to the Python language. 
They tell us: Pattern matching enables programs to extract information from complex data types, branch on the structure of data, and apply specific actions based on different forms of data.
PEP 604: New Type Union Operator as X|Y 
PEP 613: Explicit Type Aliases 
PEP 647: User-Defined Type Guards 
PEP 612: Parameter Specification Variables
You can see more on the official webpage.

Friday, October 1, 2021

Python Qt5 : The QSvgWidget for the SVG image format.

In this example tutorial, I will show you how can show an SVG image format with the PyQt5 and QSvgWidget.
I used Fedora 35 Beta with python pyqt5 package install with pip tool.
$ pip install pyqt5
The source code in the Python programming language is this:
The result image is this:

Wednesday, September 22, 2021

The Hitchhiker’s Guide to Python.

Greetings, Earthling! Welcome to The Hitchhiker’s Guide to Python.
This project comes with this license, is free, and help you to learn Python:
Creative Commons Legal Code
Attribution-NonCommercial-ShareAlike 3.0 Unported ...
This guide is currently under heavy development. This opinionated guide exists to provide both novice and expert Python developers a best practice handbook to the installation, configuration, and usage of Python on a daily basis.
You can contribute to this project on the GitHub project.

Saturday, September 18, 2021

Python 3.7.11 : My colab tutorials - part 018.

In this colab tutorial, you can see how to use the webcam with python and javascript.
This colab notebook can be found on my colab project on the GitHub webpage.
  • catafest_001.ipynb - first step, import TensorFlow;
  • catafest_002.ipynb - testing the GPU , Linux commands and python modules torch and fastai;
  • catafest_003.ipynb - testing the Altair;
  • catafest_004.ipynb - testing the cirq python package for quantum computing;
  • catafest_005.ipynb - using the estimator on tensoflow 2.0;
  • python_imdb_001.ipynb - using the colab with python module imdbpy;
  • catafest_006.ipynb - google authentification and google.colab drive and files
  • catafest_007.ipynb - test with https://github.com/harrism/numba_examples/blob/master/mandelbrot_numba.ipynb
  • catafest_008.ipynb - few simple examples with selenium and chromium-chromedriver;
  • catafest_009.ipynb - show you how to use %% colab features;
  • catafest_010.ipynb - example with Detectron2 is Facebook AI Research's with state-of-the-art object detection algorithms;
  • catafest_011.ipynb - test a sound classification with YAMNet from a web example - not very happy with the result;
  • catafest_012.ipynb - a simple tutorial about Colab tool and HTML and JavaScript with examples;
  • catafest_013.ipynb - a simple tutorial with settings for TPU and IMDB dataset;
  • catafest_014.ipynb - get IMDB review dataset and show it;
  • catafest_015.ipynb - how to get, show and use it data and create a new train data set from IMDB dataset;
  • catafest_016.ipynb - show the shape of the Fashion-MNIST dataset;
  • catafest_017.ipynb - this example show you how to write another python script in colab and run it;
  • catafest_018.ipynb - PIFuHD demo;
  • catafest_019.ipynb - get title from tiles.virtualearth.net;
  • catafest_020.ipynb - get video from youtube with pytube, converting to audio, show signal wave, energy and frequency;
  • catafest_021.ipynb - BERT is a transformers model with example and sentiment-analysis;
  • catafest_022.ipynb - webcam on colab with python and javascript;

Saturday, September 11, 2021

Python 3.7.11 : My colab tutorials - part 017.

BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding, see this https://arxiv.org/abs/1810.04805.
See this colab notebook with examples at my GitHub account.

Thursday, September 2, 2021

Python 3.7.11 : My colab tutorials - part 016.

This new colab notebook comes with: get youtube videos with pytube, converting to audio, show signals, energy and frequency.
You can see this work on the GitHub account.

Saturday, August 28, 2021

Python 3.7.11 : My colab tutorials - part 015.

Google Maps explicitly forbid using map tiles offline or caching them, but I think Microsoft Bing Maps don't say anything explicitly against it, and I guess you are not planning to use your program commercially (?)
This colab notebook show you how to get a title from tiles.virtualearth.net.
The source code is simple:
class TileServer(object):
    def __init__(self):
        self.imagedict = {}
        self.mydict = {}
        self.layers = 'ROADMAP'
        self.path = './'
        self.urlTemplate = 'http://ecn.t{4}.tiles.virtualearth.net/tiles/{3}{5}?g=0'
        self.layerdict = {'SATELLITE': 'a', 'HYBRID': 'h', 'ROADMAP': 'r'}

    def tiletoquadkey(self, xi, yi, z, layers):
        quadKey = ''
        for i in range(z, 0, -1):
            digit = 0
            mask = 1 << (i - 1)
            if(xi & mask) != 0:
                digit += 1
            if(yi & mask) != 0:
                digit += 2
            quadKey += str(digit)
        return quadKey

    def loadimage(self, fullname, tilekey):
        im = Image.open(fullname)
        self.imagedict[tilekey] = im
        return self.imagedict[tilekey]

    def tile_as_image(self, xi, yi, zoom):
        tilekey = (xi, yi, zoom)
        result = None
        try:
            result = self.imagedict[tilekey]
            print(result)
        except:
            print(self.layers)
            filename = '{}_{}_{}_{}.jpg'.format(zoom, xi, yi, self.layerdict[self.layers])
            print("filename is " + filename)
            fullname = self.path + filename
            try:
                result = self.loadimage(fullname, tilekey)
            except:
                server = random.choice(range(1,4))
                quadkey = self.tiletoquadkey(*tilekey)
                print (quadkey)
                url = self.urlTemplate.format(xi, yi, zoom, self.layerdict[self.layers], server, quadkey)
                print ("Downloading tile %s to local cache." % filename)
                urllib.request.urlretrieve(url, fullname)
                #urllib.urlretrieve(url, fullname)
                result = self.loadimage(fullname, tilekey)
        return result

Monday, July 26, 2021

Simple install of python in Windows O.S.

Today I create this simple video tutorial for new python users.
In this video tutorial I show you how easy is to install the python programming language in Windows O.S.
After install you can use the command python and you can use the python shell to test this programming language.
Also, you can create a script file with any name.
for example name the file: test.py and run in the windows shell with: python test.py.
You can see this video tutorial on my youtube account.

Saturday, July 17, 2021

Python Qt6 : Install and use python with Visual Studio.

Visual Studio is a very good tool for python programming language development.
Today I will show you how to use it with Visual Studio on a Windows operating system.
If you don't have Python install then start the Visual Studio installer and from all presents select the Python development workload.
Start Visual Studio and open a folder or open an empty file and save with the python language-specific extension: py.
Select the Python environment and add the new package with pip tool.
This is the python script I used to test:
import sys
from PyQt6.QtWidgets import QApplication, QWidget

def main():

    app = QApplication(sys.argv)

    w = QWidget()
    w.resize(250, 200)
    w.move(300, 300)

    w.setWindowTitle('Simple')
    w.show()

    sys.exit(app.exec())

if __name__ == '__main__':
    main()
You can see the video tutorial about how you can use it:

Tuesday, July 6, 2021

Python Qt6 : First example on Fedora 34 Linux distro.

Qt for Python is the project that provides the official set of Python bindings (PySide6) that will supercharge your Python applications. While the Qt APIs are world renowned, there are more reasons why you should consider Qt for Python.
I tested with Fedora 34 Linux distro:
[root@desk mythcat]# dnf search PyQt6
Last metadata expiration check: 2:03:10 ago on Tue 06 Jul 2021 08:52:41 PM EEST.
No matches found. 
First stable release for PyQt6 was on Jan 2021 by Riverbank Computing Ltd. under GPL or commercial and can be used with Python 3.
Let's install with pip tool:
[mythcat@desk ~]$ /usr/bin/python3 -m pip install --upgrade pip
...
  WARNING: The scripts pip, pip3 and pip3.9 are installed in '/home/mythcat/.local/bin' which is not on PATH.
  Consider adding this directory to PATH or, if you prefer to suppress this warning, 
  use --no-warn-script-location.
Successfully installed pip-21.1.3
[mythcat@desk ~]$ pip install PyQt6 --user
...
Let's see a simple example with this python package:
import sys
from PyQt6.QtCore import Qt
from PyQt6.QtWidgets import QApplication, QLabel

def main():
    app = QApplication(sys.argv)
    win = QLabel()
    win.resize(640, 498)
    win.setText("Qt is awesome!!!")
    win.show()
    app.exec()

if __name__ == "__main__":
    main()
I tested and run well.

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

Tuesday, June 15, 2021

Python 3.6.9 : My colab tutorials - part 014.

Here we come to the 16th notebook created with the colab utility from Google.
In this notebook, I will show you how you can view a dataset of images.
See the next image with a few of the shapes of the dataset:
You can find the full source code on my GitHub account.

Saturday, June 5, 2021

Python 3.6.9 : My colab tutorials - part 013.

In this tutorial created with the online tool google colab, we exemplified again how to access the IMDB dataset, which contains from the index point of view and what is the correspondence with the IMDB reviews, as well as how to work and create several sets of data for trains and what is the difference between them.
You can see the source code in python on this notebook.

Tuesday, June 1, 2021

Python 3.6.9 : My colab tutorials - part 012.

The purpose of this tutorial is to show the IMDB review dataset.
You can find the source code on my GitHub account here.

Thursday, May 27, 2021

Python 3.6.9 : My colab tutorials - part 011.

The purpose of this tutorial is to use the google TPU device together with Keras.
You need to set from the Edit menu and set for the notebook the device called TPU.
You can find the source code on my GitHub account here.

Tuesday, May 18, 2021

Python 3.9.1 : ABC - Abstract Base Classes - part 001.

Abstract classes are classes that contain one or more abstract methods.
By default, Python does not provide abstract classes.
Python comes with a module that provides the base for defining Abstract Base Classes (named ABC).
An abstract class can be considered as a blueprint for other classes.
By defining an abstract base class, you can define a common API for a set of subclasses.
A class that is derived from an abstract class cannot be instantiated unless all of its abstract methods are overridden.
[mythcat@desk ~]$ python3.9
Python 3.9.5 (default, May  4 2021, 00:00:00) 
[GCC 10.3.1 20210422 (Red Hat 10.3.1-1)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from abc import ABC
>>> class Test_ABC(ABC):
...     pass
... 
>>> Test_ABC.register(tuple)

>>> assert issubclass(tuple,Test_ABC)
>>> assert isinstance((), Test_ABC)
>>> class Foo:
...     def __getitem__(self, index):
...         ...
...     def __len__(self):
...         ...
...     def get_iterator(self):
...         return iter(self)
... 
>>> Test_ABC.register(Foo)
...
Let's see an example:
from abc import ABC, abstractmethod
 
class Vehicle(ABC):
    @abstractmethod
    def action(self):
        pass

class Air(Vehicle):
    # overriding abstract method
    def action(self):
        print("this flies in the air")
 
class Ground(Vehicle):
    # overriding abstract method
    def action(self):
        print("this running on the field")

class Civil(Ground):
    def action(self):
        print("Civil class - running on the field")

# Can't instantiate abstract class with abstract method action, don't use it
# abc = Vehicle()

abc = Air()
abc.action()

abc = Ground()
abc.action()

abc = Civil()
abc.action()

print( issubclass(Civil, Vehicle))
print( isinstance(Civil(), Vehicle))
This is the result:
[mythcat@desk PythonProjects]$ python3.9 ABC_001.py 
this flies in the air
this running on the field
Civil class - running on the field
True
True