Python
Is a programming language that can run on many things like Raspberry Pi or can run Home Assistant.
References¶
Setup¶
- PC: check Python website
- Raspberry Pi OS:
sudo apt install python3-pip
for Python 3
Organization¶
General¶
Text | Action |
---|---|
# |
Comment, single line |
``` | Comment, multiple lines |
var x |
Declare a new var, any type |
var _x |
Private variable |
global x |
Use a global variable |
x = name.fctA(par) |
Populate var x with the function |
Naming Convention¶
Numbers¶
123
is integer123.0
is float
Decimal¶
- Integer to Decimal:
bin(int)
but remove leading 0 - Advanced: use
format()
- documentation- Example:
format(14, '#010b')
to output'0b00001110'
- The # makes the format include the 0b prefix, and the 010 size formats the output to fit in 10 characters width, with 0 padding; 2 characters for the 0b prefix, the other 8 for the binary digits. (Source)
- Example:
- How to manage bitmasks = work with one bit - Source
- Get a bit by shifting everything to the right
python def get_normalized_bit(value, bit_index): return (value >> bit_index) & 1
- Get a bit by shifting everything to the right
Text¶
Text | Action |
---|---|
print(x) |
Print text in x |
print(x, end =",") |
Print text in x and finish by "," |
"x\nhey" or "x\hey" |
new line between x and hey |
Link | Escape characters list |
List¶
Text | Action |
---|---|
list = [a, b, c] |
Declare a list "list" with variables a b c, can be any type |
list = [[a,b][c,d] |
List in list |
print(*list, sep=", ") |
print each item in list with , as separator |
Access¶
Text | Action |
---|---|
list[0] |
access item 0 (is "a") |
list[-1] |
access last item (is "c") |
list[0:1] |
sub-list from 0 to 1 |
Work with List¶
Text | Action |
---|---|
list.extend(list2) |
add list2 after list → list, list2 |
list.append(list2) |
add list2 as sub-list in list → list, [list2] |
list.insert(position, item) |
insert |
list.remove(item) |
remove |
list.clear() |
remove all items |
list.pop() |
remove last item |
list.copy() |
copy item |
list.sort() |
sort the list by a-z, 0-9 |
list.reverse() |
inverse of sort |
Search¶
Text | Action |
---|---|
list.index(name) |
search in list for "name" |
list.count(item) |
count items |
Dictionary¶
Key:Value pairs
Single dimension¶
Text | Action |
---|---|
dict = {key:work, k1:w1} |
declare |
dict['key'] or dict.get('key') |
get |
dict.get('key', "default value") |
get with fallback |
Multiple dimensions¶
Text | Action |
---|---|
dict = { k1:{k11:w, k12:w}, k2:{k21:w, k22:w}} |
declare |
dict[0][1] -> k12 dict[0]['k12'] dict['k1']['k12'] |
access |
### Tuples | |
Like List but immutable: | |
* x = (4, 5) |
|
* x = ([1,2],[3,4]) |
|
### Thread-based parallelism | |
The following function will return "Spun off" before "Done", as there's a wait function. Source |
import threading, time
def my_threaded_func(arg):
print("Running thread! Args:", (arg))
time.sleep(2)
print("Done!")
thread = threading.Thread(target=my_threaded_func, args=("I'm a thread",))
# Note the ,) at the end: Thread expect arg to be iterable, so you have to pass a tuple
thread.start()
print("Spun off thread")
Modules management¶
pip install x
pip uninstall x
Import¶
Several ways are possible to import variables - Source:
* import <file_name>
and then use <file_name>.<variable_name>
to access variable
* from <file_name> import <variable_names>
and use variables
* from <file_name> import *
and then use variables directly.
Loops¶
Operators: <,<=, ==, !=, =>, >
If¶
var = Trues
if var:
if char in text:
do things
elif var1 or not(var2) or var3 > var 4:
do things
else:
do thing
While¶
i = 1
while i<10:
i+=1
For¶
Good for index!
# Defining a list
d = { "one": 1, "two": 2, "three": 3, "four": 4, "five": 5 }
iterable = d.keys()
for item in iterable: # Go through all items
print(item) # item is one of the items
break # Break the current loop
for item in [a, b]: # same with 2 items
for item in string: # same with string - treat is char
Switch¶
Does not exist in Python, so needs to use If.
Try¶
try:
do things
except ValueError:
do things # If ValueError is raised
except ValueError as err:
print(err) # print err being the rrror
except:
do things # If any error is raised
else:
do things # If no exception are raised
finally:
do cleanup # Always executed
Functions¶
def pretty_sumab(func):
# Define an inner function
def inner(a,b):
print(str(a) + " + " + str(b) + " is ", end="")
return func(a,b)
return inner
@pretty_sumab # Decorate the sumab function with the pretty_sumab function
def sumab(a,b):
summed = a + b
print(summed)
if __name__ == "__main__":
sumab(5,3)
# Know the type of the variable (float, int, str, list, dict, tuple)
x = isinstance(var, str) # x = True if var:str
Imports¶
import os # Import built-in os module
import fruit # Import custom file fruit.py
fruit.lemon() # Use an imported function
from time import sleep # Import only what you are going to use
sleep(2) # You can skip the prefix
Text function¶
Is an index
Retrieve¶
a = input("str") # Ask for input with message "str", put in a
Transformations¶
x.index("a") # return start index of string/char
x.replace("old", "new") # replace in x "old" by "new"
Base conversion (decimal, hexadecimal, binary)¶
import binascii
y = binascii.hexlify(x) # convert x in hexadecimal
Numbers function¶
Text | Action |
---|---|
str(x) |
int to str |
int(x) or float(x) |
str to int or float |
Random¶
import random
x = random.randint(0,10)
print(x)
Bytearrays¶
[hex(i) for i in data] # print content of data in pretty hexadecimal
Files¶
Text | Action |
---|---|
a = open("f.txt", "r+") |
open the file in: r+ - read & write> r - read w - write a - append |
a.close() |
close |
a.readable() |
bool to check if Read possible |
a.readlines() |
read each lines in array [line1, lineN] |
a.write("text") |
Mode "w": overwrite the file with text Mode "a": append text at end of file |
Logs - Logging class¶
Example inspired from this StackOverflow thread
_log_level=logging.DEBUG
_log_format = logging.Formatter('[%(asctime)s] [%(levelname)s] - %(message)s')
_LOGGER = logging.getLogger(__name__)
_LOGGER.setLevel(_log_level)
# writing to stdout
handler = logging.StreamHandler(sys.stdout)
handler.setLevel(_log_level)
handler.setFormatter(_log_format)
_LOGGER.addHandler(handler)
_LOGGER.debug("Logging has been setup")
Network¶
Requests: PUT, GET, POST¶
Example of a POST:
import requests
user = "user"
pwd = "password"
headers = {"Content-Type":"application/json"}
data_JSON = {
"id": "value",
}
response = requests.post(url, auth=(user, pwd), headers=headers, json=data_JSON)
You can use data=
instead of json=
.
If parameters are passed in the URL, use params=
instead of json=
.
UDP Communication¶
Text | Action |
---|---|
import socket |
|
UDPServerSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) |
Initiate a new UDP socket |
To receive something | |
UDPServerSocket.bind(("", port)) |
Bind the socket to port |
data, address = UDPServerSocket.recvfrom(1024) |
Receive incoming data and IP with a buffer size of 1024 |
To send something | |
UDPServerSocket.sendto(data, (host, port)) |
Send data to host:port |
Advanced functions¶
Set window title¶
from os import system
system("title " + myCoolTitle)
Classes & Objects¶
Definition¶
class Human:
def __init__(self, a, b): # a b are used for initialization - init is the constructor
self.a = a
self.job = None
def function(self):
return a
def functionb(self, x: int) # x must be of type int
return x
# Getter and Setter, to access and manage variables inside a class
def setJob(self, job):
self.job = job
def getJob(self, job):
return self.job
class AliveHuman(Human): # define a subclass of Human
# this class inherit everything that was define in the Human class
@staticmethod
def walk():
# Define a method which can be used without instanciating the object first
# So this can be called directly like AliveHuman.walk()
class_name = "abc"
@classmethod
def printName(cls):
# Return a value stored in the Class, not in each instanciation - except if the instanciation is called
print(cls.class_name)
# somebody = AliveHuman()
# somebody.class_name -> Will set the variable as usual
# print(somebody.class_name) -> Will return the variable as usual
# AliveHuman.class_name -> Will set the Class variable
# print(AliveHuman.class_name) -> Will return the Class variable
class PythonHuman(Human, PythonLover): # define a class that inherit Human and PythonLover
...
Usage¶
from filename import ClassName
object = ClassName("a", "b")
print(object.a)
# Delete an object
del object
Inheritance¶
from filename import ClassName
class Child(Parent):
def fct(self):
do things
def overridenFct(self):
do things
XML¶
Import XML as dict- Use xmltodict:
import xmltodict
dico = xmltodict.parse('<?xml version="1.0" ?><PAGE><LOCK> ...')
dico['PAGE']['LOCK']
Structure¶
<tag>Text content</tag>
<tag attribute1="something1 something2"/>
In Python¶
Text | Action |
---|---|
data.find('key').text |
get the Text content |
data.find('key').get('attribute1') |
get the Attribute content |
JSON¶
import json
data = "{ 'k1': 'w1' }" # JSON string
dictData = json.loads(data) # load a JSON string in dictData
print(dictData['k1']) # print content of k1
data['k1'].get['k12',''] # Get [k1][k12], otherwise return ''
len(data) # Get number of items in data
Development¶
Package an application for pip¶
Tutorial: 1. Create the structure
packaging_tutorial/
└── src/
└── example_pkg/
└── __init__.py
└── example_pkg.py
- Configure metadata
[metadata]
# replace with your username:
name = example-pkg-YOUR-USERNAME-HERE
version = 0.0.1
author = Example Author
author_email = [email protected]
description = A small example package
long_description = file: README.md
long_description_content_type = text/markdown
url = https://github.com/pypa/sampleproject
project_urls =
Bug Tracker = https://github.com/pypa/sampleproject/issues
classifiers =
Programming Language :: Python :: 3
License :: OSI Approved :: MIT License
Operating System :: OS Independent
[options]
package_dir =
= src
packages = find:
python_requires = >=3.6
[options.packages.find]
where = src
- Create README
- Create LICENSE
- Update if necessary
- Windows
py -m pip install --upgrade build
- Unix
python3 -m pip install --upgrade build
- Windows
- Generate
- Windows
py -m build
- Unix
python3 -m build
- Windows
- Install
pip install C:/some-dir/some-file.whl
To use this example: from example_pkg import example_pkg
Publish an application on PyPI¶
There's a good tutorial here
1. Configure setup.py
1. Document with Readme and License
1. Increment version in setup.py
and __init__.py
* Or with bump2version --current-version 1.0.0 minor setup.py PROJECT/__init__.py
1. Install pip install twine wheel
if necessary
1. Create archive and wheel python setup.py sdist bdist_wheel
1. Check twine check dist/*
1. Upload to TestPyPI twine upload --repository-url https://test.pypi.org/legacy/ dist/*
1. Upload to PyPi twine upload dist/*
1. Make a release in GitHub
Virtual environment - venv¶
Useful to use one library for one project! * System packages are coming with Python * Site packages are installed by user, using pip for instance
How to use - Source
1. pip install virtualenv
to install virtualenv
1. Create a directory for your project
1. python3 -m venv toto
set up the venv in folder toto
- it won't contain existing site package by default
1. .\toto\Scripts\activate
to activate the venv
* If you have an error about PowerShell scripts, try Set-ExecutionPolicy -ExecutionPolicy Unrestricted -Scope CurrentUser
- Source
1. deactivate
to return to the normal environment