Créer des scripts Python

Nous allons voir aujourd’hui comment transformer une fonction en script Python. Pour cela, nous allons utiliser la bibliothèque docopt qui permet de créer des interfaces en ligne de commande.

Remarque : Peut-être l’année prochaine je vais utiliser la bibliothèque fire que je ne connais pas encore, mais qui semble plus simple à utiliser que docopt. Et peut-être que je vais aussi enseigner la programmation objet, car c’est fort pratique pour créer des scripts.

docopt

Le principe de docopt est que l’on écrit une documentation pour notre script, et docopt se charge de transformer cette documentation en interface en ligne de commande. Voici un exemple de documentation pour un script qui prend un nombre en argument et qui affiche si ce nombre est pair ou impair :

"""
This script checks if a number is even or odd.

Usage:
  odd_even.py [--] <number>

Options:
  -h --help     Display this help message
  <number>      The number to check
"""

from docopt import docopt

arguments = docopt(__doc__)

try:
    number = int(arguments['<number>'])
except ValueError:
    print("The number must be an integer")
    print(__doc__)
    exit(1)

if number % 2 == 0:
    print(f"{number} is even")
else:
    print(f"{number} is odd")

Quelques remarques sur ce script :

On peut réaliser ce script simple sans bibliothèque externe. Et pour un cas aussi simple, c’est probablement plus approprié. Cependant, pour des scripts plus complexes, docopt permet de gérer automatiquement les erreurs de syntaxe des options et arguments, et de générer une aide automatique pour le script.

Voici le même script sans docopt:

import sys

if len(sys.argv) != 2:
    print("Usage: odd_even.py <number>")
    exit(1)

try:
    number = int(sys.argv[1])
except ValueError:
    print("The number must be an integer")
    exit(1)

if number % 2 == 0:
    print(f"{number} is even")
else:
    print(f"{number} is odd")

Ce script est disponible dans le fichier odd_even2.py dans ce répertoire.

Exemple plus complexe

Transformons la fonction table(n, format='d') qui était à faire en exercice lors de la séance 5 en script Python. Voici la documentation que nous pourrions écrire pour ce script :

"""
Usage:
  table.py [--format=<f>] <number>

Print the multiplication table up to <number> in the format <f>

Options:
    -h --help     Display this help message
    <number>      The maximal number in the table
    --format=<f>  The format of the numbers, one of d, x, o, b [default: d]
"""

On peut voir le script complet dans le fichier table.py dans ce répertoire.

Quelques astuces

Pour effacer l’écran

Il existe des commandes pour effacer l’écran dans les terminaux. Par exemple, la commande clear efface l’écran dans un terminal Unix. On peut utiliser cette commande dans un script Python pour effacer l’écran. Mais on peut aussi imprimer la chaîne de caractères "\033c" qui efface l’écran dans la plupart des terminaux.

def clear_screen():
    print("\033c", end="")

Pour lire la réponse de l’utilisateur

En général on utilise la fonction input pour lire la réponse de l’utilisateur. Cependant, cette fonction n’est pas très pratique quand on attend une réponse d’une seule lettre.

Pour récupérer une seule lettre, on peut utiliser la bibliothèque readchar. Voici un exemple de script qui lit une seule lettre sans attendre que l’utilisateur appuie sur la touche Entrée.

from readchar import readkey, key

def get_key(allowed_keys):
    """
    Lit une touche du clavier et retourne la touche si elle est dans la chaîne `allowed_keys`.
    Sinon, affiche un message d'erreur et redemande une touche.
    """
    while True:
        k = readkey()
        if k in allowed_keys:
            return k
        print(k)
        print(f"Touche invalide. Les touches autorisées sont : {allowed_keys}.")

Les inconvénients de cette méthode sont :

Pour utiliser des couleurs dans le terminal

On peut utiliser différent bibliothèques pour afficher du texte en couleur dans le terminal. Par exemple, la bibliothèque colorama ou rich permettent de faire cela.

Mais on peut utiliser des codes de couleurs pour afficher du texte en couleur dans le terminal. Voici un exemple de script qui affiche du texte en couleur :


def color_text(text, color):
    """
    Retourne le texte `text` coloré avec la couleur `color`.
    """
    colors = {
        "black": "\033[30m",
        "red": "\033[31m",
        "green": "\033[32m",
        "yellow": "\033[33m",
        "blue": "\033[34m",
        "magenta": "\033[35m",
        "cyan": "\033[36m",
        "white": "\033[37m",
        "reset": "\033[0m"
    }
    c = colors.get(color, "")
    return c + text + colors["reset"]

Inconvénients de cette méthode :