Accueil

Tutoriel Python - sommaire

Compléments sur la programmation

Commentaires dans un programme Python

Un programme doit être commenté

Les commentaires doivent préciser : le nom de stockage du programme, son objet général.
Les instructions complexes doivent être expliquées.
Les débuts de programme principal, sous-programmes doivent être signalés aussi par des commentaires.
Grâce aux commentaires le débogage du code est facilité.

Comment écrire les commentaires ?

Commentaire sur une ligne : le commentaire doit être précédé du symbole #
Pour supprimer logiquement les instructions provisoires inssérées lors de la phase de débogage : faites les précéder du symbole #

Commentaires sur plusieurs lignes : le commentaire multi-lignes doit être délimité par trois guillemets doubles.

Formater des chaines en Python

Séquence de commandes à saisir :

>>> a=6
>>> b=4
>>> print("a = ", a, " et b = ", b)
a =  6  et b =  4
>>> print(f"a = {a} et  b = {b}")
a = 6 et b = 4

Les deux instructions basées sur print() retournent exactement la même chose.
Dans la première la fonction a plusieurs arguments : suite de chaines et de variables séparées par des virgules.
Dans le deuxième cas j'ai utilisé une seule chaine précédée du symbole f.
Argument du deuxième print (): f"a={a} et b={b}"
Notez le symbole f (comme formatage) placé devant la chaine. Entre accolades les noms des variables qui doivent être affichées dans la chaine.
Dès que vous serez habitué à cette syntaxe, vous y serez accroc (lol).

Retour sur les fonctions

Lorsqu'on évoque les fonctions, on emploie les termes paramètres & arguments. Ces deux termes sont souvent confondus.

Paramètres et arguments

Un exemple vaut mieux qu'un long discours ...
Commandes à saisir :

>>># définition d'une fonction >>> def bonjour(nom, prenom): ... chaine = "bonjour " + nom + " " + prenom ... return chaine … >>> bonjour("darche", "pat") #appel de la fonction 'bonjour darche pat' >>> bonjour("dupont") #appel de la fonction Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: bonjour() missing 1 required positional argument: 'prenom' >>>

nom & prenom sont les paramètres de la fonction "bonjour". Ils sont définis lors de la création de cette fonction.
"darche" & "pat" sont les arguments passés lors du premier appel de la fonction et "dupont" l'argument passé lors du deuxième appel.
Lors du deuxième appel de la fonction "bonjour", on ne saisit qu'un argument et il y a alors un "plantage".
Même si on n'est bon en anglais, on comprend le message : il manque un argument !

Or dans certaines situations, nous voulons créer des fonctions plus flexibles qui pourront accepter un nombre variable d’arguments.

Créer des fonctions acceptant un nombre variable d’arguments

Avec Python, c'est possible !
A saisir dans l'interpréteur :

 
>>> def somme(*args):
...     s=0
...     for i in args:
...             s = s+i
...     return s
...
>>> somme(10,20)
30
>>> somme(10,20,15,25)
70
>>>

Lors de la définition de la fonction le paramètre doit être "* args" (remplacez 'args' par ce que voulez).
Lors de l'appel de la fonction, vous saisissez en guise d'arguments un tuple de valeurs : 1 ou 2 ou 3, etc. valeurs séparées par des virgules.

Fonction récursive

Vous devez savoir qu’une fonction peut également s’appeler elle même dans son exécution. C’est ce qu’on appelle la récursivité.
L’exemple classique de fonction récursive est celle qui calcule une factorielle.
La factorielle de 4, par exemple, est égale à 1 * 2 * 3 * 4 = 24
La factorielle de 6 = 1 * 2 * 3 * 4 * 5 * 6 = 720

Ci-dessous programme de calculer plusieurs factorielles

# nom programme : factorielle.py
# objet : calcul de la factorielle de n
# début fonction 
def factorielle(n):
    if n == 0:
        return 1
    else:
        return n  * factorielle(n-1)
# fin fonction

# debut prog. principal 
reponse ="o"
while reponse in "oO":
    try:
        n = int(input ("Saisir un nombre entier :" ))
        resultat = factorielle(n)       #appel fonction
        print(f"factorielle de {n} est égale à {resultat}")
    except:
       print ("Vous avez du saisir une lettre et non un chiffre !")
    reponse =input("Continuez  o/n ? ")

Trace d'exécution de ce programme :

Saisir un nombre entier :4
factorielle de 4 est égale à 24
Continuez  o/n ? o
Saisir un nombre entier :6
factorielle de 6 est égale à 720
Continuez  o/n ? o
Saisir un nombre entier :1O
Vous avez du saisir une lettre et non un chiffre !
Continuez  o/n ? n

Tout cela mérite quelques explications ...

Commentaire de la fonction récursive

Notez la syntaxe return n * factorielle(n-1)
Si on argumente avec n > à 1 on retourne cette valeur et on appelle factorielle(n-1).
Si n-1 est toujours > à 1, on retourne cette valeur et on appelle à nouveau notre fonction avec une valeur diminuée de 1 ce jusqu’à ce que la valeur passée à factorielle() soit 1.

Vous trouvez ça compliqué. Rassurez vous, il y a une autre solution sans récursité évoquée plus loin.

Commentaire du programme principal

Si par malheur, l'utilisateur saisit 1o (chiffre 1 suivi de la lettre "o" au lieu de zéro) alors cette erreur de saisie est gérée proprement : pas de "plantage" du programme mais affichage d'un message d'erreur.
Notez les clauses "try:" et "except;" qui vont être expliquées dans le paragraphe suivant.

Autre solution pour la fonction factorielle

La récursivité est une notion algorithmique que certains ont du mal à maitriser. Or nous n'étions pas obligés d'utiliser la récursivité pour définir la fonction "factorielle". On peut utiliser le "couteau suisse" de la programmation en Python : la fonction range().

Nouvelle écriture de la fonction ci-dessous :

 
def factorielle(n):
if n == 0:
	return 1
else:
	F = 1
	for k in range(2,n+1):
		F = F * k
	return F

Donc la fonction retourne 24, ce qui est bien la factorielle de 4.

Je suis d'accord avec vous : c'est plus simple que la récursivité.
Mais au moins vous savez maintenant ce que c'est que la récursivité.

Gestion des erreurs en Python

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 qui indiquera à Python quoi faire si telle ou telle erreur est rencontrée. Bref, éviter le plantage du programme.
En Python, les erreurs survenant lors de l'exécution d'un script, sont appelées des exceptions.

L'emploi des expressions régulières permet d'éviter que certaines de ces erreurs ne surviennent ...

Les différents messages d'erreur

À saisir dans l'interpréteur :

>>> a= 20 >>> b=0 >>> a/b Traceback (most recent call last): File "<stdin>", line 1, in <module> ZeroDivisionError: division by zero >>> c="10" >>> d=10 >>> c+d Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: can only concatenate str (not "int") to str >>> d + e Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'e' is not defined >>>

Programmes avec gestion des exceptions

Ce programme a un objectif simple : saisie du dividende et du diviseur en vue d'obtenir le quotient.

Le code

""" nom du programme : gestion_exceptions.py
    objet : programme de division avec structure try et except
"""
try: 
      a = int(input("Tapez la valeur de a : "))
      b = int(input("Tapez la valeur de b : "))
      print("Le quotient de a par b est : a/b = " , a/b)
except:
    print("erreur : division par zéro ou saisie de chaines")

Notez que j'ai utilisé un commentaire multi-lignes pour indiquer le nom et l'objet du programme.
Les instructions sont réparties entre deux blocs : l'un introduit par la clause try: et l'autre par la clause except:.

Créez et testez ce programme

Donc si les saisies sont correctes, on reste dans le bloc "try".
Par contre si une erreur de saisie, on se retrouve dans le bloc "except".

Version définitive

Dans le cadre de la gestion des erreurs, on peut rajouter une clause else: . Le code contenu dans cette clause sera exécuté dans le cas ou aucune exception n’a été levée par la clause try:.
Il est conseiller de placer le code “non problématique” dans la clause else: plutôt que dans la clause try:.
La dernière clause à connaitre est la clause finally:. Le code qu’elle contient sera exécuté dans tous les cas, qu’une exception ait été levée par la clause try: ou pas.

Le code correspondant

""" nom du programme : gestion_exceptions_plus.py
    objet : programme avec structure try, except, else, finally
"""
reponse ="o"
while reponse in "oO": 
      try: 
            a = int(input("Tapez la valeur de a : "))
            b = int(input("Tapez la valeur de b : "))
            q= a/b
      except:
          print("erreur : division par zéro ou saisie de chaines")
      else:
            print(f"quotient : {q}") #emploi d'une chaine formatée
      finally:
            reponse =input("encore faire des divisions,  o/n ? : ")

Ce programme comprend donc 4 clauses : try:, exept:, else:, finally:
Ces clauses doivent toujours être dans cet ordre.
Notez que j'ai employé une chaine formatée en guise d'argument pour la fonction print() : f"quotient : {q}"

Commencez une chaine formatée avec f ou F avant d’ouvrir vos guillemets doubles. Dans cette chaine formatée vous pouvez insérer des variables (entre accolades).

Créez et testez ce programme

Dans tous les cas le programme vous demande si vous voulez encore faire des divisions.

N'oubliez pas les expressions régulières

Dois-je vous rappeler que de nombreuses erreurs de saisie peuvent être évitées grâce aux expressions régulières.
Privilégiez cette solution si il y a une batterie de saisies à faire.