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

Module random - premiers programmes

Jusqu'à présent nous n'avons utilisé Python en mode interactif (mode console).
Gros inconvénient : aucune sauvegarde de notre travail. Il est temps de passer au mode script (ou mode programmé)
Un script est un fichier qui contient une suite de commandes interdépendantes constituant un traitement basé sur un algorithme.
Dans ce chapitre nous allons utiliser l'interface de programmation appelée IDLE (Integrated DeveLoppment Environnement)  c'est à dire  "environnement de développement intégré".
Dans cet "environnement de développement" vous aurez pour un projet plusieurs fenêtres : une pour le code source, une autre pour l'exécution de ce programme (shell) voire une troisième fenêtre pour l'affichage du graphique éventuel.
Pour lancer l'IDLE sous Windows, il suffit de cliquer sur l'un des icônes dans la barre de tâches légendée "IDLE ... ". Si vous n'avez pas créé ces raccourcis, il suffit de tapez "python" (ou "py")dans la zone de recherche de Windows puis de sélectionner "IDLE" dans la liste des applications proposées.

Un programme/script Python est un fichier d'extension .py
Créez un dossier nommé "python_prog" à la racine du disque dur C.
Vous rangerez dans ce répertoire tous les scripts de ce chapitre.

Le hasard dans Python

Pour simuler le hasard en Python il faut faire appel à des fonctions qui font partie du module random.

Les principales fonctions du module random

>>> maliste =list(range(1,21,2))
>>> maliste
[1, 3, 5, 7, 9, 11, 13, 15, 17, 19]
>>> import random as rd
>>> rd.shuffle(maliste)
>>> maliste
[15, 17, 19, 13, 3, 7, 1, 5, 11, 9]
>>> rd.sample(maliste,3)
[9, 19, 7]
>>> rd.randint(1,100)
51
>>> rd.choice(maliste)
9
>>> rd.random()
0.862046898238531

Commentaire de cette série de commandes

Je crée une liste d'entiers impairs.

Importation du module avec emploi d'un alias (rd). Les fonctions du module doivent alors être préfixées avec cet alias.

La fonction shuffle(liste) mélange les éléments d'une liste. Idéal pour mélanger une liste de cartes ...

La fonction sample(liste,n) tire au sort n éléments d'une liste.

La fonction randint(a,b) retourne un nombre entier entre a et b (bornes comprises). On peut ainsi facilement simuler le lancer d'un dé : randint(1,6).

La fonction choice(liste) permet de tirer au sort un élément de la liste.

La fonction random() retourne un nombre réel entre 0 (compris) et 1 (non compris). Même si il n'y a pas d'argument à saisir, les parenthèses sont obligatoires puisqu'il s'agit d'une fonction.

Premier programme en Python

Démarrez l'IDLE. ; une fenêtre légendée "untitled" s'affiche

Le code source

Tapez le code suivant dans cette fenêtre :

# nom du programme : test_input.py
#saisie tant que variable = 'fin'
while True :
    nombre  =input("tapez un nombre ou  'fin' : ")
    print('type : ', type(nombre))
    if nombre == 'fin' :
        break
print('fin de programme')

Surtout respectez l'indentation.
L'instruction while True: crée une boucle infinie. N'oubliez pas les deux points après "while true" pour signifier un début de bloc.
Toutes les lignes de ce bloc doivent donc être en retrait par rapport l'instruction introductive.
Attention l'instruction print('fin de programme') doit être exécutée qu'une fois; elle est donc en dehors du bloc. Donc cette instruction ne doit pas être en retrait mais au même niveau que while true :

L'instruction while true: crée une boucle infinie mais (et heureusement) l'utilisateur peut intervenir pour en sortir grâce à un bloc qui contient l'instruction break : sortie de boucle.

Sauvegarde du programme

Tant qu'il n'a pas été sauvegardé sous forme d'un fichier, un programme ne peut pas être exécuté.

Produisez la commmande File/Save ..." : une boite de dialogue s'ouvre pour enregistrer votre programme sous forme d'un fichier.
Sélectionnez le dossier (c:\python_prog) que vous avez créé spécialement pour stocker vos programme ; donnez un nom au fichier-programme : "test_input.py".

Exécution du programme

Pour appeler l'interpréteur Python à partir de l'IDLE il suffit de produire la commande "Run/Run module".
Une fenêtre d'exécution (appelée "shell") s'affiche et le message de l'instruction input apparait.
Votre saisie s'affiche à côté de l'invite, vous appuyez sur ENTER et le programme continue ...

Attention, comme le montre la capture d'écran, même si on saisit une suite de chiffres dans la variable "nombre" , cette saisie est considérée comme une chaine. Or on ne peut pas faire d'opérations arithmétiques sur une chaine ... Heureusement, on peut convertir une chaine composée de chiffres en un nombre comme nous le verrons dans le deuxième programme ci-dessous.

Deuxième programme

Dans un second programme je vais vous montrer comment convertir une chaine numérique (composée d'une suite de chiffres) en un nombre.
Créer un nouveau fichier dans l'IDLE avec la commande : File/New File ...

Le code source

# nom du programme : cumul_saisies.py
#saisie tant que variable = 'fin'
somme = 0
while True :
    nombre =input("tapez un nombre ou  'fin' : ")
    if nombre == 'fin' :
        break
    somme = somme + eval(nombre)
print('cumul des nombres saisis' , somme)

Ce programme permet de cumuler les valeurs saisies.
Il faut que chaque valeur saisie soit convertie en nombre d'où l'instruction : somme = somme + eval(nombre) La fonction eval(chaine) qui convertit une chaine (au format numérique) en un flottant.
J'aurais pu écrire : somme +=eval(nombre) ; voir ci-dessous les opérateurs d'affection complexes en Python.
À la place de la fonction eval() j'aurais pu utiliser la fonction float().

Exécution

Ci-dessous la fenêtre d'exécution :

Il y a bien cumul des trois nombres dont deux décimaux.

Attention à la saisie d'un nombre décimal

tapez un nombre ou 'fin' : 12,5
...
TypeError: unsupported operand type(s) for +: 'int' and 'tuple'
>>> 

Pour Python 12,5 est un tuple (suite de deux entiers : 12 & 5) et non pas un nombre décimal Le séparateur décimal doit être le point (et Jamais la virgule). Il fallait donc saisir 12.5.

Excécuter un programme à partir du terminal windows

À partir du moment qu'un programme est "débuggé", vous n'êtes plus obligé de passer par l'IDLE pour exécuter un programme. Vous pouvez appeler le programme à partir du terminal windows ("invite de commande").
Rappel : tapez cmd dans la zone "Rechercher" de la barre d'état pour lancer l'invite de commmande.

Microsoft Windows [version 10.0.22631.3527]
(c) Microsoft Corporation. Tous droits réservés.
C:\Users\boulanger>cd c:\python_prog

c:\python_prog>py test_input.py
tapez un nombre ou la chaine 'fin' : 5
type :  
tapez un nombre ou la chaine 'fin' : fin
type :  
fin de programme
c:\python_prog>py cumul_saisies.py
tapez un nombre ou 'fin' : 10
tapez un nombre ou 'fin' : 20
tapez un nombre ou 'fin' : fin
cumul des nombres saisis 30

Attention il faut d'apbord taper une commande DOS pour sélectionner le répertoire contenant le script : cd c:\python_prog. Ensuite, dès que vous êtes dans le dossier il suffit de taper : py test_input.py et ce programme s'éxécute.
Après exécution vous êtes toujours dans le répertoire c:\python_prog ; donc pour lancer le deuxième programme de ce dossier il suffit de taper python ou py suivi du nom du script.

Les structures conditionnelles ou tests

Vous avez déjà eu un aperçu des tests dans les deux programmes précédents. Dans chacun, on teste à chaque passage dans la boucle la saisie effectuée.
Si la variable nommée "nombre" contient "fin" alors sortie de la boucle (par exécution du "break").
Mais les tests peuvent être beaucoup plus complexes ... C'est l'occasion d'introduire le pseudo-code.

Algorithme en pseudo-code

Le pseudo-code, également appelé LDA (pour Langage de Description d'Algorithmes), est une façon de décrire un algorithme  en langage presque naturel pour un francophone donc sans référence à un langage de programmation en particulier.
L'écriture de l'algorithme en pseudo-code précède donc le codage proprement dit.
C'est l'étape la plus importante ; un programme respectant la syntaxe du langage, mais reposant sur un mauvais algorithme sera toujours un mauvais programme.

Si … alors

Exercice : si moyenne est supérieure ou égale à 12 il faut afficher "bon trimestre".
En pseudo-code :

SAISIR moyenne
CONVERTIR en flottant
SI moyenne ≥ = 12 ALORS AFFICHER  "bon trimestre" 

En pseudo-code il y a des mots réservés. L'usage veut qu'il soient écrits en majuscules.
Maintenant je code en python :

#nom programme : test_if.py
moyenne = input('tapez la moyenne')
moyenne = eval(moyenne) 	 
#conversion chaine en nombre
if moyenne >= 12 : 
	print("bon trimestre")

Je rappelle que toute saisie avec la fonction input est de type string même si vous avez saisi une suite de chiffres.
moyenne = eval(moyenne) : la variable moyenne contient d'abord une chaine puis un flottant.
Remarquez que dans l'instruction le terme "moyenne" est utilisée deux fois

Si … alors … sinon

Exercice : si la moyenne est supérieure ou égale à 12 il faut afficher "bon trimestre" sinon afficher "doit mieux faire"
Algorithme en pseudo-code :

 
SAISIR moyenne 
CONVERTIR moyenne
SI moyenne ≥ = 12 ALORS AFFICHER "bon trimestre"
SINON AFFICHER "peux mieux faire"

Le script Python :

 
# nom du programme : test_if_else.py
moyenne = input('tapez la moyenne')
moyenne = eval(moyenne) 
if moyenne >= 12: 
	print("bon trimestre")
else: 
	print("peut mieux faire")
Remarque : n'oubliez pas les ":" à la fin du "if" et du "else" pour annoncer un début de bloc.

Si … ALORS ... SINON SI ...

Exercice : barème de l'appréciation en fonction de la moyenne du trimestre.

Intervalleappréciation
>=18Excellent
[14 à 18[ Très bien
[10 à 14[ Correct
[6 à 10[ Insuffisant
< à 6 Très faible

Algorithme en pseudo-code - première solution

C'est celui qui vient à l'esprit en lisant le barème :

SAISIR moyenne  et CONVERTIR
SI moyenne > = 18  ALORS AFFICHER "excellent"
SINON SI moyenne >= 14 ET < 18   ALORS AFFICHER "très bien"
SINON SI moyenne >= 10 ET  < 14 ALORS AFFICHER "correct"
SINON SI moyenne >= 6  ET < 10 ALORS AFFICHER "insuffisant"
SINON AFFICHER "très faible" 

Cet algorithme est correct mais lourd. Puisqu' à chaque fois il faut comparer la moyenne à deux valeurs et donc introduire un opérateur logique.
Il existe une solution beaucoup plus simple : la technique des bornes décroissantes. C'est à dire comparer la moyenne à 18 puis à 14 puis à 10 et enfin à 6.

Algorithme amélioré

SAISIR moyenne & CONVERTIR
SI moyenne >= 18  ALORS AFFICHER "excellent"
SINON SI moyenne >= 14 ALORS AFFICHER "très bien"
SINON SI moyenne >= 10 ALORS AFFICHER "correct"
SINON SI moyenne >= 6 ALORS AFFICHER "insuffisant"
SINON AFFICHER "très faible" 

Supposons que :
moyenne = 15 : premier test retourne FALSE donc on passe au suivant, deuxième test est TRUE donc affichage "très bien".
moyenne = 9 : premier test est FALSE donc on passe au deuxième test qui est FALSE donc on passe au troisième qui est aussi FALSE donc on passe au quatrième qui est TRUE donc affichage de "insuffisant".

Code source

A partir de cet algorithme vous pouvez saisir directement dans l'IDLE le programme en Python.

Vous nommerez ce programme "test_if_elif.py".

Amélioration du programme

C'est bien gentil ce programme, mais si vous voulez déterminer l'appréciation pour toute une classe de 30 élèves, vous devez exécutez le script 30 fois ...
En fait c'est très facile d'améliorer ce programme pour que la routine de tests soit exécutée tant qu'on n'est pas fatigué. Il suffit d'intégrer le code précédent dans une boucle infinie.

Je vous communique ci-dessous le code de la version améliorée.

#nom programme : test_if_elif_plus.py
while True: 
    moyenne =input("saisir moyenne ou 'fin' : ")
    if moyenne =='fin':
        break
    moyenne =eval(moyenne) #conversion chaine en nombre
    if moyenne >= 18:
        print('excellent')
    elif moyenne >=14:
        print('très bien')
    elif moyenne >=10:
        print('correct')
    elif moyenne >=6:
        print('insuffisant')
    else:
        print('très faible')
    print("-----------------------")
print('fin du boulot')

Attention la ligne "print('fin de boulot')" est hors bloc (ne doit être exécutée qu'une fois) donc elle doit être au même niveau que "while True".

Critique de cette version prétendue améliorée

Python est sensible à la casse. Donc si vous saisissez "FIN" le test if moyenne =="fin" n'est pas vrai donc on ne sort pas de la boucle.
Le programme tente ensuite de convertir en nombre une chaine de lettres, il y a alors une erreur d'exécution.
Rassurez vous il y a bien sûr des solutions ; voir le chapitre X.

Un jeu

Le programme génère de façon aléatoire un entier inférieur à 100.
Ce nombre généré n'est pas affiché ; l'utilisateur doit le deviner, il fait des propositions. A chaque fois le programme répond : "trop grand" OU "trop petit" OU "correct" et alors le programme s'arrête.

Le code du jeu

# nom programme : nombre_a_trouver.py
from random import *
nbre_secret = randint(1,100)
while True
    nbre_propose = input('propose un nombre : ')
    if nbre_secret ==int(nbre_propose):
        print ('correct')
        break
    elif nbre_secret > int(nbre_propose)
        print('trop petit')
    else
        print('trop grand')

La fonction randint() du module random permet de gérer de façon aléatoire un entier.

Sauvegarde du programme sous le nom "nombre_a_trouver.py"
Lancez l'exécution mais ça ne fonctionne pas car il y a des erreurs de syntaxe.
Cherchez les erreurs (il y a en 3!).

Correction

from random import *
nbre_secret = randint(1,100)
while True:
    nbre_propose = input('propose un nombre : ')
    if nbre_secret ==int(nbre_propose):
        print ('correct')
        break
    elif nbre_secret > int(nbre_propose):
        print('trop petit')
    else:
        print('trop grand')

J'avais oublié les ":" à la fin de la ligne de code introduisant un bloc.

Les boucles

Vous savez déjà faire une boucle infinie et aussi comment sortir de cette boucle infinie. Voyons maintenant comment boucler un nombre fini de fois.

Objectif

On veut afficher successivement les cinq éléments d'une liste.

Première solution

Nous allons utiliser la structure while ...

#nom du programme : test_while.py
gars = ['Alain', 'Bernard', 'Claude', 'Didier', 'Emile']
i = 0
while i < 5:
        print(gars[i])
        i = i + 1

L'instruction i = i + 1 dans le bloc est indispensable sinon i sera toujours inférieur à 5 et donc bouclage à l'infini.

Deuxième solution

Le code source sera plus simple en utilisant avec la structure for ...

# nom programme : test_for.py
filles = ['Alice', 'Béatrice', 'Claudine', 'Delphine', 'Emma']
for i in range(5): #pour i de 0 à 4
    print(filles[i])

Lorsque l’on sait d'avance le nombre de fois qu'il faut itérer ; la commande FOR est la plus appropriée.
On retrouve le mot clé "for" associé à la fonction "range()" qui sert de compteur.
for i in range(5) signifie : pour i de 0 à 5 exclu (donc pour i de 0 à 4) avec un pas de 1 (valeur par défaut).

Autre exemple avec for ...

Affichage successif des 25 premiers impairs.

Le code source

# nom programme : impairs.py
for i in range(1,50): #pour i de 1 à 49
    if i%2 !=0:
        print(i, " est un nombre impair")
    else:
        continue
print("fin programme")

for i in range(1,50)" signifie : pour i de 1 à 49
Si le reste de la division entière du nombre par 2 est différent de 0, ce nombre est impair. Il faut l'afficher.
Sinon il faut passer à l'itération suivante : instruction continue

Mais il y a plus simple :
>>> for i in range(1,50,2) :
	print(i, 'est un impair')

Correction de l'exercice : le jeu de devinette amélioré

Non seulement le programme est "débuggé" mais de plus on peut jouer plusieurs fois.

# nom programme : nombre_a_trouver_plus.py
from random import *
choix ="O"
# boucle externe
while choix in "oO": 
    nbre_secret = randint(1,100)
	# boucle interne
    while True:
        nbre_joueur = input('propose un nombre : ')
        if nbre_secret ==int(nbre_joueur):
            print ('correct')
            break
        elif nbre_secret > int(nbre_joueur):
            print('trop petit')
        else:
            print('trop grand')
    choix =input('encore jouer ? O/N : ')

Tant que le joueur saisit "o" ou "O" la condition choix in "oO" est VRAI.

Parcours de liste

Il est souvent nécessaire dans un programme de parcourir un objet de type "list".

Première solution : for ... nomListe

Le script

 
#nom programme : parcours_liste.py
#objet : parcours d'une liste selon une méthode classique
maliste = ["Pierre", "Paul", "Jean", "Jacques", "Henri", "Bernard"]
for ele in maliste : 
    print (ele)

for ele in maliste : parcours de la liste ; la variable ele contient successivement les différentes éléments de la liste.
Le nom de la variable après le mot "for" est libre ; j'aurais pu utiliser "element" ou "valeur".

Exécution

Pierre
Paul
Jean
Jacques
Henri
Bernard

Seuls les éléments s'affichent mais pas l'indice correspondant à chaque élément ...

Deuxième solution : for ... in enumerate(nomListe)

Pour afficher l'indice il faut combiner la structure "for ... in" avec la fonction enumerate().

Le script

#nom prog parcours_liste_plus.py
#objet : parcours d'une liste avec la fonction enumerate
maliste = ["Pierre", "Paul", "Jean", "Jacques", "Henri", "Bernard"]
for indice, valeur in enumerate(maliste) :
	print(indice,valeur)

Après le mot clé "for" il y a deux variables : une pour l'indice et une autre pour la valeur correspondante.
J'aurais pu nommer ces variables autrement.

Exécution

0 Pierre
1 Paul
2 Jean
3 Jacques
4 Henri
5 Bernard

Les boucles - allons plus loin

Plusieurs boucles imbriquées

Vous connaissez tous les tables de multiplication. Et bien sachez que le programme Python pour les afficher est très très court : deux boucles FOR imbriquées.

Le programme

# nom programme : table_multiplication.py
# objet : tables de multiplication
print("Les tables de multiplication")
for i in range(1,11): #pour ligne de 1 à 10
    print("Table par " , i )
    for j in range(1,11):
        produit = i * j
        print(i, " *", j, " = ", produit)
    print("----------------")

Extrait du shell

...
Table par  2
2  * 1  =  2
2  * 2  =  4
2  * 3  =  6
2  * 4  =  8
2  * 5  =  10
2  * 6  =  12
2  * 7  =  14
2  * 8  =  16
2  * 9  =  18
2  * 10  =  20
----------------
...

En imbriquant deux boucles FOR l'instruction " print(i, " *", j, " = ", produit)" est exécutée 100 fois (10 par 10).

Les mots clé break & continue

Dans une boucle (créée avec for ... OU while ...) on peut trouver les mots clés break / continue.

Passer à l'itération suivante avec "continue"

>>> for elt in range(1,11):
...     if elt ==7:
...             continue
...     print(elt,end="-")
...
1-2-3-4-5-6-8-9-10->>>

L'item 7 n'est pas affiché.

Quitter la boucle prématurément avec break

>>> for elt in range(1,11):
...     if elt==9:
...             break
...     print(elt,end ="*")
...
1*2*3*4*5*6*7*8*>>>

La structure range n'est pas affichée complètement.

Un test de connaissances

Je vous propose un programme et plus précisément un jeu que l'on peut proposer à un élève pour vérifier s'il connait bien les tables de multiplication.

Le code source

# test_tables.py
# grâce à ce jeu vous testez vos connaissances des tables de multiplication
import random
compteur = 0
points = 0
while True :
    terme1 = random.randint(1,10)
    terme2 = random.randint(1,10)

    print("Saisir 'fin' pour quitter le jeu")
    reponse_saisie = input(f" produit de {terme1} par {terme2} ? ")
    if reponse_saisie.upper()== 'FIN' :
        break
    reponse_ok = terme1 * terme2
    if int(reponse_saisie) == reponse_ok :
	# conversion du contenu de reponse_saisi en entier 
        print("correct")
        points+=1
    else :
        print(f"erreur ; la reponse est :  {reponse_ok}")
    compteur+=1
    # fin boucle infinie
print ("========================")
print(f"Votre score est de {points} sur {compteur}")

Pour sortir de la boucle infinie il suffit de saisir "fin" quelque soit la casse : FIN ou fin ou fIN ...
Donc le programme gère les maladresses éventuelles de l'utilisateur.

Le rendu

Saisir 'fin' pour quitter le jeu
 produit de 5 par 8 ? 40
correct
Saisir 'fin' pour quitter le jeu
 produit de 8 par 10 ? 80
correct
Saisir 'fin' pour quitter le jeu
 produit de 8 par 6 ? 48
correct
Saisir 'fin' pour quitter le jeu
 produit de 10 par 9 ? fin
========================
Votre score est de 3 sur 3

Autre façon d'exécuter un programme Python

Vous pouvez exécuter un script Python à partir de l'explorateur de fichiers. Par exemple ouvrez avec l'explorateur le dossier "C:\python_prog" puis double-cliquer sur un des fichiers d'extension .py. (par exemple "test_tables.py).
Le script correspondant s'exécute (sauf si le programme est encore "buggé").

Ci-dessous le dossier "python_prog" affiché sous forme d'icônes : Lancer un script à partir de l'explorateur de fichiers

Grâce aux différents types d'icônes on identifie facilement la nature de chaque fichier : programme, base de données, fichier texte, etc.
Les scripts apparaissent avec le logo officiel de Python ; les fichiers texte avec le logo de NotePad, etc.

Des scripts plus professionnels

Dans le chapitre 10 vous verrez comment réaliser des programmes plus professionnels. En effet il est préférable d'un programme soit structuré en programme principal et sous-programmes afin qu'il soit plus lisible et plus facile à maintenir.
Dans un programme qui sera distribué on ne peut accepter que la moindre maladresse de l'utilisateur dans la saisie provoque un "plantage". Il faut donc prévoir des contrôles de saisie.

Des programmes pro.