Python
Table of contents
- References
- Setup
- Organization
- Loops
- Functions
- Classes & Objects
- XML
- JSON
- Development
- Kivy - Cross-platform GUI Python Framework
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
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 variablefrom <file_name> import <variable_names>
and use variablesfrom <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 |
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
- Launch a python module from the OS:
python3 -m MODULE
Package an application for pip
- 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
- Configure
setup.py
- Document with Readme and License
- Increment version in
setup.py
and__init__.py
- Or with
bump2version --current-version 1.0.0 minor setup.py PROJECT/__init__.py
- Or with
- Install
pip install twine wheel
if necessary - Create archive and wheel
python setup.py sdist bdist_wheel
- Check
twine check dist/*
- Upload to TestPyPI
twine upload --repository-url https://test.pypi.org/legacy/ dist/*
- Upload to PyPi
twine upload dist/*
- 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
pip install virtualenv
to install virtualenv- Create a directory for your project
python3 -m virtualenv toto
set up the venv in foldertoto
- it won’t contain existing site package by default.\toto\Scripts\activate
to activate the venv- If you have an error about PowerShell scripts, try
Set-ExecutionPolicy -ExecutionPolicy Unrestricted -Scope CurrentUser
- Source
- If you have an error about PowerShell scripts, try
deactivate
to return to the normal environment
Kivy - Cross-platform GUI Python Framework
With a virtual environment active, install with python -m pip install kivy[base] kivy_examples
UI
UI is defined in widgets with Layout, like:
- BoxLayout
- FloatLayout
- GridLayout
KV Language
KV Language can be used to separate interface design from logic.
The logic:
from kivy.app import App
from kivy.uix.button import Button
class ButtonApp(App):
def build(self):
return Button()
def on_press_button(self):
print('You pressed the button!')
if __name__ == '__main__':
app = ButtonApp()
app.run()
The interface in a file named button.kv
:
<Button>:
text: 'Press me'
size_hint: (.5, .5)
pos_hint: {'center_x': .5, 'center_y': .5}
on_press: app.on_press_button()
Events
Buttons
from kivy.app import App
from kivy.uix.button import Button
class MainApp(App):
def build(self):
button = Button(text='Hello from Kivy',
size_hint=(.5, .5),
pos_hint={'center_x': .5, 'center_y': .5})
button.bind(on_press=self.on_press_button)
return button
def on_press_button(self, instance):
print('You pressed the button!')
if __name__ == '__main__':
app = MainApp()
app.run()
Images
from kivy.uix.image import Image
#...
img = Image(source='/path/to/real_python.png',
size_hint=(1, .5),
pos_hint={'center_x':.5, 'center_y':.5})
return img
Kivy examples
from kivy.app import App
from kivy.uix.label import Label
class MainApp(App):
def build(self):
label = Label(text='Hello from Kivy', # Create a label
size_hint=(.5, .5),
pos_hint={'center_x': .5, 'center_y': .5}) # Positions are between 0 and 1
return label
if __name__ == '__main__':
app = MainApp() # Instantiate the MainApp class
app.run()
Publish application
Android
pip install buildozer
orpython -m pip buildozer
buildozer init
to create defaultbuildozer.spec
file