analitics

Pages

Showing posts with label module. Show all posts
Showing posts with label module. Show all posts

Wednesday, January 11, 2023

Python 3.7.9 : simple zodiac diagrams with ephem and matplotlib.

I used openai chat to test another issue with these python packages: ephem and matplotlib.
It seems that openai is limited to new changes in python packages, but it resolves quite well combinations of source code that it has corrected with defined errors. It can't really extract source code from general questions. Anyway, it is a very good help for a programmer in the initial phase of any project.
This source code show two diagrams about the solar system on a specific date:
import ephem
import matplotlib.pyplot as plt

# create an observer
obs = ephem.Observer()

# set the observer's location
obs.lat = '47.27' # latitude
obs.lon = '26.18' # longitude
obs.elevation = 307 # elevation (meters)

# set the date and time of the observation
obs.date = '2022/05/15 12:00:00' # date and time
# if you want you can use now() for real time data

# create the bodies
mercury = ephem.Mercury(obs)
venus = ephem.Venus(obs)
mars = ephem.Mars(obs)
jupiter = ephem.Jupiter(obs)
saturn = ephem.Saturn(obs)
uranus = ephem.Uranus(obs)
neptune = ephem.Neptune(obs)
pluto = ephem.Pluto(obs)
moon = ephem.Moon(obs) 

# compute the position of each planet and the moon
mercury.compute(obs)
venus.compute(obs)
mars.compute(obs)
jupiter.compute(obs)
saturn.compute(obs)
uranus.compute(obs)
neptune.compute(obs)
pluto.compute(obs)
moon.compute(obs)  

# extract ra and dec coordinates of each body
ra = [mercury.ra, venus.ra, mars.ra, jupiter.ra, saturn.ra, uranus.ra, neptune.ra, pluto.ra,moon.ra]
dec = [mercury.dec, venus.dec, mars.dec, jupiter.dec, saturn.dec, uranus.dec, neptune.dec, pluto.dec,moon.dec]

# convert ra,dec from radians to degrees
ra = [r*180/ephem.pi for r in ra]
dec = [d*180/ephem.pi for d in dec]
print(ra,dec)
# create a scatter plot of the positions
plt.scatter(ra, dec)

# add labels for each planet
plt.annotate('Mercury', (ra[0], dec[0]))
plt.annotate('Venus', (ra[1], dec[1]))
plt.annotate('Mars', (ra[2], dec[2]))
plt.annotate('Jupiter', (ra[3], dec[3]))
plt.annotate('Saturn', (ra[4], dec[4]))
plt.annotate('Uranus', (ra[5], dec[5]))
plt.annotate('Neptune', (ra[6], dec[6]))
plt.annotate('Pluto', (ra[7], dec[7]))
plt.annotate('Moon', (ra[8], dec[8]))

plt.xlabel("RA [degrees]")
plt.ylabel("Dec [degrees]")

# show the plot
plt.show()

# Set the figure size
plt.figure(figsize=(10, 10))

# Define the polar axis
ax = plt.subplot(111, projection='polar')

# Set the axis limits
ax.set_ylim(0, 36)

# Plot the Sun at the center
plt.scatter(0, 0, s=200, color='yellow')

mercury_distance = mercury.earth_distance
venus_distance= venus.earth_distance
mars_distance= mars.earth_distance
jupiter_distance= jupiter.earth_distance
saturn_distance= saturn.earth_distance
uranus_distance= uranus.earth_distance
neptune_distance= neptune.earth_distance
pluto_distance= pluto.earth_distance
moon_distance= moon.earth_distance
print(mercury_distance)
distance = [mercury_distance,venus_distance,mars_distance,jupiter_distance,saturn_distance,uranus_distance,neptune_distance,pluto_distance,moon_distance]

# Plot the planets
plt.scatter(ra[0], distance[0], s=20, color='green')
plt.scatter(ra[1], distance[1], s=50, color='orange')
plt.scatter(ra[2], distance[2], s=80, color='red')
plt.scatter(ra[3], distance[3], s=120, color='brown')
plt.scatter(ra[4], distance[4], s=150, color='tan')
plt.scatter(ra[5], distance[5], s=100, color='blue')
plt.scatter(ra[6], distance[6], s=80, color='cyan')
plt.scatter(ra[7], distance[7], s=40, color='purple')
plt.scatter(ra[8], distance[8], s=20, color='gray')

# add the labels for each planet
plt.annotate('Mercury',(ra[0], distance[0]),xytext=(ra[0], distance[0] - 2))
plt.annotate('Venus',(ra[1], distance[1]),xytext=(ra[1], distance[1] - 2))
plt.annotate('Mars',(ra[2], distance[2]),xytext=(ra[2], distance[2] - 2))
plt.annotate('Jupiter',(ra[3], distance[3]),xytext=(ra[3], distance[3] - 4))
plt.annotate('Saturn',(ra[4], distance[4]),xytext=(ra[4], distance[4] - 4))
plt.annotate('Uranus',(ra[5], distance[5]),xytext=(ra[5], distance[5] - 2))
plt.annotate('Neptune',(ra[6], distance[6]),xytext=(ra[6], distance[6] - 2))
plt.annotate('Pluto',(ra[7], distance[7]),xytext=(ra[7], distance[7] - 2))
plt.annotate('Moon',(ra[8], distance[8]),xytext=(ra[8], distance[8] - 2))

# Show the plot
plt.show()
This is the result of this source code:

Python 3.7.9 : simple zodiac constellation with ephem.

This time I used openai chat to create my source code and with small changes it worked…
PyEphem provides an ephem Python package for performing high-precision astronomy computations. The underlying numeric routines are coded in C and are the same ones that drive the popular XEphem astronomy application, whose author, Elwood Charles Downey, generously gave permission for their use in PyEphem. The name ephem is short for the word ephemeris, which is the traditional term for a table giving the position of a planet, asteroid, or comet for a series of dates.
import ephem

# create an observer
obs = ephem.Observer()

# set the observer's location
obs.lat = '47.27' # latitude
obs.lon = '26.18' # longitude
obs.elevation = 307 # elevation (meters)

# set the date and time of the observation
obs.date = '2022/05/15 12:00:00' # date and time

# create the bodies
mercury = ephem.Mercury(obs)
venus = ephem.Venus(obs)
mars = ephem.Mars(obs)
jupiter = ephem.Jupiter(obs)
saturn = ephem.Saturn(obs)
uranus = ephem.Uranus(obs)
neptune = ephem.Neptune(obs)
pluto = ephem.Pluto(obs)
moon = ephem.Moon(obs)

# print the constellation
print("Mercury:", ephem.constellation(mercury))
print("Venus:", ephem.constellation(venus))
print("Mars:", ephem.constellation(mars))
print("Jupiter:", ephem.constellation(jupiter))
print("Saturn:", ephem.constellation(saturn))
print("Uranus:", ephem.constellation(uranus))
print("Neptune:", ephem.constellation(neptune))
print("Pluto:", ephem.constellation(pluto))
print("Moon:", ephem.constellation(moon))
This is result of the running source code:
python constelation001.py
Mercury: ('Tau', 'Taurus')
Venus: ('Psc', 'Pisces')
Mars: ('Aqr', 'Aquarius')
Jupiter: ('Psc', 'Pisces')
Saturn: ('Cap', 'Capricornus')
Uranus: ('Ari', 'Aries')
Neptune: ('Psc', 'Pisces')
Pluto: ('Sgr', 'Sagittarius')
Moon: ('Lib', 'Libra')

Tuesday, January 10, 2023

Python 3.7.9 : simple zodiac with pyephem and ephem.

I don't know how to calculate a zodiac exactly, from what I understand the planets and the moon must overlap. so I tested a script that calculates the dates between the planets and the moon when they appear within one degree of each other and displays them in an array with rows and columns created from these planets and the moon. The intersections on the diagonal should be none because there's obviously no way to overlap the same object, and they only occur when there's this less than one degree rule.
If you think it is wrong then you can try to fix it.
You can install pyephem and ephem with pip tool, I used both python packages:
pip install pyephem --user
Requirement already satisfied: pyephem in 
... site-packages (9.99)
Requirement already satisfied: ephem in 
...
site-packages (from pyephem) (4.1.4)
This is the source script.
import ephem

# create a list with planets objects from ephem
planets = [ephem.Mercury(), ephem.Venus(), ephem.Mars(), ephem.Jupiter(), ephem.Saturn(), ephem.Uranus(), ephem.Neptune(), ephem.Moon()]

start_date = ephem.Date("2023/01/01")
end_date = ephem.Date("2023/12/31")
date = start_date

# create matrix to store planet names and conjunction dates
matrix = [[None for _ in range(len(planets) + 1)] for _ in range(len(planets))]

# create list to store planet names
planet_names = [planet.name for planet in planets]
# list all planets names as first row in matrix
matrix.insert(0, [""] + planet_names)

while date < end_date:
    for i, planet1 in enumerate(planets):
        for j, planet2 in enumerate(planets):
            if i < j:
                planet1.compute(date)
                planet2.compute(date)
                sep = ephem.separation(planet1, planet2) #  calculate the angular distance
                # compare the separation, if less than 0.01 degree then it's a conjunction
                if sep < 1.0:
                    date_formatted = date.datetime().strftime("%d %B %Y")
                    matrix[i+1][j+1] = date_formatted
                    break
    date = ephem.Date(date + 1)
# print a matrix with date is separation from 1 degree between planets on rows and column
for row in matrix:
    print(row)
This is the result:
['', 'Mercury', 'Venus', 'Mars', 'Jupiter', 'Saturn', 'Uranus', 'Neptune', 'Moon']
[None, None, '30 December 2023', '14 December 2023', '20 June 2023', None, None, None, None]
[None, None, None, '30 December 2023', '15 March 2023', '06 January 2023', None, None, '12 October 2023']
[None, None, None, None, None, None, '24 April 2023', None, '16 December 2023']
[None, None, None, None, None, '05 June 2023', '30 December 2023', None, None]
[None, None, None, None, None, None, None, '30 December 2023', None]
[None, None, None, None, None, None, None, '30 December 2023', None]
[None, None, None, None, None, None, None, None, '23 December 2023']
[None, None, None, None, None, None, None, None, None]

Sunday, January 8, 2023

Python 3.7.9 : The sunpy python package - part 001.

In the past, I have written several small tutorials related to this Python package. Now I have some news related to the sunpy python package:
  • HelioviewerClient is deprecated;
  • The Helioviewer Project now maintains a Python Wrapper called hvpy.
  • sunpy users are encouraged to upgrade parfive python package;
  • the sunpy.database deprecation;
  • the sample data files provided through sunpy.data.sample are now downloaded individually on demand;
  • SunPy is tested against Python 2.7, 3.5, and 3.6.;
  • SunPy no longer supports Python 3.4.;
  • easy to extract data values from a GenericMap along a curve specified by a set of coordinates using the new sunpy.map.extract_along_coord function;
  • has a new make_heliographic_header() function that simplifies creating map headers that span the whole solar surface in Carrington or Stonyhurst coordinates;
  • aiaprep is now deprecated;
  • ... and more on the official website.
I install this python package on the Windows OS with the pip tool:
pip install "sunpy[all] -U"
You can install extra available options: [asdf], [dask], [database], [image], [jpeg2000], [map], [net], [timeseries], [visualization].
You can see the version of this python package with this source code:
 import sunpy
print(sunpy.__version__)
3.1.8
I tested this package with this simple source code:
from matplotlib import pyplot as plt
import sunpy.map
import sunpy.data.sample  
sunpyAIA = sunpy.map.Map(sunpy.data.sample.AIA_171_IMAGE) 
sunpyAIA.plot()
plt.colorbar()
plt.show()
The instrument is AIA and the measurement is 171, see more on this online tool named helioviewer.
After I run I got this image:

Python 3.11.0 : The scapy python module - part 003.

Scapy is a powerful interactive packet manipulation program. It is able to forge or decode packets of a wide number of protocols, send them on the wire, capture them, match requests and replies, and much more. It can easily handle most classical tasks like scanning, tracerouting, probing, unit tests, attacks or network discovery (it can replace hping, 85% of nmap, arpspoof, arp-sk, arping, tcpdump, tshark, p0f, etc.). It also performs very well at a lot of other specific tasks that most other tools can’t handle, like sending invalid frames, injecting your own 802.11 frames, combining technics (VLAN hopping+ARP cache poisoning, VOIP decoding on WEP encrypted channel, …), etc.
First, you need to install it with pip tool: pip install scapy --user.
I used with WinPcap from this webpage, but you will see the recomandation is to use Npcap.
#!/usr/bin/env python3
import os
print(os.sys.path)
from scapy.all import *

def mysniff(interface):
    sniff(iface=interface, store=False, prn=process_sniffed_packet)

def process_sniffed_packet(packet):
    pyperclip.copy(str(packet))
    print(packet)

mysniff("Realtek PCIe GbE Family Controller")
The running result is something like this:
...
WARNING: WinPcap is now deprecated (not maintained). Please use Npcap instead
Ether / IP / TCP 104.244.42.2:https > 192.168.0.143:55478 PA / Raw
Ether / IP / TCP 192.168.0.143:55478 > 104.244.42.2:https PA / Raw
Ether / IP / TCP 192.168.0.143:55478 > 104.244.42.2:https PA / Raw
Ether / IP / TCP 104.244.42.2:https > 192.168.0.143:55478 A / Padding
Ether / IP / TCP 104.244.42.2:https > 192.168.0.143:55478 A / Padding
Ether / ARP who has 192.168.0.1 says 192.168.0.206 / Padding
...

Thursday, January 5, 2023

Python Qt6 : Create a tray icon application.

The notification area known as system tray is located in the Windows Taskbar area, usually at the bottom right corner.
I tested with:
Python 3.10.2 (tags/v3.10.2:a58ebcc, Jan 17 2022, 14:12:15) [MSC v.1929 64 bit (AMD64)] on win32
...
pip show pyqt6
Name: PyQt6
Version: 6.4.0
Summary: Python bindings for the Qt cross platform application toolkit
I created a trayicon application with PyQt6 that show a menu with two entry: Show Window and Exit.
The Show Window will sow a default window and the Exit will close the application.
This is the source code I tested, you need an icon.png in the same folder with this script.
import sys
from PyQt6.QtCore import Qt, QEvent, QPoint
from PyQt6.QtGui import QGuiApplication, QIcon, QAction
from PyQt6.QtWidgets import QApplication, QSystemTrayIcon, QMainWindow, QMenu

# create the default application
app = QApplication(sys.argv)

# create the main window
window = QMainWindow()
# set the title for the window
window.setWindowTitle("My Window")

# this set the tray icon and menu
tray_icon = QSystemTrayIcon()
tray_icon.setIcon(QIcon("icon.png"))
menu = QMenu()

# add an action to the menu to show the window
show_window_action = QAction("Show Window", None)
show_window_action.triggered.connect(window.show)
menu.addAction(show_window_action)

# add an action to the menu to exit the application
exit_action = QAction("Exit", None)
exit_action.triggered.connect(app.quit)
menu.addAction(exit_action)

# set the context menu
tray_icon.setContextMenu(menu)

# show the tray icon
tray_icon.show()

# run the application
app.exec()

Tuesday, January 3, 2023

Manim python example.

I have written before about manim as a Python package in this tutorial.
It's quite powerful for animation and I recommend it to content producers who need a tool for school board-like graphics.
Today I'm back with a link that a document written in Jupiter notebook with Manim package from manim community, see this link.

Wednesday, December 28, 2022

Python 3.10.2 : Copernicus A.P.I. and python sentinelsat python package - part 001.

Last night I worked a bit with python and tested on the online tool from Copernicus.
Copernicus is the European Union's Earth observation programme, which analyzes our planet and its environment for the benefit of all European citizens.
If you want to test it with python or another A.P>I. you need to create an user and a apassword.This is the source code I used with S:
from sentinelsat import SentinelAPI, read_geojson, geojson_to_wkt
from datetime import date
# Connect to the Sentinel API
api = SentinelAPI('___', '___', 'https://scihub.copernicus.eu/dhus')
#
api.download('___from_copernicus_website___')
# Search for Sentinel-2 images covering a specific area
footprint = geojson_to_wkt(read_geojson('area_of_interest.geojson'))

products = api.query(footprint,
                     date=('20211201', '20211205'),
                     platformname='Sentinel-1')
# convert to Pandas DataFrame
products_df = api.to_dataframe(products)
print(products_df)
# sort and limit to first 5 sorted products
products_df_sorted = products_df.sort_values(['link'], ascending=[True])
products_df_sorted = products_df_sorted.head(5)

# download sorted and reduced products
api.download_all(products_df_sorted.index)
You need a JSOn file to select the area of interest:
After I run this python script, the result is this:
python test001.py
                                                                                  title  ... productconsolidation
8f12995e-8f4b-4634-91bb-4971a1bdd0c3  S1B_IW_SLC__1SDV_20211201T160049_20211201T1601...  ...                  NaN
c62ceac6-c9ac-409d-bea9-d1bc23b1b183  S1B_IW_GRDH_1SDV_20211201T160050_20211201T1601...  ...                  NaN
2d1319c5-60af-468b-904a-5dfbdd5f205c  S1B_IW_RAW__0SDV_20211201T160046_20211201T1601...  ...                SLICE

[3 rows x 36 columns]
Downloading S1B_IW_GRDH_1SDV_20211201T160050_20211201T160115_029834_038FB2_A390.zip: 100%|█| 929M/929M [02:44<00:00, 5.
Downloading products:  33%|██████████████████▋                                     | 1/3 [02:58<05:57, 178.58s/product]
Downloading S1B_IW_RAW__0SDV_20211201T160046_20211201T160119_029834_038FB2_D35D.zip:  83%|▊| 1.31G/1.58G [03:21<00:26,
Downloading S1B_IW_SLC__1SDV_20211201T160049_20211201T160116_029834_038FB2_AC13.zip:  31%|▎| 1.33G/4.35G [03:18<04:16,
...
The copernicus online map can be seen in the next inage:

Friday, October 7, 2022

Python 3.10.7 : Rembg for remove background.

Rembg is a tool to remove images background and the project can be found on the GitHub webpage.
Create a python file named remove_background.py.
Install using the pip tool.
pip install rembg
Collecting rembg
  Downloading rembg-2.0.25-py3-none-any.whl (12 kB)
Add this source code and the input001.png image for procesing in the same folder with the python script.
from rembg import remove 
from PIL import Image 
input_path = 'input001.png'
output_path = 'output001.png'
input = Image.open(input_path)
output = remove(input)
output.save(output_path)
Run the python script and if you see this error:
python remove_background.py
Access denied with the following error:

        Too many users have viewed or downloaded this file recently. Please
        try accessing the file again later. If the file you are trying to
        access is particularly large or is shared with many people, it may
        take up to 24 hours to be able to view or download the file. If you
        still can't access a file after 24 hours, contact your domain
        administrator.

You may still be able to access the file from the browser:

         https://drive.google.com/uc?id=1tCU5MM1LhRgGou5OpmpjBQbSrYIUoYab
         ...
... then copy the u2net.onnx file into this path:
C:\Users\your_user\.u2net\
After I copy the file I run again the python script and this is the result.

Sunday, September 11, 2022

Python : Blockchain Programming - part 001.

This is the first tutorial in the blockchain programming series using the python programming language.
To program a blockchain, we must consider two elements: in addition to the blockchain address, it can have a programmable area and the second essential element, the interaction of the blockchain with external web areas can be programmed.
In this tutorial I will use the python web3 package, an etherium address and an online web utility called infura.io.
In the infura.io account, create a web3 project and in the dashboard - manage key you will have to add the ethereum address and use the url created to mainnet.infura.io.
I created a project in python in Fedora 37 using the conda utility and installed the web3 package.
Here is the python source code I used
from web3 import Web3
node_provider = "https://mainnet.infura.io/v3/1f2fb5d1e1be4c11acdbbb07a2e06a1c"

web3_connection = Web3(Web3.HTTPProvider(node_provider))


def is_connected():
    print(web3_connection.isConnected())

def latest_block():
    print(web3_connection.eth.block_number)

def balanceETH(ETH_address):
    balance = web3_connection.eth.get_balance(ETH_address)
    balance_for_ETH = web3_connection.fromWei(balance,'ether')
    print(balance_for_ETH)
Here is the answer to running this source code using the etherium address:
(web3_001) [mythcat@fedora PythonProjects]$ vi web3_func_001.py
(web3_001) [mythcat@fedora PythonProjects]$ python
Python 3.9.13 (main, Aug 25 2022, 23:26:10)
[GCC 11.2.0] :: Anaconda, Inc. on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from web3_func_001 import *
>>> is_connected()
True
>>> latest_block()
15516253
>>> balanceETH("0x74E55f28a8A0158b466FcB481EC7e6bE45D1DB91")
0
Since it is a rather complex field, I will come back with other tutorials when I have the necessary resources.

Monday, August 15, 2022

Blender 3D and python scripting - part 025.

In this tutorial I will show a simple python script for add a String interface to the Group Output.
You can see in the next image the result of this script.
You need to have an modifier Geometry Nodes or add new one.
This is the source script with comments for each step I used:
import bpy

#get active object - default 
obj = bpy.context.active_object

# set the default start for working with Geometry Nodes modifier
# you need to have a Geometry Nodes modifier
node_group = obj.modifiers['GeometryNodes'].node_group
nodes = node_group.nodes

#get the node named 'Group Output'
geom_out = nodes.get('Group Output')

#create a string node 
string_node = nodes.new('FunctionNodeInputString')
# set the name to 'String'
string_out = string_node.outputs['String']
# set the value to "This is a string"
string_node.string = "This is a string"

# link to the Group Output
node_group.links.new(string_out, geom_out.inputs[-1])

Wednesday, August 10, 2022

Python 3.10.7 : Manim python package - part 001.

Manim is an engine for precise programmatic animations, designed for creating explanatory math videos, see the official GitHub repo.
Let's install this python package.
python.exe -m pip install manim
...
Successfully installed Pillow-9.2.0 Pygments-2.12.0 certifi-2022.6.15 charset-no
rmalizer-2.1.0 click-8.1.3 click-default-group-1.2.2 cloup-0.13.1 colour-0.1.5 c
ommonmark-0.9.1 decorator-5.1.1 glcontext-2.3.6 idna-3.3 isosurfaces-0.1.0 manim
-0.16.0.post0 manimpango-0.4.1 mapbox-earcut-0.12.11 moderngl-5.6.4 moderngl-win
dow-2.4.1 multipledispatch-0.6.0 networkx-2.8.5 pycairo-1.21.0 pydub-0.25.1 pygl
et-1.5.26 pyrr-0.10.3 requests-2.28.1 rich-12.5.1 scipy-1.9.0 screeninfo-0.8 ski
a-pathops-0.7.2 srt-3.5.2 tqdm-4.64.0 urllib3-1.26.11 watchdog-2.1.9 
You need to install the ffmepg software and add this to the environment path.
The default source code for create a circle is this:
from manim import *

# a simple python class
class DefaultClassExample(Scene):
    def construct(self):
        # add a circle 
        circle = Circle()
        # create a animation 
        self.play(Create(circle))
Use this command to create a video with this source code
manim -pql manim_001.py test
Manim Community v0.16.0.post0
...
INFO     Previewed File at: 'C:\Python310\media\videos\manim_001\480p15\DefaultClassExample.mp4'
...
This is the result of this command:

Blender 3D and python scripting - part 024.

In this tutorial I will show you how to use GeometryNodes with python script and Blender A.P.I.
You can see the result in the next image.
The Object Info node gets information from objects. This can be useful to control parameters in the geometry node tree with an external object, either directly by using its geometry, or via its transformation properties. An Object Info node can be added quickly by dragging an object into the node editor.
Another information can be found on the manual link.
In the next script you can see I created a simple BezierCurve object.
The definition named new_GeometryNodes_group is used to create two nodes GroupInit and GroupOutput.
I commente the source code to see some steps.
# import python packages
import bpy
from mathutils import Vector

# create a simpple BezierCurve and rename it with 'BezierCurveGeormetryNode'
bpy.ops.curve.primitive_bezier_curve_add()
bpy.ops.object.modifier_add(type='NODES')  

curve = bpy.context.active_object
curve.name = 'BezierCurveGeormetryNode'

# define a function for GroupInit and GroupOutput
def new_GeometryNodes_group():
    ''' Create a new empty node group that can be used
        in a GeometryNodes modifier.
    '''
    node_group = bpy.data.node_groups.new('GeometryNodes', 'GeometryNodeTree')
    inNode = node_group.nodes.new('NodeGroupInput')
    inNode.outputs.new('NodeSocketGeometry', 'Geometry')
    outNode = node_group.nodes.new('NodeGroupOutput')
    outNode.inputs.new('NodeSocketGeometry', 'Geometry')
    node_group.links.new(inNode.outputs['Geometry'], outNode.inputs['Geometry'])
    # the -3.5 is value for how far will be set the GroupInit and GroupOutput in the area of GeormetryNodes
    inNode.location = Vector((-3.5*inNode.width, 0))
    outNode.location = Vector((3.5*outNode.width, 0))
    return node_group

# the default curve modifier has no node group set, you need to set :
if curve.modifiers[-1].node_group:
    node_group = curve.modifiers[-1].node_group    
else:
    node_group = new_GeometryNodes_group()
    curve.modifiers[-1].node_group = node_group

# set default grup node as nodes
nodes = node_group.nodes

# get both nodes for each one 
group_in = nodes.get('Group Input')
group_out = nodes.get('Group Output')

# add the GeometryNodeObjectInfo to the GeometryNode area 
new_node_obj = nodes.new('GeometryNodeObjectInfo')
new_node_obj.inputs[0].default_value = bpy.data.objects["BezierCurveGeormetryNode"]

Monday, August 8, 2022

Python 3.10.4 : EbookLib python library - part 001.

EbookLib is a Python library for managing EPUB2/EPUB3 files. It’s capable of reading and writing EPUB files programmatically.
You can read more about this python library on this website.
First, I install with the pip tool:
C:\Python310>python -m pip install --upgrade pip
Requirement already satisfied: pip in c:\python310\lib\site-packages (22.1)
Collecting pip
  WARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, stat
us=None)) after connection broken by 'NewConnectionError(': Failed to establish a n
ew connection: [Errno 11001] getaddrinfo failed')': /packages/1f/2c/d9626f045e7b
49a6225c6b09257861f24da78f4e5f23af2ddbdf852c99b8/pip-22.2.2-py3-none-any.whl
  Downloading pip-22.2.2-py3-none-any.whl (2.0 MB)
     ---------------------------------------- 2.0/2.0 MB 1.5 MB/s eta 0:00:00
Installing collected packages: pip
  Attempting uninstall: pip
    Found existing installation: pip 22.1
    Uninstalling pip-22.1:
      Successfully uninstalled pip-22.1
Successfully installed pip-22.2.2

C:\Python310>python -m pip install lxml-4.9.0-cp310-cp310-win_amd64.whl
Processing c:\python310\lxml-4.9.0-cp310-cp310-win_amd64.whl
Installing collected packages: lxml
Successfully installed lxml-4.9.0

C:\Python310>python -m pip install EbookLib --user
Collecting EbookLib
  Using cached EbookLib-0.17.1.tar.gz (111 kB)
  Preparing metadata (setup.py) ... done
Requirement already satisfied: lxml in c:\python310\lib\site-packages (from Eboo
kLib) (4.9.0)
Collecting six
  Using cached six-1.16.0-py2.py3-none-any.whl (11 kB)
Using legacy 'setup.py install' for EbookLib, since package 'wheel' is not insta
lled.
Installing collected packages: six, EbookLib
  Running setup.py install for EbookLib ... done
Successfully installed EbookLib-0.17.1 six-1.16.0
I used a the simple python script from the last tutorial to test it:
The last tutorial used the default script from the official webpage.
Compared to the default script, I made changes, the selection in the Romanian language and diacritics...
from ebooklib import epub

book = epub.EpubBook()

# set metadata
book.set_identifier('__1976')
book.set_title('')
book.set_language('en')

book.add_author('Autho: Cătălin George Feștilă')

# create chapter
cap001 = epub.EpubHtml(title='Intro', file_name='capitolul_01.xhtml', lang='ro')
cap001.content=u'<h1>Introducere</h1><p>Această carte este...</p>'

# add chapter
book.add_item(cap001)

# define Table Of Contents
book.toc = (epub.Link('capitolul_01.xhtml', 'Introducere', 'introducere'),
             (epub.Section('O carte simplă'),
             (cap001, ))
            )

# add default NCX and Nav file
book.add_item(epub.EpubNcx())
book.add_item(epub.EpubNav())

# define CSS style
style = 'BODY {color: white;}'
nav_css = epub.EpubItem(uid="style_nav", file_name="style/nav.css", media_type="text/css", content=style)

# add CSS file
book.add_item(nav_css)

# basic spine
book.spine = ['nav', cap001]

# write to the file
epub.write_epub('ro_lan_test.epub', book, {})
This is the result of the epub file:

Sunday, July 24, 2022

Python 3.11.0a7 : image conversions in Python.

Image processing is very important in development, therefore also in python.
The image processing packages used in python have undergone changes over time.
Pillow and PIL cannot co-exist in the same environment. Before installing Pillow, please uninstall PIL.
Pillow higher than version 10 no longer supports import Image. Please use from PIL import Image instead.
Pillow higher than version 2.1.0 no longer supports import _imaging. Please use from PIL.Image import core as _imaging instead.
Although the image formats are old compared to the newer ones in vector format, they are preferred depending on the field of work.
You can see all of these file image formats on the official python package.
First, the basic installation start with upgrade the pip tool:
C:\PythonProjects\ConvertImages>python -m pip install --upgrade pip
Requirement already satisfied: pip in c:\python311alpha\lib\site-packages (22.1.
2)
Collecting pip
  Downloading pip-22.2-py3-none-any.whl (2.0 MB)
     ---------------------------------------- 2.0/2.0 MB 3.3 MB/s eta 0:00:00
Installing collected packages: pip
  Attempting uninstall: pip
    Found existing installation: pip 22.1.2
    Uninstalling pip-22.1.2:
      Successfully uninstalled pip-22.1.2
Successfully installed pip-22.2
Secondary, the install of the Pillow python package:
C:\PythonProjects\ConvertImages>python  -m pip install --upgrade Pillow
Collecting Pillow
  Downloading Pillow-9.2.0-cp311-cp311-win_amd64.whl (3.3 MB)
     ---------------------------------------- 3.3/3.3 MB 4.0 MB/s eta 0:00:00
Installing collected packages: Pillow
Successfully installed Pillow-9.2.0
I have a webp image here that I have scaled to smaller sizes and that I will test its conversion from webp format to png format.
The image is named waterski2 and I'm using the 3.11.0a7 python version.
Let's see the source code:
from PIL import Image

# open the image file WEBP
image = Image.open('waterski2.webp')

# show the image 
image.show()

# convert the image to RGB color
image = image.convert('RGB')

# save PNG RGB image
image.save('waterski2_RGB_PNG.png', 'png')

# save JPG RGB image
image.save('waterski2_RGB_JPG.jpg', 'jpeg')

# open the image file JPG
image_jpg = Image.open('waterski2_RGB_JPG.jpg')

# convert the image to RGB color
image_rgb_jpg = image_jpg.convert('RGB')

# save PNG RGB image from JPG
image_rgb_jpg.save('new-image_RGB_PNG_from_JPG.png', 'png')

#same process of conversion to WEBP file type
# from png image
image = Image.open('waterski2_RGB_PNG.png')
image = image.convert('RGB')
image.save('new-image_RGB_WEBP_from_png.webp', 'webp')
# from jpg image
image = Image.open('waterski2_RGB_JPG.jpg')
image = image.convert('RGB')
image.save('new-image_RGB_WEBP_from_jpg.webp', 'webp')
Here is a screenshot with these converted images and the processed image.

Saturday, July 23, 2022

Blender 3D and python scripting - part 023.

This script will add a submenu to the main Help menu with an icon with a folder that will open the explorer from the Windows operating system.
I have not solved the tooltip of this button, it is set to show a message about opening a URL.
This is the source code:
import bpy

def menu_func(self, context):
    '''Open explorer in windows systems'''
    self.layout.operator(
            "wm.url_open", text="Open explorer", icon='FILE_FOLDER').url = "C:/"
def register():
    bpy.types.TOPBAR_MT_help.append(menu_func)

def unregister():
    bpy.types.TOPBAR_MT_help.remove(menu_func)

if __name__ == "__main__":
    register()
If you want to change the tooltip then need to create a class OpenOperator and wrapper for this operator function and set the bl_label and all you need to have it.
The menu_func will get the layout operator with all defined in the class OpenOperator and will set the tooltip with the text: Open explorer in windows systems.
See this new source code:
import bpy

def menu_func(self, context):
    self.layout.operator(
            OpenOperator.bl_idname, text="Open explorer", icon='FILE_FOLDER')

class OpenOperator(bpy.types.Operator):
    """Open explorer in windows systems"""
    bl_idname = "wm.open_explorer"
    bl_label = "Open explorer"

    def execute(self, context):
        bpy.ops.wm.url_open(url="C:/")
        return {'FINISHED'}


def register():
    bpy.utils.register_class(OpenOperator)
    bpy.types.TOPBAR_MT_help.append(menu_func)


def unregister():
    bpy.utils.unregister_class(OpenOperator)
    bpy.types.TOPBAR_MT_help.remove(menu_func)


if __name__ == "__main__":
    register()

Wednesday, July 13, 2022

Python 3.11.0a7 : local script for update python packages.

If you want to upgrade all local packages from a local script for pip with version greater than 10.0.1 version use a local python script with this source code:
import pkg_resources
from subprocess import call

packages = [dist.project_name for dist in pkg_resources.working_set]
call("pip install --upgrade " + ' '.join(packages), shell=True)
Run it with the python executable and you will see something like this:
C:\Python311alpha>python.exe update_python.py
...
Requirement already satisfied: pip-api in c:\python311alpha\lib\site-packages (0.0.29)
Requirement already satisfied: pypng in c:\python311alpha\lib\site-packages (0.0.21)
Requirement already satisfied: PyGetWindow in c:\python311alpha\lib\site-packages (0.0.9)
Requirement already satisfied: bs4 in c:\python311alpha\lib\site-packages (0.0.1)

Thursday, July 7, 2022

Blender 3D and python scripting - part 022.

In the last tutorial, we exemplified with the default template from Blender 3D how to create a panel in the Object area.
Today I will show you how to modify this panel with some useful elements for developing an addon.
The purpose of the old tutorial on this is the differences and changes that must be made to the template source code to introduce the following functions:
    StringProperty(
    BoolProperty( 
    IntProperty(
    IntVectorProperty(
    FloatProperty(
    FloatVectorProperty(
    BoolVectorProperty(
Some arguments need to be modified to have different input data, see the selection of colors in the attached image:
I commented on the source code areas in the template and added my changes:
The class also called SceneSettingItem and CollectionProperty is currently being tested and is not finalized to be implemented, it can be seen in panel: 0 items.
It can be seen that any defined class must be registered and unregistered
Here is the source code used to get the new screenshot changes:
import bpy

# Assign a collection
class SceneSettingItem(bpy.types.PropertyGroup):
    name = bpy.props.StringProperty(name="Cube")
    mesh = bpy.props.PointerProperty(type=bpy.types.Mesh)
    


PROPS = [
            ('myString', bpy.props.StringProperty(name='myString', default='this is my string!')),
            ('myBoolean', bpy.props.BoolProperty(name='myBoolean', default=False)),
            ('myInt', bpy.props.IntProperty(name='myInt', default=1)),
            ('myIntVectorXYZ', bpy.props.IntVectorProperty(subtype='XYZ')),
            ('myFloat', bpy.props.FloatProperty(name='myFloat', default=1)),
            ('myFloatVectorXYZ', bpy.props.FloatVectorProperty(subtype='XYZ')),
            ('myBooleanVector', bpy.props.BoolVectorProperty(size=3)),
            ('myBooleanVectorXYZ', bpy.props.BoolVectorProperty(size=3,subtype='XYZ')),
            ('myBooleanVectorColor', bpy.props.FloatVectorProperty(name="Edit Mode Color", subtype='COLOR',  default=(0.76, 0.0, 0.0), size=3, min=0, max=1)),
            ('myCollectionProperty', bpy.props.CollectionProperty(type=SceneSettingItem)),
        ]    

class HelloWorldPanelVariables(bpy.types.Panel):
    """Creates a Panel in the Object properties window"""
    bl_label = "Hello World Panel Variables"
    bl_idname = "OBJECT_PT_hello"
    bl_space_type = 'PROPERTIES'
    bl_region_type = 'WINDOW'
    bl_context = "object"

#    def draw(self, context):
#        layout = self.layout
#        obj = context.object
#        row = layout.row()
#        row.label(text="Hello world!", icon='WORLD_DATA')
#        row = layout.row()
#        row.label(text="Active object is: " + obj.name)
#        row = layout.row()
#        row.prop(obj, "name")
#        row = layout.row()
#        row.operator("mesh.primitive_cube_add")

    def draw(self, context):
        col = self.layout.column()
        for (prop_name, _) in PROPS:
            row = col.row()
            row.prop(context.scene, prop_name)

        
def register():
    bpy.utils.register_class(SceneSettingItem)
    bpy.utils.register_class(HelloWorldPanelVariables)
    for (prop_name, prop_value) in PROPS:
        setattr(bpy.types.Scene, prop_name, prop_value)

def unregister():
    bpy.utils.unregister_class(SceneSettingItem)
    bpy.utils.unregister_class(HelloWorldPanelVariables)    
    for (prop_name, _) in PROPS:
        delattr(bpy.types.Scene, prop_name)

if __name__ == "__main__":
    register()

Wednesday, July 6, 2022

Blender 3D and python scripting - part 021.

I will continue the series of tutorials with python and the Blender 3D software interface.
From the main menu we can get to the scripting part and here we choose Templates - Python - Ui Panel Simple.
The source code will be added to the python editor.
Save this source code with a name and load it as an addon.
After loading this source code it can be found at Properties at Object, see screenshot.
You can see the source code from the Ui Panel Simple template that I used.
import bpy

class HelloWorldPanel(bpy.types.Panel):
    """Creates a Panel in the Object properties window"""
    bl_label = "Hello World Panel"
    bl_idname = "OBJECT_PT_hello"
    bl_space_type = 'PROPERTIES'
    bl_region_type = 'WINDOW'
    bl_context = "object"

    def draw(self, context):
        layout = self.layout

        obj = context.object

        row = layout.row()
        row.label(text="Hello world!", icon='WORLD_DATA')

        row = layout.row()
        row.label(text="Active object is: " + obj.name)
        row = layout.row()
        row.prop(obj, "name")

        row = layout.row()
        row.operator("mesh.primitive_cube_add")

def register():
    bpy.utils.register_class(HelloWorldPanel)


def unregister():
    bpy.utils.unregister_class(HelloWorldPanel)

if __name__ == "__main__":
    register()

Saturday, July 2, 2022

Python 3.7.10 : Simple example with PyQRCode.

The pyqrcode module is a QR code generator that can automate most of the building process for creating QR codes.
The pypng python library is required to save and upload PNG images.
I had to install them both with the pip utility.
pip install pyqrcode
Collecting pyqrcode
  Using cached PyQRCode-1.2.1-py3-none-any.whl
Installing collected packages: pyqrcode
Successfully installed pyqrcode-1.2.1
WARNING: There was an error checking the latest version of pip.
...
pip install pypng
Collecting pypng
  Using cached pypng-0.0.21-py3-none-any.whl (48 kB)
Installing collected packages: pypng
Successfully installed pypng-0.0.21
WARNING: There was an error checking the latest version of pip.
Let's try some simple examples:
import pyqrcode
url = pyqrcode.create('https://ro.wikipedia.org/wiki/Utilizator:Catalin_Festila', error='H', mode='binary')
url.svg('uca-url.svg', scale=8)
url.eps('uca-url.eps', scale=2)
url.png('code.png', scale=5, module_color=[0, 0, 0, 128], background=[0, 0, 128])
url.show()
print(url.terminal(quiet_zone=1))
This is the result of this source code: