Outils de base

Identification

Infoforall

7 - Outils de base


Nous allons maintenant voir les outils qui sont utilisées dans la majorité des programmes ainsi que quelques trucs bien pratiques en Python pour réaliser des permutations ou des affectations multiples.

Vous allez encore aujourd'hui travailler avec l'environnement qui permet très simplement d'observer le contenu des variables : Thonny.

Evaluation ✎ : questions 05-07-09-13-14-16-18

Résumé : Version HTML ou fond blanc ou ou PDF (couleur ou gris)

1 - Test logique SI

Avec input, vous savez maintenant poser des questions à l'utilisateur et stocker ses réponses.

La prochaine étape dans la conception d’un programme interactif : les choix logiques. Nous n'allons faire qu'une introduction ici. Voyons comment faire agir l'ordinateur de façon différente en fonction des réponses données. Et faire un petit jeu.

Booléens

Pour comprendre les tests logiques, il faut savoir que les ordinateurs n'ont que deux choix possibles lorsqu'on leur donne une proposition à tester (du style "est-on en 2025 ?"). Il s'agit d'un booléen, d'après George Boole, fondateur de l'algèbre de Boole dans le milieu du 19ème siècle.

Un booléen ne peut valoir que True (pour VRAI) ou False (pour FAUX). Dans les faits, Python considère que 0 correspond à False et le reste à True.

Si nous étions en 2025, le résultat de "Sommes-nous en 2025 ?" donnerait True. Sinon, le résultat donnerait False.

01° Tester le programme suivant avec différentes réponses :

1 2 3 4 5 6 7 8 9 10 11 12 13 14
# Initialisation des données annee_creation_python = 1991 reponse = input("En quelle année est sortie la première version de Python ? ") # Traitement des données reponse = int(reponse) if reponse > annee_creation_python : print("Votre réponse est fausse.") print(f"Python a été créé avant {reponse}") elif reponse < annee_creation_python : print("Votre réponse est fausse.") print(f"Python a été créé après {reponse}") else : print(f"Oui, Python est sorti pour la première fois en {reponse}")

CLIQUEZ SUR UN BOUTON-REPONSE :

reponse :

annee_crea... :

C'est l'indentation vers la droite qui permet à Python de comprendre les actions que vous voulez qu'il réalise si une condition est vérifiée. Il faut donc placer une tabulation ou 4 espaces de suite pour savoir qu’elles sont les instructions rattachées au bloc. De plus, on remarquera qu’on met un double point [ : ] après la condition de if, else if (elif en Python) ou else. Sans ce symbole, vous déclenchez une erreur. Ce double point permet de dire à l'interpréteur que la déclaration de la condition est finie.

Dans Thonny ou tout autre éditeur spécialisé dans Python, la tabulation est équivalente à 4 espaces. Attention par contre aux éditeurs multi-langages. La tabulation est parfois de 2 ou 3 espaces. Dans ce cas, votre code ne sera pas compris par l'interpréteur Python. Dans ce cas de figure, préférez les 4 espaces ou configurez votre éditeur pour forcer une tabulation équivalente à 4 espaces.

La chose à bien comprendre : l'interpréteur Python ne va exécuter que l'un des blocs.

Déroulement d'une séquence if - elif - else

Si on regarde le code en le divisant en bloc, on obtient ceci :

if reponse > annee_creation_python : print("Votre réponse est fausse.") print(f"Python a été créé avant {reponse}")
elif reponse < annee_creation_python : print("Votre réponse est fausse.") print(f"Python a été créé après {reponse}")
else : print(f"Oui, Python est sorti pour la première fois en {reponse}")

Je répète : La chose à bien comprendre : l'interpréteur Python ne va exécuter que l'un des blocs. Il s'arrête au premier test correct et ne s'occupe pas des autres situés en dessous, même si les conditions sont vraies également.

02° Créer un programme qui demande l'age de l'utilisateur et qui affiche qu'il est adulte et peut voter s'il a 18 ans ou plus (codé à l'aide de >=. Sinon (il n'y aura donc pas de elif), il dit que l'utilisateur est mineur et qu'il ne peut pas encore voter.

...CORRECTION...

1 2 3 4 5 6 7 8
age = int(input("Quel est votre age ? ")) if age >= 18 : print("Vous êtes adulte.") print("Vous avez le droit de vote.") else : print("Vous n'êtes pas encore adulte. Vous n'avez pas encore le droit de vote.")

Attention à l'ordre de vos tests.

Comme l'interpréteur n'exécute qu'un des blocs, il vaut être vigilant. Nous en reparlerons lors d'une activité dédiée à cela.

2 - Egalité et hasard

Voyons maintenant le test d'égalité. C'est à dire tester si une variable contient bien 5 par exemple.

Pour tester une égalité en Python, on n'utilise pas a = b qui donne un ordre d'affectation : l'ordinateur comprend dans ce cas qu'il faut stocker b dans la variable a.

Tester une égalité avec Python

Pour tester l'égalité, on utilise un double signe égal a == b. Cette instruction teste réellement si les deux variables sont égales.

Le code ci-dessous permet d'affecter à la variable mystere un nombre aléatoire compris entre 1 et 3. Pour cela, on importe le module random et on va y chercher la fonction randint(min, max) qui renvoie un nombre entier aléatoire compris dans l'intervale [min;max].

03° Compléter le code pour qu'il affiche bien le message lorsqu'on trouve le bon nombre.

1 2 3 4 5 6 7 8 9 10 11
import random mystere = random.randint(1,3) reponse = input("Tapez un nombre entier, entre 1 et 3 : ") reponse = ??? if ??? == ??? : print("Vous avez trouvé le bon nombre mystère.") else : print(f"Vous n'avez pas trouvé le nombre {mystere}")

...CORRECTION...

1 2 3 4 5 6 7 8 9 10 11
import random mystere = random.randint(1,3) reponse = input("Tapez un nombre entier, entre 1 et 3 : ") reponse = int(reponse) if reponse == mystere : print("Vous avez trouvé le bon nombre mystère.") else : print(f"Vous n'avez pas trouvé le nombre {mystere}")

3 - Boucle non bornée tant que / while

Voyons maintenant le tant que / while, bien pratique avec cette activité qui consiste à récupérer des données. En effet, comment parvenir par exemple à demander l'arrêt d'un programme lorsqu'on a trouvé le bon nombre ?

On pourrait utiliser un test SI mais cela ne fonctionnerait qu'une fois ...

Boucle non bornée : la boucle while

Heureusement, il existe le test TANT QUE. Il s'agit d'instructions qui seront executés en boucle TANT QUE la condition testée est VRAI.

Puisqu'on ne peut pas connaitre à l'avance le nombre de fois où la boucle d'exécution va être réalisée, on parle également de boucle non bornée : il n'y a pas de nombre limite au bout duquel on quitte la boucle.

Elle se code de la façon suivante :

while condition_a_respecter :

Comme pour le IF, c'est l'indentation de 4 espaces qui permet d'indiquer quelles instructions sont à faire en boucle.

Voici à titre d'exemple la façon d'utiliser un while (TANT QUE).

04° Tester le code en tapant plusieurs fois N avant de taper O.

1 2 3 4 5 6 7
reponse = "N" nombre = 0 while reponse == 'N' : nombre = nombre + int(input("Quel nombre voulez-vous rajouter ? ")) reponse = input("Voulez-vous sortir du programme ? (O/N): ") print(f"Au total, on obtient {nombre}")

Comme pour les autres tests, nous les étudierons plus en détail plus tard.

Il est temps de réaliser votre premier vrai jeu :

✎ 05° Réaliser un jeu où on cherche à trouver un nombre (voir le programme de la question 4). La différence ? On continue tant qu'il ne trouve pas le bon nombre. Pour tester une égalité, c'est ==.

Tester une inégalité

Pour tester une inégalité, une différence de valeur, il faut utiliser !=. Par exemple  a != b .

Une fois que cela fonctionne, compliquer le code en rajoutant une indication sur le nombre à trouver au cas où le joueur ne trouverait pas le bon nombre : on doit dire si le nombre cherché est plus grand ou plus petit.

Finalement, créer un compteur pour connaitre le nombre de réponses données pour atteindre la bonne réponse.

Et voici une correction possible (à n'utiliser que si vous bloquez !) :

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
import random mystere = random.randint(1,100) reponse = 0 nombre = 0 print('Il faut trouver un nombre entier compris entre 1 et 100 !') while mystere != reponse : reponse = int(input("Quel nombre voulez-vous faire tester ? ")) nombre = nombre + 1 if reponse > mystere : print('Le nombre mystère est plus petit que cela.') elif reponse < mystere : print('Le nombre mystère est plus grand que cela.') print(f"Vous avez trouvé la réponse en {nombre} coups.")

4 - Boucle bornée POUR / FOR

Nous allons voir comment parvenir à afficher plusieurs fois le même message sans pour autant avoir à taper plusieurs fois ce message.

Imaginons qu'on désire afficher 5 fois le message ATTENTION (pour indiquer que c'est vraiment très important) :

06° Tester pour vérifier que le programme suivant fonctionne.

1 2 3 4 5 6
print("Attention") print("Attention") print("Attention") print("Attention") print("Attention") input("Tapez ENTREE")

Néanmoins, c'est un peu répétitif : on doit noter 5 fois le même mot. Et si finalement, on veut afficher "Warning !" ou même "Attention !" ? Et bien, on est bon pour modifier les lignes à la main.

Nous allons déjà faire mieux en utilisant une variable.

✎ 07° Modifier le programme ci-dessus en utilisant une variable de façon à n'avoir à fournir le texte à afficher qu'une seule fois : si finalement on décide de changer le message à afficher, c'est plus facile. Nommer cette variable monTexte par exemple.

Et si maintenant on affichait le message 2000 fois ! Là, c'est carrément lourd. Il faudrait faire du copier-coller pour obtenir 2000 lignes. Ni 1999, ni 2001. Bref, c'est lourd.

Et c'est compliqué uniquement car nous n'avons pas utilisé le bon outil : avec la boucle FOR, ça se règle en quelques lignes.

Cette boucle va permettre de faire les mêmes instructions plusieurs fois de suite. La différence avec le WHILE ? On définit à l'avance le nombre de bouclage.

Comme pour le IF, c'est l'indentation de 4 espaces qui permet d'indiquer quelles instructions sont à faire en boucle.

08° Utiliser le programme. Combien de fois effectue-t-on la boucle ? Donner les valeurs prises par la variable x de la boucle FOR. Combien de valeurs y a-t-il ?

1 2 3 4 5 6 7
# D'abord on crée la variable monTexte # Ensuite on boucle monTexte = "Nouveauté" for x in range(5) : print(x) print(monTexte) # On est sorti de la boucle en arrivant ici

CLIQUEZ ICI POUR VOIR LE CONTENU DE LA VARIABLE :

monTexte :

x :

Vous devriez obtenir ceci :

0 Nouveauté 1 Nouveauté 2 Nouveauté 3 Nouveauté 4 Nouveauté

...CORRECTION...

Les instructions print(x) et print(monTexte) sont réalisées 5 fois. La boucle est donc réalisée 5 fois.

La variable x prend les valeurs 0, 1, 2, 3 et 4.

La variable x prend donc bien 5 valeurs mais comme on commence à 0, on ne va que jusqu'à 4.

Nous irons beaucoup plus loin dans l'activité sur les boucles FOR. Il ne s'agit ici que d'une introduction ou un rappel à des notions que vous avez certainement déjà rencontré.

Valeurs prises par la variable de boucle

Retenez bien que lors d'une boucle créée avec for x in range(5), la variable de boucle nommée x ici, est dans l'intervalle [ 0 ; 4 ] ou [ 0 ; 5 [.

La variable ne va PAS jusqu'à 5 ! Sinon, on aurait fait 6 fois la boucle : 0 - 1 - 2 - 3 - 4 - 5.

✎ 09° Créer un programme utilisant une variable contenant un texte et une boucle FOR pour afficher 500 fois le message Hello World ! suivi de la valeur de la variable de boucle.

Hello World ! 0 Hello World ! 1 ... Hello World ! 499

Que vaut la première valeur de la variable de boucle ?

Que vaut la dernière valeur de la variable de boucle ?

On peut heureusement faire autre chose que juste partir de 0 et atteindre une valeur finale.

Description plus complète de range

En réalité, on peut transmettre autre chose que la valeur finale (non incluse) avec range.

On peut en réalité transmettre :

  1. La valeur de départ
  2. La valeur bornant la fin (non incluse)
  3. Le pas : la variation à appliquer à chaque tour de boucle

Si on veut créer une variable de boucle prenant les valeurs entières de 0 à 9, on a donc deux façons de l'écrire :

1 2
for x in range(10) : print(x)
1 2
for x in range(0,10,1) : print(x)

Comme vous pouvez le voir, si on ne transmet qu'une valeur, l'interpréteur Python va placer par défaut le départ à 0 et incrémenter de 1 à chaque boucle.

Il existe trois possibilités :

  1. On ne fournit que la borne finale (non atteinte) :
  2. 1 2
    for x in range(10) : print(x)

    Ici on obtient l'ensemble de valeurs 0-1-2-3-4-5-6-7-8-9.

  3. On fournit la valeur initiale et la borne finale (non atteinte) :
  4. 1 2
    for x in range(2, 10) : print(x)

    Ici on obtient l'ensemble de valeurs 2-3-4-5-6-7-8-9.

  5. On fournit tout : la valeur initiale, la borne finale (non atteinte) et la valeur du pas :
  6. 1 2
    for x in range(2, 10, 3) : print(x)

    Ici on obtient l'ensemble de valeurs 2-5-8.

    • On part de 2.
    • On rajoute 3 : on obtient 5.
    • On rajoute 3 : on obtient 8.
    • On stoppe puisque 8+3 donne 11 : c'est supérieur à 9 qui est la valeur extrême.

10° Fournir un code permettant de compter de 10 à 100, de deux en deux.

L'affichage doit donc afficher quelque chose comme 10 - 12 - 14 - ... - 98 - 100.

...CORRECTION...

1 2
for nombre in range(10, 101, 2) : print(nombre, end=" - ")

11° Fournir un code permettant de compter cette fois de 100 à 10 en diminuant de deux à chaque fois.

L'affichage doit donc afficher quelque chose comme 100 - 98 - 96 - ... - 12 - 10.

...CORRECTION...

1 2
for nombre in range(100, 9, -2) : print(nombre, end=" - ")

5 - La permutation

Première chose courante en informatique : la permutation.

Si vous voulez inverser les pièces qui se trouvent dans votre poche droite et dans votre poche gauche, en tant qu'humain, c'est facile puisque vous avez deux mains.

L'ordinateur lui ne peut faire qu'une chose à la fois. Il va donc devoir utiliser un stockage temporaire d'informations pour parvenir à inverser le contenu de deux variables.

Si vous voulez mettre l’argent argentGauche dans argentDroite et inversement, il faut normalement 3 variables, trois conteneurs :

Déroulé étape par étape :

videPoche = argentDroite

Cela permet de créer une variable videPoche et y placer le contenu de la variable argentDroite.

argentDroite = argentGauche

Mettre le contenu de la variable argentGauche dans la variable argentDroite.

  • Mettre le contenu de la variable videPoche (qui contient l’argent initialement à droite) dans argentGauche.
  • argentGauche = videPoche

    Bref, c’est long et plutôt compliqué puisqu'on a besoin de 3 conteneurs au total.

    Python intègre un outil de permutation automatique. Il suffit de taper une seule ligne d'instruction. Il suffit de noter :

    a,b = b,a

    12° Tentez de permuter les poches droite et gauche à l’aide de la commande ci-dessus.

    >>> g = float(input('Combien à gauche ? : ')) >>> g >>> d = float(input('Combien à droite ? : ')) >>> d >>> g,d = d,g >>> g >>> d

    En réalité, cette permutation magique d'une ligne va simplement automatiquement créer la permutation à 3 conteneurs. Mais vous n'aurez pas en vous en occuper.

    Permutation en NSI

    Si vous êtes en NSI, nous allons utiliser uniquement la méthode des 3 variables. Pourquoi ?

    Simplement car cet outil de permutation est un spécificité de Python. Beaucoup d'autres langages ne l'implémentent pas.

    Nous écrirons donc plutôt ceci (même si on peut faire plus simple avec une permutation) :

    a = 5 b = 10 temporaire = b b = a a = temporaire

    6 - Un autre outil pratique : l’affectation multiple

    Imaginons qu’on désire créer 6 variables a, b, c, d, e et f contenant 3,78. Il faudrait créer 6 lignes de code. On peut faire plus simple avec la ligne suivante :

    a = b = c = d = e = f = 3.78

    7 - ET / OU

    Imaginons qu'on veuille créer une fonction est_valide qui vérifie qu'une note est bien comprise entre entre 0 et 20.

    1 2 3 4 5 6 7 8 9 10 11 12
    def est_valide(n) : '''Fonction qui renvoie True si n est un entier dans [0;20] :: param n(int) :: un entier quelconque :: return (bool) :: True si n est dans [0;20], False sinon ''' if n > 20 : return False elif n < 0 : return False return True

    13° Expliquer pourquoi la fonction est_valide ne renvoie pas systématiquement True alors qu'il s'agit de la dernière ligne de cette fonction.

    ...CORRECTION...

    Tout simplement car on sort de la fonction dès qu'on rencontre un return.

    Si l'un des deux tests précédents renvoie True, on va donc exécuter le return False et sortir de la fonction.

    ✎ 14° Un élève propose la fonction ci-dessous. Expliquer clairement pourquoi sa fonction n'est pas correcte alors qu'elle ne déclenche pas d'erreur et qu'elle renvoie bien True pour une note de 15 par exemple.

    1 2 3 4 5 6 7 8 9 10 11 12
    def est_valide(n) : '''Fonction qui renvoie True si n est un entier dans [0;20] :: param n(int) :: un entier quelconque :: return (bool) :: True si n est dans [0;20], False sinon ''' if n <= 20 : return True elif n >= 0 : return True return False

    Si vous ne trouvez pas, demandez-vous ce qu'elle renvoie pour une note de -15.

    Pour obtenir un code plus lisible et concis, il existe un moyen d'associer la réponse de plusieurs tests logiques.

    Voyons comment cela fonctionne.

    15° Tapez les instructions ci-dessous dans le Shell.

    >>> note = 15 >>> note >= 0 True >>> note < 0 False >>> note <=20 True >>> note > 20 False >>> note >= 0 and note <= 20 True >>> note = 25 >>> note >= 0 and note <= 20 False

    Question : lorsque deux conditions sont reliées par un and, dans quel cas l'expression totale va-t-elle évaluée à True ?

    ...CORRECTION...

    L'expression n'est évaluée à True qui si les deux conditions sont également évaluées à True. Il s'agit d'un ET logique.

    Voici donc une manière plus simple de créer notre fonction est_valide. Cela ne change en rien son utilisation : pour l'utilisateur, le changement est totalement invisible.

    1 2 3 4 5 6 7 8
    def est_valide(n) : '''Fonction qui renvoie True si n est un entier dans [0;20] :: param n(int) :: un entier quelconque :: return (bool) :: True si n est dans [0;20], False sinon ''' return n >= 0 and n <= 20

    Une seule ligne, hors documentation. Pas mal non ?

    ✎ 16° Un élève propose la fonction ci-dessous. Expliquer clairement pourquoi vous pensez que sa fonction est correcte ou fausse (pensez à regarder les préconditions sur le paramètre n).

    1 2 3 4 5 6 7 8
    def est_valide(n) : '''Fonction qui renvoie True si n est un entier dans [0;20] :: param n(int) :: un entier quelconque :: return (bool) :: True si n est dans [0;20], False sinon ''' return n > -1 and n < 21

    Nous allons revoir en détail le ET dans d'autres activités. Voici simplement ce qu'on nomme la table de vérité d'un ET :

    Valeur de a Valeur de b a ET b
    VRAI VRAI VRAI
    FAUX VRAI FAUX
    VRAI FAUX FAUX
    FAUX FAUX FAUX

    Il existe également le OU

    Un ET répond VRAI lorsque toutes les entrées sont VRAIES.

    Le OU répond VRAI lorsqu'une des entrées au moins est VRAIE.

    17° Compléter la table de vérité du OU :

    Valeur de a Valeur de b a OU b
    VRAI VRAI ?
    FAUX VRAI ?
    VRAI FAUX ?
    FAUX FAUX ?

    Cela revient à chercher cela avec Python :

    a or b

    ...CORRECTION...

    Valeur de a Valeur de b a OU b
    VRAI VRAI VRAI
    FAUX VRAI VRAI
    VRAI FAUX VRAI
    FAUX FAUX FAUX

    ✎ 18° QCM : On demande à quatre élèves de créer une fonction note_invalide. Elle doit renvoyer True si la note n n'est pas dans [0;20].

    On vous fournit ci-dessous la réponse de leur fonction. Quel élève fournit la bonne façon de repondre ?

    • A : return n >= 0 or n <= 20
    • B : return n <= 0 or n >= 20
    • C : return n > 0 or n < 20
    • D : return n < 0 or n > 20

    8 - FAQ

    Aucune question

    Les conditions IF, les boucles bornées FOR et non bornées WHILE seront désormais utilisées de façon régulière.

    D'autres activités ou articles les détailleront car il y a encore beaucoup à dire à leur sujet.

    L'activité suivante propose de gérer une animation Turle utilisant les tests et les fonctions.

    Activité publiée le 28 08 2019
    Dernière modification : 19 07 2020
    Auteur : ows. h.