analitics

Pages

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

Saturday, February 27, 2021

Python 2.7.18 : Kick Start Google - Boring Numbers.

Today I solved one of the problems required for solving Google Kick Start in 2020, see on my account.
Round H 2020 - Kick Start 2020 Boring Numbers (7pts, 12pts) Problem Ron read a book about boring numbers. According to the book, a positive number is called boring if all of the digits at even positions in the number are even and all of the digits at odd positions are odd. The digits are enumerated from left to right starting from 1. For example, the number 1478 is boring as the odd positions include the digits {1, 7} which are odd and even positions include the digits {4, 8} which are even. Given two numbers L and R, Ron wants to count how many numbers in the range [L, R] (L and R inclusive) are boring. Ron is unable to solve the problem, hence he needs your help.
Let's try to find the solution:
import math
print("Round H 2020 - Kick Start 2020: Detect is positive number is called boring.\n")
nr = int(input("get natural positive number: "))

all_cond = []
# detect if the number is odd or even number
def detect_odd_even(num):
  if (num % 2) == 0:  
    #print("{0} is Even number".format(num)) 
    detect = True  
  else:  
    #print("{0} is Odd number".format(num))  
    detect = False
  return detect
# check if is an boring number.
def boring_number(num):
    for p,num in enumerate(str(num),1):
        print(p,num)
        if (detect_odd_even(p) == detect_odd_even(int(num))): all_cond.append(True)
        else:
          all_cond.append(False)

# check the number is 
boring_number(nr)
# print result if the positive number is boring
if (all(all_cond) == True): print("{0} is an positive boring number".format(nr))
else:
  print("{0} is not a positive boring number".format(nr))
Let's test it:
~/mathissues$ python math_003.py 
Round H 2020 - Kick Start 2020: Detect is positive number is called boring.

get natural positive number: 345
(1, '3')
(2, '4')
(3, '5')
345 is an positive boring number
Then la last step is to test any number from range of given two numbers L and R.
The new source code is this:
import math
print("Round H 2020 - Kick Start 2020: Detect is positive number is called boring.\n")
#nr = int(input("get natural positive number: "))

all_cond = []
# detect if the number is odd or even number
def detect_odd_even(num):
  if (num % 2) == 0:  
    #print("{0} is Even number".format(num)) 
    detect = True  
  else:  
    #print("{0} is Odd number".format(num))  
    detect = False
  return detect
# check if is an boring number.
def boring_number(num):
    for p,num in enumerate(str(num),1):
        print(p,num)
        if (detect_odd_even(p) == detect_odd_even(int(num))): all_cond.append(True)
        else:
          all_cond.append(False)

# check the number is 
#boring_number(nr)
# print result if the positive number is boring

nr1 = int(input("get firt natural positive number: "))
nr2 = int(input("get firt natural positive number: "))
if nr1 < nr2:
  n1 = nr1
  n2 = nr2
else: 
  n1 = nr2
  n2 = nr1
for all_nr in range(n1,n2):
  all_cond = []
  boring_number(all_nr)
  print(all_nr)
# print result if the positive number is boring
  if (all(all_cond) == True): print("{0} is an positive boring number".format(all_nr))
  else: print("{0} is not a positive boring number".format(all_nr))
  all_cond = [] 
The final solution result to test all numbers in range given two numbers L and R can be see bellow:
~/mathissues$ python math_003.py 
Round H 2020 - Kick Start 2020: Detect is positive number is called boring.

get firt natural positive number: 11
get firt natural positive number: 16
(1, '1')
(2, '1')
11
11 is not a positive boring number
(1, '1')
(2, '2')
12
12 is an positive boring number
(1, '1')
(2, '3')
13
13 is not a positive boring number
(1, '1')
(2, '4')
14
14 is an positive boring number
(1, '1')
(2, '5')
15
15 is not a positive boring number

Thursday, February 25, 2021

Python 3.9.1 : Python and Spectator Earth.

The Spectator Earth allows you to track satellites, access their imagery, and easily build new information, based on data from this amazing orbital infrastructure.
You need just an API KEY to use it with cURL, Python, or JavaScript. 
In this tutorial, I will show you how can be used.
Login on the app.spectator.earth and get your API Key. 
Let's see some simple examples.
This first example shows you the satellite by id:
import requests

id = input("Type id sattelite: ")
satellite_id = id
url = 'https://api.spectator.earth/satellite/{satellite_id}'.format(satellite_id=satellite_id)

response = requests.get(url)
data = response.json()
print(data)
Let's see some satellite by ids:
[mythcat@desk Spectator]$ python  satellite_all.py 
Type id sattelite: 1
{'id': 1, 'type': 'Feature', 'geometry': {'type': 'Point', 'coordinates': [-51.88851761326367, 
70.75978200389422]}, 'properties': {'name': 'Sentinel-1A', 'norad_id': 39634, 'sensors': 
[{'type': 'SAR', 'avg_footprint_width': '3.20'}], 'open': True, 'platform': 'Sentinel-1A'}}
[mythcat@desk Spectator]$ python  satellite_all.py 
Type id sattelite: 2
{'id': 2, 'type': 'Feature', 'geometry': {'type': 'Point', 'coordinates': [42.046601163641796, 
-14.660442921557335]}, 'properties': {'name': 'Sentinel-2A', 'norad_id': 40697, 'sensors': 
[{'type': 'OPTICAL', 'avg_footprint_width': '2.32'}], 'open': True, 'platform': 'Sentinel-2A'}}
[mythcat@desk Spectator]$ python  satellite_all.py 
Type id sattelite: 3
{'id': 3, 'type': 'Feature', 'geometry': {'type': 'Point', 'coordinates': [-91.98478583784988, 
79.45732380441011]}, 'properties': {'name': 'Sentinel-3A', 'norad_id': 41335, 'sensors': 
[{'type': 'OPTICAL', 'avg_footprint_width': '10.16'}, {'type': 'OPTICAL', 
'avg_footprint_width': '11.20'}], 'open': True, 'platform': 'Sentinel-3A'}}
[mythcat@desk Spectator]$ python  satellite_all.py 
Type id sattelite: 4
Let's see one example with satellite overpasses:
import requests
import json
api_key = input("api_key :")
bbox = '19.59,49.90,20.33,50.21'
satellites = 'Sentinel-2A,Sentinel-2B'
url = 'https://api.spectator.earth/overpass/?api_key={api_key}&bbox={bbox}&
satellites={satellites}'.format(api_key=api_key, bbox=bbox, satellites=satellites)
response = requests.get(url)
data = response.json()
print(type(data))
print(data)
You can query for overpasses of the chosen satellite over a defined area of interest and the output provides you with a satellite sensor footprint for the nearest overpass, overpass frequency in seconds, and all information available.
Query parameters for the URL variable are:
The result is this:
[mythcat@desk Spectator]$ python satellite.py 
api_key :....
...
{'frequency': 93996, 'overpasses': [{'id': 16486437, 'acquisition': True, 'date': 
'2021-02-26T09:57:00Z', 'footprint': {'type': 'Polygon', 'coordinates': 
...
footprint': {'type': 'Polygon', 'coordinates': 
...
[[[19.153675312697636, 46.847554078717884], ... 
Query parameters for the url :
  • api_key - your API key
  • bbox - area of interest bounding box list of coords (lon, lat, lon, lat);
  • satellites - which satellites to include like: (Sentinel-1A, Sentinel-1A, Sentinel-2A, Sentinel-2B, Sentinel-3A, Landsat-8) - optional;
  • days_before - a number of days before the current date for which overpasses should be computed integer optional, default=0;
  • days_after - a number of days after the current date for which overpasses should be computed integer optional, default=7;
You can see a image get from my location:

Tuesday, January 26, 2021

Python 3.6.0 : Django 3.2 alpha 1 released.

Django is a high-level Python Web framework that encourages rapid development and clean, pragmatic design. Built by experienced developers, it takes care of much of the hassle of Web development, so you can focus on writing your app without needing to reinvent the wheel. It’s free and open source. 

I tested it and I was satisfied with the way it works with this framework and it has many good features for the web. 
Django 3.2 is designated as a long-term support release.

Today, Django 3.2 alpha 1 is available with new features.
A good roadmap towards Django 3.2. can be found on this schedule webpage.
As with all alpha and beta packages, this is not for production use.
Django 3.2 supports Python 3.6, 3.7, 3.8, and 3.9. The next release is expected in April 2021, see:
  • January 14, 2021, Django 3.2 alpha; feature freeze;
  • February 18 Django 3.2 beta; non-release blocking bug fix freeze;
  • March 18 Django 3.2 RC 1; translation string freeze;
  • April 6 Django 3.2 final release.

Sunday, December 27, 2020

Python 3.9.1 : Testing the drawSvg python package.

The tutorial for today is about drawSvg python package.
This python package let you to create SVG images (vector drawings) and rendering them or displaying them in a Jupyter notebook.
Let's install it with pip3 tool:
[mythcat@desk ~]$ cd PythonProjects/
[mythcat@desk PythonProjects]$ pip3 install drawSvg
...
Successfully installed drawSvg-1.7.0 imageio-2.9.0
A simple source code test added to svg_001.py python script:
import drawSvg as draw

# Draw a frame of the animation
def draw_frame(t):
    #Create draw surface and add a geometric shapes ...
    out = draw.Drawing(1, 1, origin=(0,0))
    out.setRenderSize(h=460)
    out.append(draw.Rectangle(0, 0, 5, 5, fill='white'))
    y = t + 0.3
    out.append(draw.Circle(0.5, y, 0.5, fill='blue'))
    return out

with draw.animate_video('example.gif', draw_frame, duration=0.01) as anim:
    # Add each frame to the animation
    for i in range(20):
        anim.draw_frame(i/10)
You can change the source code and open the GIF animation file:
[mythcat@desk PythonProjects]$ vi svg_001.py
[mythcat@desk PythonProjects]$ python svg_001.py 
[mythcat@desk PythonProjects]$ google-chrome example.gif
The result of the source code is this:

Monday, December 21, 2020

Python 3.6.9 : Ursina python game engine - part 001 .

I wrote the tutorial a few days ago and today I completed it with a video clip ...
The official webpage comes with this intro:
Ursina makes it easier to develop games, visualizations and other kinds of software.
The concise API combined with the power of the Python programming language, makes life easier for the developer so they can focus on what they are making.

Ursina can be used on Windows and Linux
Today I tested on Fedora Linux and works great.
First, the install process is easy with pip3 tool.
[mythcat@desk ~]$ pip3 install ursina
Defaulting to user installation because normal site-packages is not writeable
Requirement already satisfied: ursina in ./.local/lib/python3.9/site-packages (3.2.2)
Requirement already satisfied: screeninfo in ./.local/lib/python3.9/site-packages (from ursina) (0.6.6)
Requirement already satisfied: numpy in /usr/lib64/python3.9/site-packages (from ursina) (1.19.4)
Requirement already satisfied: panda3d in ./.local/lib/python3.9/site-packages (from ursina) (1.10.7)
Requirement already satisfied: pyperclip in ./.local/lib/python3.9/site-packages (from ursina) (1.8.1)
Requirement already satisfied: pillow in /usr/lib64/python3.9/site-packages (from ursina) (7.2.0)
Let's create some examples and see how this python package works.
Create a python script file:
[mythcat@desk ~]$ cd PythonProjects/
[mythcat@desk PythonProjects]$ vi ursina_001.py
Add this simple example:
from ursina import *
# create the application
app = Ursina()
# set some data , like a cube
ground = Entity(
    model = 'cube',
    color = color.blue,
    z = -.1,
    y = -3,
    origin = (0, .5),
    scale = (50, 1, 10),
    collider = 'box'
    )
# run the application
app.run()
And the last pas, run it with python:
[mythcat@desk PythonProjects]$ python ursina_001.py 
ursina version: 3.2.2
package_folder: /home/mythcat/.local/lib/python3.9/site-packages/ursina
asset_folder: .
psd-tools not installed
which: no blender in (/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:
/home/mythcat/.composer/vendor/bin:/home/mythcat/.dotnet/tools:/var/lib/snapd/snap/bin)
blender_paths:
{}
OS: posix
screen resolution: (1280, 1024)
Known pipe types:
  glxGraphicsPipe
(all display modules loaded.)
render mode: default
no settings.py file
no settings.py file
development mode: True
application successfully started
You can read on web!:

Sunday, December 6, 2020

Python 3.6.9 : My colab tutorials - part 010.

In this tutorial created with Colab online tool I used HTML and JavaScript source code.
The tutorial is easy to understand and use it.
You can see all my examples of my GitHub repo.

Thursday, December 3, 2020

Python 3.6.9 : My colab tutorials - part 009.

I update may colab work and I add new notebooks.
You can see all of these on my GitHub account.
These are examples:
  • 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;

Sunday, November 22, 2020

Python 3.9.0 : Physics simulation with PyBullet .

I took a look at the documentation of this python packet to give you a brief introduction:
PyBullet is a fast and easy to use Python module for robotics simulation and machine learning, with a focus on sim-to-real transfer. With PyBullet you can load articulated bodies from URDF, SDF, MJCF and other file formats. PyBullet provides forward dynamics simulation, inverse dynamics computation, forward and inverse kinematics, collision detection and ray intersection queries. The Bullet Physics SDK includes PyBullet robotic examples such as a simulated Minitaur quadruped, humanoids running using TensorFlow inference and KUKA arms grasping objects.
...
PyBullet can be easily used with TensorFlow and OpenAI Gym.
...
The GUI connection will create a new graphical user interface (GUI) with 3D OpenGL rendering, within the same process space as PyBullet. On Linux and Windows this GUI runs in a separate thread, while on OSX it runs in the same thread due to operating system limitations.
...
For UDP networking, there is a App_PhysicsServerUDP that listens to a certain UDP port.
...
By default, there is no gravitational force enabled. setGravity lets you set the default gravity force for all objects. The loadURDF will send a command to the physics server to load a physics model from a Universal Robot Description File (URDF). The URDF file is used by the ROS project (Robot Operating System) to describe robots and other objects, it was created by the WillowGarage and the Open Source Robotics Foundation (OSRF).

I tested with Fedora 33 and Python version 3.9.0.
The first step was installation.
[mythcat@desk ~]$ pip3 install pybullet --upgrade --user
Collecting pybullet
  Downloading pybullet-3.0.6.tar.gz (89.8 MB)
     |████████████████████████████████| 89.8 MB 51 kB/s 
Using legacy 'setup.py install' for pybullet, since package 'wheel' is not installed.
Installing collected packages: pybullet
    Running setup.py install for pybullet ... done
Successfully installed pybullet-3.0.6
The next step was to test with examples already built using urdf file type.
import pybullet as p
# Can alternatively pass in p.DIRECT 
client = p.connect(p.GUI)
p.setGravity(0, 0, -10, physicsClientId=client) 

import pybullet_data
p.setAdditionalSearchPath(pybullet_data.getDataPath())
planeId = p.loadURDF("plane.urdf")

my_racecar = p.loadURDF("racecar/racecar.urdf", basePosition=[0,0,0.2])

position, orientation = p.getBasePositionAndOrientation(my_racecar)

for _ in range(10000): 
    p.stepSimulation()
I run the script and all works well.
It can be seen that in the cycle for which I have the simulation for 10000 steps of time.
A smaller number will quickly interrupt the simulation.
You can create your own URDF files because they are formatted in XML format.
A good area for learning is this webpage.

Saturday, October 31, 2020

Python 3.9.0 : Testing twisted python module - part 001 .

Today I tested two python modules named: twisted and twisted[tls].
Twisted is an event-driven network programming framework written in Python and licensed under the MIT License. Twisted projects variously support TCP, UDP, SSL/TLS, IP multicast, Unix domain sockets, many protocols (including HTTP, XMPP, NNTP, IMAP, SSH, IRC, FTP, and others), and much more. Twisted is based on the event-driven programming paradigm, which means that users of Twisted write short callbacks which are called by the framework., see wikipedia webpage.
In this tutorial I will show you only some of these tests and how you can work with these python modules.
About twisted you can read more at the official webpage. In Fedora distro version 33 you can use the dnf tool to search for and install these python packages.
[root@desk mythcat]# dnf search twisted
...
python3-twisted.x86_64 : Twisted is a networking engine written in Python
python3-twisted+tls.x86_64 : Metapackage for python3-twisted: tls extras
You can also use the pip tool for installation:
[mythcat@desk ~]$ cd PythonProjects/
[mythcat@desk PythonProjects]$ pip3 install twisted
...
[mythcat@desk PythonProjects]$ pip3 install twisted[tls]
...
I used python 3.9.0 to test if this python package works:
[mythcat@desk PythonProjects]$ python3.9
Python 3.9.0 (default, Oct  6 2020, 00:00:00) 
[GCC 10.2.1 20200826 (Red Hat 10.2.1-3)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from twisted.protocols import basic
Let's test with simple example using the reactor and protocol:
from twisted.internet import reactor, protocol

class ClientEcho(protocol.Protocol):
    def connectionMade(self):
        self.transport.write("Hello, world!".encode('utf-8'))

    def dataReceived(self, data):
        print ("Server: ", data)
        self.transport.loseConnection()

class FactoryEcho(protocol.ClientFactory):
    def buildProtocol(self, addr):
        return ClientEcho()

    def clientConnectionFailed(self, connector, reason):
        print ("Connection failed")
        reactor.stop()

    def clientConnectionLost(self, connector, reason):
        print ("Connection lost")
        reactor.stop()

reactor.connectTCP("localhost", 8080, FactoryEcho())
reactor.run()
Your protocol handling class will usually subclass twisted.internet.protocol.Protocol.
The default factory class twisted.internet.protocol.Factory just instantiates each Protocol and lets every Protocol access, and possibly modify, the persistent configuration.
This protocol responds to the initial connection with a well known quote, and then terminates the connection.
The protocol never waits for an event because handles data in an asynchronous manner.
The reactor interface lets many different loops handle the networking code.
The source code have two classes each is used to show a simple echo client on port 8080 - you can use any port.
This source code is the most simple example to understand the relation between factory , protocol and reactor.
The result is this:
[mythcat@desk PythonProjects]$ python3.9 echo_client_001.py 
Server:  b'Hello, world!'
Connection lost

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: