Accueil

Traduction

Tutoriel Python - sommaire

Tutoriel Python - recherche

L'auteur : Patrick Darcheville

Vous pouvez me contacter via Facebook pour questions & suggestions : Page Facebook relative à mon site

Python : bien programmer & distribuer vos programmes

Un programme bien écrit est facile à lire et donc la maintenance du code est facilitée. Un programme ne doit pas "planter" à cause de quelques maladresses de l'utilsateur. Il faut gérer les exceptions.

Il faut ensuite faire profiter vos relations, amis de vos créations logicielles. On parle de distribution du programme.

De bonnes pratiques de programmation

Les bonnes pratiques de programmation Python sont proposées dans le cadre du PEP (Python Enchancement Proposal : propositions d'améliorations de Python).

Indentation

Vous savez qu'un bloc d'instruction (appelé par un while OU un if OU un else OU elif) doit être décalé par rapport à l'instruction d'appel.

Longueur maximale d'une ligne d'instruction

Une ligne ne doit pas dépasser 79 caractères.
Pour indiquer qu'une instruction n'est pas terminée il faut rajouter en fin de ligne la barre oblique inversée. On peut aussi ouvrir une parenthèse (qui est fermée dans la ligne suivante).

Directives d'importation

Ce qu'il ne faut pas faire

from os import *
from time import *
from datetime import *

La fonction native open() ne sera plus disponible car écrasée par os.open() ; la fonction time.time() ne sera plus accessible car écrasée par datetime.time().

Ce qu'il faut faire

import os
import time
import datetime as dt

Utilisez des alias pour les modules ayant un nom long ou qui doit respecter une certaine casse.
Les importations doivent se trouver en début de programme.

Attention à la casse

Python fait la différence entre majuscule et minuscule. On dit qu'il tient "compte de la casse".
Exemple :

>>> maChaine ="bonjour"
>>> machaine
NameError: name 'machaine' is not defined

Il y a une erreur puisque "machaine" (sans C majuscule) n'existe pas.

Nommer les variables et fonctions

Consignes

Le premier caractère ne peut pas être un chiffre.

Donnez des noms logiques à vos variables. Si une variable sert de compteur appelez la "compteur" ; si elle doit contenir le score d'une partie appelez la "score". Pas de lettre accentuées !

Pour les noms composés utilisez la notation "camelCase" : soudure et emploi d'une majuscule pour la première lettre de chaque mot mais à partir du deuxième mot. Exemples : cumulNotes, totalPoints, etc.
Le PEP préconise plutôt le "snake_case" ; ce qui donnerait : cumul_notes, total_points, etc.

Toujours selon le PEP les constantes doivent être écrires en majuscules.
Par exemple :

TAUX_REDUIT, TAUX_NORMAL = (5.5, 20) 

Initialisation de deux constantes via un tuple.

Pour les variables dont le nom ne comprend qu'un seul caractère il est déconseillé d'utiliser les lettres : O (o majuscule), l( L minuscule) et I(i majuscule). En effet avec certaines polices le o majuscule peut être confondu avec zéro, le L minuscule avec 1 et I majuscule avec l.

Interdictions

Un mot réservé ne peut être employé pour nommer une variable ou fonction.

>>> del ='supprimer'
  File "", line 1
    del ='supprimer'
SyntaxError: invalid syntax

Il ne faut pas utiliser un nom de fonction générique pour nommer une variable.

>>> print="imprimer"
>>> range="ranger"
>>> print(print)
Traceback (most recent call last):
  File "", line 1, in 
TypeError: 'str' object is not callable

Les commentaires

Un commentaire est précédé du symbole # (tout ce qui n'est pas interprété).

Les commentaires peuvent être écrits sur plusieurs lignes à condition d'être encadrés par une paire de triples guillemets(""" ou ''')/
Les commentaires multilignes doivent être utilisés obligatoirement dans les fichiers correspondant à des modules perso. Ils s'appellent alors les "docstrings".

Une chaine peut aussi être écrite sur plusieurs lignes à condition d'être délimitée par une paire de triples guillemets;

>>> machaine ="""
... début de chaine
... milieu de chaine
... fin de chaine
... """
>>> machaine
'\ndébut de chaine\nmilieu de chaine\nfin de chaine\n'
>>>

Les messages

Si les messages dans les fonctions input() & print() sont délimités par des guillemets doubles vous pouvez utiliser les apostrophes dans ces consignes.

Structurez votre programme

Dès que le programme est conséquent en nombre de lignes pensez à le décomposer en Programme Principal et Sous-Programmes.
Le programme sera beaucoup plus facile lire donc plus facile à comprendre et à maintenir.

Pensez à créer vos propres modules afin de pouvoir appeler vos fonctions perso. dans vos différents programmes.

Gestion des espaces et des lignes vides

Le PEP 8 recommande d’entourer les opérateurs (+, -, /, *, ==, !=, >=, not, in, and, or…) d’un espace avant et d'un espace après.

Les lignes vides sont utiles dans un script pour séparer visuellement les différentes parties du code.
Laissez, par exemple, une ligne vide avant la définition d’une fonction ou d’une classe.

Gestion des exceptions

En programmation, on peut rencontrer principalement deux types d’erreurs :

Les erreurs de syntaxe sont signalées par l'éditeur IDLE dès que l'on veut exécuter le programme. Il s'agit souvent d'oubli des ":" ou des erreurs d'indentation ou une paire de parenthèses, crochets, accolades non fermée.

Pour les autres erreurs, en revanche, il va falloir mettre en place un système de gestion d’erreurs pour éviter un plantage.

Les différents messages d'erreur

Commandes dans la console :

>>> a= 20
>>> b=0
>>> a/b
...
ZeroDivisionError: division by zero
>>> c="10"
>>> d=10
>>> c+d
...
TypeError: can only concatenate str (not "int") to str
>>> d + e
...
NameError: name 'e' is not defined
>>>

Exemple de programme avec gestion des exceptions

Vous devez régulièrement effectuer de nombreuses divisions.
Vous avez donc produit le script ci-dessous.

Le script primitif

""" nom du programme : gestion_exceptions_sans.py
    un programme qui 'plante' si erreur de saisie
"""
reponse ="o"
while reponse in "oO":
        D = int(input("Dividende  : "))
        d = int(input("Diviseur : "))
        print("Le quotient est : ", D/d)
        
        reponse =input("encore des  saisies o / n ? : ")

Ce programme fonctionne très bien mais à condition que son utilisateur soit très très rigoureux. Or nul n'est à l'abri d'étourderie ...
Comme vous savez la fonction input() retourne une chaine de caractères ; la fonction int() la convertit en entier à conditon que la chaine soit une suite de chiffres.

Exécutions de ce script

Première exécution :

Dividende  : 1000
Diviseur : 50
Le quotient est :  20.0
encore des  saisies o / n ? : o
Dividende  : 1200
Diviseur : -é
...
ValueError: invalid literal for int() with base 10: '-é'

Deuxième exécution :

Dividende  : 1000
Diviseur : 0
ZeroDivisionError: division by zero

L'utilisateur a voulu saisir trop vite ; Il a oublié d'appuyer sur la touche MAJ pour saisir des chiffres.

Le script amélioré

Cette fois les erreurs de saisie ne provoqueront pas le plantage ; le script va gérer les exceptions.

""" nom du programme : gestion_exceptions.py
    objet : programme avec structure try et except
"""
reponse ="o"
while reponse  not in "nN":
    try: 
        D = int(input("Dividende  : "))
        d = int(input("Diviseur : "))
        print("Le quotient est : ", D/d)
    except:
        print("erreur de saisie")
    reponse =input("encore des  saisies o / n ? : ")

Tant qu'on saisit autre chose que "n" ou "N" on reste dans la boucle while.

Exécution du script amélioré

Dividende  : 1000
Diviseur : 0
erreur de saisie
encore des  saisies o / n ? : o
Dividende  : 1ooo
erreur de saisie
encore des  saisies o / n ? : p
Dividende  : 1200
Diviseur : '(
erreur de saisie
encore des  saisies o / n ? : 
Dividende  : 1000
Diviseur : 50
Le quotient est :  20.0
encore des  saisies o / n ? : N

Malgré la saisie de zéro comme diviseur le programme ne plante pas.
Malgré la saisie d'un dividende non numérique (suite de lettres "o" après le 1) le script ne plante pas.
Malgré la saisie d'un diviseur non numérique, le programme ne plante pas.

Dans les trois cas il y a branchement sur le bloc "except" ; ce programme ne "plante" jamais !

Diffuser vos programmes Python

Problématique

Vous avez réalisé un superbe programmme de jeu avec Python et vous voulez en faire profiter vos relations.
Problème : pour qu'un programme Python (d'extension .py) fonctionne sur un PC, il faut que la bonne version de Python y soit installée et si de plus vous faites appel dans ce programme à des bibliothèques tierces, il faut aussi les installer. Bref pour un non informaticien c'est très compliqué.

Le programme que nous voulons distribuer

Il s'agit du jeu qui consiste à deviner le plus vite possible l'entier généré.

Le script

# nom programme : entier_a_trouver.py

# sous-programmes 
def unepartie():
    score = 10
    nbre_secret = random.randint(1,99)
    while True:
        nbre_joueur =""             # entier proposé par le joueur
        try:
            nbre_joueur =int(input("Propose un nombre :  "))
            if nbre_secret == nbre_joueur : 
                if score < 0 :
                    score = 0
                print (f"Enfin trouvé ; ton score est  : {score}")
                return score
                break
            elif nbre_secret > nbre_joueur : 
                print(f"{nbre_joueur} est trop petit",end=" * ")
                score -= 1 
            else:
                print(f"{nbre_joueur} est trop grand", end=" * ")
                score -= 1  
        except:
                print("Erreur de saisie")
# fin fonction

# programme principal
import random
consignes =""" L'ordinateur produit de façon aléatoire 
un entier compris entre 1 et 99. 
Tu dois découvrir cet entier avec le moins d'essais possibles.
Tu joues autant de fois que tu veux. 
A toi de jouer !  """
score_total = 0
compteur = 0
print(consignes)
encore ="O"
while encore not in "Nn" :
    score_partie = unepartie()      #   appel de la fonction unepartie et
    # récupération du score sur 10
    encore = input("Encore jouer O/N ?")
    score_total += score_partie
    compteur +=1
# fin boucle while

print(f"points obtenus : {score_total} sur  {compteur * 10}")

Remarquez dans la fonction "unepartie()" la gestion des exceptions.
Donc si par erreur, vous ne saisissez par un entier le script ne plantera pas pour autant.
La fonction retourne le score de la partie.

Notez dans le programme principal : la chaine multilignes et l'appel de la fonction "unepartie()" avec récupération du score de la partie.

Avant de distribuer ce programme il faut le tester ; est-il "débuggé" ?

Exécution dans le shell

 L'ordinateur produit de façon aléatoire un entier compris entre 1 et 99. 
Tu dois découvrir cet entier avec le moins d'essais possibles.
Tu joues autant de fois que tu veux. 
A toi de jouer !  
Propose un nombre  :  50
50  est trop petit  Propose un nombre  :  70
70  est trop petit  Propose un nombre  :  90
Enfin trouvé ; ton score est  : 8
Encore jouer O/N ?p
Propose un nombre  :  50
50  est trop petit  Propose un nombre  :  90
90 est trop grand  Propose un nombre  :  70
70  est trop petit  Propose un nombre  :  80
80 est trop grand  Propose un nombre  :  75
75  est trop petit  Propose un nombre  :  77
77  est trop petit  Propose un nombre  :  78
78  est trop petit  Propose un nombre  :  79
Enfin trouvé ; ton score est  : 3
Encore jouer O/N ?n
points obtenus : 11 sur  20

Si par maladresse vous ne saisissez pas une suite de chiffres le bloc "except" interdit le plantage.

Créer un exécutable

Il existe une bibliothèque externe qui dès qu'elle est installée, permet de produire un programme "standalone" c'est à dire un programme qui fonctionne sans qu'il soit nécessaire d'installer Python sur le terminal qui va l'utiliser.
Une version "standalone" d'un programme comprend en plus du code, l'exécutable Python et les extensions dont il a besoin.
Concrétement sous Windows, vous obtiendrez un exécutable (fichier. exe)
Pour créer cet exécutable il faut utiliser la bibliothèque pyinstaller.

Pyinstaller

Pyinstaller est une librairie externe qu'il faut donc installer sur votre ordinateur.

Installation de pyinstaller

Vous vous doutez qu'il faut utiliser l'outil pip. Et bien vous avez raison.
Dans la fenêtre de commandes de windows il suffit donc de taper :
pip install pyinstaller
L'utilitaire pysinstaller est désormais installé sur votre PC.

Produire un exécutable

Nous voulons créer un exécutable du programme "entier_a_trouver.py" qui est stocké (comme tous nos programmes Python) dans c:\python_prog.

Il n'y a que deux commandes à saisir dans l'invite de commandes :

 
	cd c:\python_prog
	pyinstaller –-onefile  entier_a_trouver.py

Il faut sélectionner le répertoire qui contient le programme source.
Attention l'exécution de la deuxième commande peut demander un certain temps ... près d'une minute. Soyez patient.

Message final :
...
16768 INFO: Building EXE from EXE-00.toc completed successfully.
PS C:\python_prog>

Le système indique enfin que la fabrication du EXE s'est réalisé avec succès.

Vérifions !
Ouvrons le dossier "C:\python_prog".
Nous constatatons l'existence d'un nouveau sous-dossier "dist" et à l'intérieur de ce sous-dossier un fichier d'extension .exe nommé "entier_a_trouver.exe" qui pèse plus de 5000 KO.

Tester cet exécutable

Double-cliquez sur le fichier .exe
Une fenêtre s'ouvre :

Vous pouvez maintenant adresser cet exécutable à vos relations. Il fonctionnera même s'ils n'ont pas installé Python sur leur poste.

Exercice

Dans le chapitre précédent nous avons réaliser un programme avec une interface graphique : calculatrice.py.
Votre mission consistre à produire l'exécutable correspondant. Mais auparavant vous devez l'améliorer le programme : gérer les exceptions.

Le code amélioré

Il suffit d'enrichir la fonction saisies()

def saisies() :
    try : 
        a= eval(zt1.get())
        b = eval(zt2.get())
        return a,b
    except :
        zt3.delete(0,END)
        zt3.insert(0, "Saisir chiffres !")

Ainsi, si par maladresse, l'utilisateur appuie sur un bouton de commande alors que les zones de texte zt1 & zt2 sont encore vides, un message d'erreur s'affiche en zt3.
Même remarque si vous saisissez des lettres et non pas des chiffres dans zt1 & zt2.

Exécutable

Vous devriez obtenir un exécutable qui pèse près de 8 Mégas. C'est logique car ce fichier intégre entre autres le module tKinter.

Utiliser Google Colab

Grâce à ce service en ligne il n'est pas nécessaire d'installer quoi que ce soit sur votre PC pour faire fonctionner un programme Python. Il suffit d'avoir un compte Google.

Procédure pour transformer un programme python en notebook partageable

Lancez la plateforme en ligne "Google Colab" : https://colab.research.google.com/?hl=fr ou tapez "google colab" dans le moteur de recherche).
Cliquez sur le bouton bleu "+Nouveau Notebook".
Dans l'IDLE de Python ouvrez le programme "entier_a_trouver.py"
Sélectionnez tout le code de ce programme et copiez le dans le nouveau notebook.
Renommez le notebook en "entier_a_trouver.ipynb" (un notebook a obligatoirement cette extension).

Aperçu du notebook :

Tester le programme

Il suffit de produire la commmande Exécution / Tout exécuter pour lancer le programme.
Rendu d'exécution :

Partager le programme

À partir de la page d'accueil de Google Colab il est possible d'adresser le programme à vos relations.

Sélectionnez "entier_a_trouver.ipynb" ; cliquez sur les trois points de suspension verticaux ; dans le menu contextuel choisir "partager" ; une boite de dialogue s'ouvre pour indiquer les contacts à qui vous allez adresser le fichier.
Je m'adresse le fichier :

Une vidéo intéressante

Développez en Python avec Google Colab

Créer une page web

Dans le chapitre suivant vous trouverez des exemples de scripts Python qui peuvent "tourner" dans un navigateur. car se présentant sous forme de pages web. Donc si ces pages web sont hébergées, référencées par les moteurs de recherche alors n'import quel internaute peut y accéder.

Télécharger les exécutables

Avant de passer à la programmation web via Python vous pouvez installer sur votre PC les deux exécutables évoquées dans ce chapitre :
La calculatrice avec une belle interface
Jeu "entier à trouver"