Python
Environnements virtuels
Créer un environnement
python3 -m venv new-env
new-env est le nom du dossier qui va contenir le nouvel environnement virtuel.
Activer l'environnement
Dans le dossier de l'environnement:
source bin/activate
Yaml
Installation
sudo pip3 install pyyaml
Lecture d'un fichier YAML
import yaml config_file = open("file.yaml", 'r') config = yaml.safe_load(config_file)
config est alors un dictionnaire contenant toutes les clés du fichier Yaml.
Voir la note sur le dépôt pour les différents loaders.
Écriture d'un fichier YAML
import yaml vars_dict = dict() # ... with open('file.yaml'), 'w') as yaml_file: yaml.dump(vars_dict, yaml_file, default_flow_style=False)
Arguments du programme
import sys if len(sys.argv) < 2: sys.exit(1) action = sys.argv[1]
argparse
Permet de gérer facilement les arguments passés à un script, et générer la documentation qui va avec.
import argparse cli_parser = argparse.ArgumentParser() cli_parser.add_argument("config_file", help="Configuration file in YAML format") cli_parser.add_argument("nb_cores_per_numa", help="Number of cores per NUMA node", type=int) args = cli_parser.parse_args()
args est un objet contenant les paramètres passés en arguments du script (par exemple: args.config_file).
Pour avoir un paramètre optionnel avec une valeur par défaut :
cli_parser.add_argument("b", help="Block size", type=int, nargs="?", default=320)
Fonction par défaut
if __name__ == '__main__': # some stuff
Lire un fichier
with open(filename, 'r') as file: content = file.read() # ou lines = file.readlines() # liste où chaque élément est une ligne du fichier # ou for line in file: print(line) # ou print(file.readline(3)) # lit la 3ème ligne du fichier
Pour préciser l'encodage du fichier (Source):
with open(filename, 'rb') as file: content = file.read().decode('windows-1252')
CSV
https://docs.python.org/fr/3/library/csv.html
import csv with open('eggs.csv', newline='') as csvfile: spamreader = csv.reader(csvfile, delimiter=' ', quotechar='|') nb_lines = sum(1 for row in spamreader) for row in spamreader: print(', '.join(row))
Écrire un CSV:
import csv someiterable = [ ['abc', 20.7, 17.2], ['def', 20.6, 17.1] ] with open('some.csv', 'w', newline='') as f: # possibilité d'utiliser le mode 'a' pour ajouter à la fin d'un fichier existant. Dans tous les cas, le fichier sera créé s'il n'existe pas. writer = csv.writer(f) writer.writerows(someiterable)
Il est possible d'écrire sur la sortie standard en utilisant le fichier sys.stdout.
Ignorer la première ligne
reader = csv.reader(file) next(reader)
Lire l'entrée standard ou un fichier
import sys f = open(sys.argv[1]) if len(sys.argv) == 2 else sys.stdin # ... work with f ... if len(sys.argv) == 2: f.close()
Ecrire sur stderr
import sys print("Erreur", file=sys.stderr)
Listes
Retirer un élément
Récupère et retire l'élément d'index passé en paramètre:
e = liste.pop(0)
Index d'un élément d'une liste
https://www.programiz.com/python-programming/methods/list/index
vowels = ['a', 'e', 'i', 'o', 'i', 'u'] index = vowels.index('e') print('The index of e:', index) # 1
Insérer un élément n'importe où
l.insert(0, "new") # insert "new" at the beginning of the list
Tri
sorted_list = sorted(list_to_sort) sorted_list = sorted(list_to_sort, key=lambda e: e['dict_key']) list_to_sort.sort()
Ces fonctions acceptent un paramètre reverse=True pour trier dans l'ordre décroissant.
Map
list_mapped = map(lambda x: x*2, initial_list)
S'assurer qu'il n'y a pas de doublons
Si les éléments sont hashables:
len(your_list) != len(set(your_list))
Sinon, une méthode avec une complexité plus importante:
any(thelist.count(x) > 1 for x in thelist)
Somme terme à terme de deux listes
# Est plus rapide from operator import add list(map(add, list1, list2))
[sum(x) for x in zip(list1, list2)]
Si la vitesse importe vraiment, il est aussi possible de le faire avec Numpy encore plus rapidement.
Chaînes de caractères
Formatage de chaînes de caractères
https://pyformat.info/, https://fstring.help/cheat/
Il faut doubler les accolades pour qu'elles soient ignorées par Python:
"\\texttt{{{}}}".format('COPY') # = "\texttt{COPY}"
Générer une chaîne de caractères aléatoires
import string import random def generate_random_string(size = 40, chars = string.ascii_lowercase + string.digits): return ''.join(random.choice(chars) for _ in range(size))
Enlever les espaces de début et fin de chaîne
s = " abc " print(s.strip())
Formater un flottant en texte
format(2.03, '.5f') # '2.03000'
Trouver une sous-chaîne
s = "the dude is a cool dude" s.find('dude') # 4
Tester si une chaîne contient une lettre
any(c.isalpha() for c in s)
Sur plusieurs lignes
https://www.techbeamers.com/python-multiline-string/
# Préserve les retours à la ligne dans la chaîne de caractère: s = """ multi ligne """ # Pour juste éviter d'avoir un code trop large: s = ("texte" "sur la" "même ligne")
Tester si c'est un nombre
'12'.isdigit()
Trouver le préfixe commun
import os os.path.commonprefix([str1, str2])
Connaître la langue d'un texte
L'installation de Polyglot est un peu particulière (source) :
pip install numpy six icu pip install pyicu pip install pycld2 pip install morfessor
from polyglot.text import Text if Text(txt).language.code not in ["en", "fr"]: printf("...")
Temps
Enlever les secondes d'une date
dtwithoutseconds = dt.replace(second=0, microsecond=0)
Récupérer le temps actuel
import datetime t = datetime.datetime.now() # datetime.datetime(2009, 1, 6, 15, 8, 24, 78915) t = datetime.datetime.now().time() # datetime.time(15, 8, 24, 78915) t = datetime.datetime.now().timestamp() # 1575914832.536088
Différence de temps
t1 = datetime.datetime.now() t2 = datetime.datetime.now() delta = t2-t1 # datetime.timedelta(seconds=231, microseconds=573812), peut contenir des jours (t2-t1).seconds # 231 (t2-t1).total_seconds() # 231.573812, converti tout en secondes delta.days
Arithmétique sur les temps
import datetime some_date -= datetime.timedelta(days=90)
Str vers date
>>> from datetime import date >>> date.fromisoformat('2019-12-04') datetime.date(2019, 12, 4)
À partir de la version 3.7.
>>> import datetime >>> d = datetime.datetime.strptime(date_str, '%m-%d-%Y').date()
Date vers Str
print(date_var.strftime("format"))
Mesurer des durées
from timeit import default_timer as timer start = timer() # ... end = timer() print(end - start) # Time in seconds, e.g. 5.38091952400282
Regex
Vérifier le respect d'un pattern
import re pattern = re.compile("regex\d+") m = pattern.match("string to test") if m is not None: # "string to test" matches the regex
Capturer des motifs
p = re.compile(r"^.+\s+(\d{2})/(\d{2})$") m = p.match("abc 25/11") if m is not None: day = int(m.group(1)) month = int(m.group(2))
Trouver toutes les occurrences qui correspondent à un motif (source) :
re.findall( r'all (.*?) are', 'all cats are smarter than dogs, all dogs are dumber than cats') # Output: ['cats', 'dogs']
Remplacer un motif
re.sub(r'[\x00-\x08\x0B-\x0C\x0E-\x1F]', '', content)
Flottants
Tronquer un flottant
Utiliser la fonction round:
round(1.23456, 3) # 1.235
Tester si une chaîne est un flottant
s.replace('.','',1).isdigit()
Tester si un flottant est NaN
import math math.isnan(f)
Divers
Condition ternaire
condition_if_true if condition else condition_if_false
Tester le type d'une variable
if isinstance(x, dict): print("x is dict")
Exécuter une commande système
import os code_retour = os.system('ls')
Attention, chaque commande se place dans le dossier d’exécution du script, il n'y pas de persistance des déplacements dans l'arborescence au sein des différents appels à system().
Pour capturer ce qui est écrit sur la sortie standard (source):
import subprocess out = subprocess.check_output("ls", text=True) print(out) out_with_stderr = subprocess.check_output("ls", text=True, stderr=subprocess.STDOUT)
Quitter le programme avec un code d'erreur spécifique
import sys sys.exit(1)
Générer un nombre aléatoire
Entre 0 et 1:
import random x = random.random()
Entre deux entiers:
import random x = random.randint(10, 25) # 10 <= x <= 25
Manipuler l’hexadécimal
Conversion de hexadécimal en décimal:
x = int("deadbeef", 16) y = int("0xdeadbeef", 0)
0 indique à Python de trouver par lui-même la base.
Conversion de décimal en hexadécimal:
x = hex(10)
On peut manipuler l'hexadécimal directement dans la console en préfixant les nombres par 0x.
Convertir un nombre en binaire
bin(14) # '0b1110'
Sleep
import time time.sleep(5) # secondes
Savoir si la sortie est redirigée
On cherche à savoir si stdout est différent de stdin:
import os redirected_to_file = not (os.fstat(0) == os.fstat(1))
Une solution plus simple (et semble plus fonctionnelle), mais pas forcément valide avec Windows :
import sys if sys.stdout.isatty(): print "Not redirected" else: sys.stderr.write("Redirected!\n")
Obtenir le nom des arguments d'une fonction
import inspect param_names = inspect.getfullargspec(f)[0]
Lire l'entrée standard
import sys lines = [] for line in sys.stdin: lines.append(line)
On sort de la boucle lorsque l'entrée standard est fermée.
Connaître le nom du script exécuté
import os os.path.basename(__file__)
Dictionnaires
https://realpython.com/iterate-through-dictionary-python/
a_dict = {'color': 'blue', 'fruit': 'apple', 'pet': 'dog'} for key in a_dict: print(key, '->', a_dict[key]) for key, value in a_dict.items(): print(key, '->', value) for value in a_dict.values(): print(value)
Tri
Par valeur:
{k: v for k, v in sorted(x.items(), key=lambda item: item[1])}
Parser du XML
doc = minidom.parse("file.xml") systems = doc.getElementsByTagName("System") for s in systems: n = s.getElementsByTagName("Node") name = n[0].getElementsByTagName("NodeDesc")[0].firstChild.data uid = n[0].attributes["id"].value
Énumérations
https://docs.python.org/fr/3/library/enum.html
from enum import Enum class Direction(Enum): TOP = 0 BOTTOM = 1 LEFT = 2 RIGHT = 3 d = Direction.TOP
On peut accéder à la valeur de l'élément de l'énumération:
Direction.TOP.value # 0
Pour faciliter la représentation des éléments:
class CompMetric(Enum): BANDWIDTH = "bandwidth" TIME = "time" def __repr__(self): return self.name
JSON
Afficher correctement en objet dans le format JSON:
import json print(json.dumps(data, ensure_ascii=False, indent=4)) # ensure_ascii=False permet d'afficher correctement l'utf-8