Outils Pour et Tableau

Identification

Infoforall

10 - Boucles bornées et tableaux


Cette activité présente deux façons d'utiliser une boucle bornée.

Evaluation ✎ : -.

La partie Tkinter est entièrement optionnelle comme d'habitude.

Documents de cours :

1 - Boucles bornées et tableaux

Un petit complément de cours (avant de voir les tableaux en cours de façon plus approfondi) pour que vous puissiez voir la puissance de la boucle FOR associée aux données structurées :

1/3 - Création et lecture d'un tableau

On peut enregistrer une séquence de données dans un tableau en utilisant un crochet [ en ouverture, un crochet ] en fermeture et des virgules pour séparer les valeurs.

On peut alors accéder à la valeur en tapant simplement le nom de la variable suivi de crochets et du numéro d'indice voulu.

Indice 0 1 2 3 4 5 >>> tables = ['Alice', '-', 'Bob', '-', '-', 'Clark'] >>> tables[0] 'Alice' >>> tables[1] '-' >>> tables[2] 'Bob' >>> tables[3] '-' >>> tables[4] '-' >>> tables[5] 'Clark' >>> tables[6] IndexError: list index out of range

Comme vous le voyez, on peut facilement savoir qui a reservé une table précise et si une table n'a pas été réservée : il suffit de constater que le tableau ne contient rien à ce numéro. On utilisera souvent plutôt numéro d'indice ou simplement indice.

La version anglaise d'indice est index.

2/3 - Déterminer la longueur d'un tableau

La longueur d'un tableau correspond au nombre de "cases" du tableau.

Comment connaître le nombre de cases d'un tableau  ? Comme avec les strings tout simplement : on utilise la fonction native len().

Indice 0 1 2 3 4 5 >>> tables = ['Alice', '-', 'Bob', '-', '-', 'Clark'] >>> len(tables) 6

Comme on voit qu'il y a 6 tables, on sait alors qu'on peut demander des numéros de cases allant de 0 à ...5.

01° Observer cette façon de transformer l'évaluation du range en cases d'un tableau en utilisant la fonction native list() qui permet de tenter de convertir quelque chose en tableau :

>>> list(range(10)) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Comme nous l'avons vu, range(10) va donc être évalué comme une séquence de valeurs partant de 0 et allant jusqu'à 9.

Questions

Expliquer pour chaque proposition, le contenu du tableau obtenu. Vérifier ensuite à l'aide de la console.

  1. list(range(4))
  2. list(range(2, 6))
  3. list(range(2, 60, 10))
  4. list(range(100, -1, -20))

...CORRECTION...

>>> list(range(4)) [0, 1, 2, 3]

On donne une seule valeur : c'est donc la valeur "presque" finale (on s'arrête juste avant).

Pas de valeur initiale : c'est donc zéro.

Pas de pas : c'est donc +1 à chaque fois.

>>> list(range(2, 6)) [2, 3, 4, 5]

On donne deux valeurs : c'est donc la valeur de départ et la valeur "presque" finale (on s'arrête juste avant).

Pas de pas : c'est donc +1 à chaque fois.

>>> list(range(2, 60, 10)) [2, 12, 22, 32, 42, 52]

On donne trois valeurs : c'est donc la valeur de départ, la valeur "presque" finale (on s'arrête juste avant) et le pas (ici, on gagne +10 lorsqu'on passe à l'élément suivant). On ne peut pas atteindre 62 puisqu'on doit au pire s'arrêter à 59.

>>> list(range(100, -1, -10)) [100, 80, 60, 40, 20, 0]

On donne trois valeurs : c'est donc la valeur de départ (100), la valeur "presque" finale (on s'arrête juste avant -1, comme on descend, on s'arrêtera à 0) et le pas (ici, on perd 20 lorsqu'on passe à l'élément suivant, d'où le -20).

02° Expliquer le contenu du tableau indices obtenu. Vérifier ensuite à l'aide de la console.

>>> tableau = ['Ananas', 'Banane', 'Clémentine', 'Datte'] >>> indices = list(range(len(tableau))) >>> indices ???

Vu comme cela, c'est impressionnant mais en se souvenant de la séquentialité, ça ira mieux : pour répondre, il faudra agir comme l'interpréteur Python et évaluer séquentiellement les demandes :

  1. D'abord : que vaut len(tableau) ?
  2. Puis : que vaut range(len(tableau)) ?
  3. Enfin : que vaut list(range(len(tableau))) ?

Remarque : j'ai nommé le tableau indices avec un s car il contient les différentes valeurs des indices disponibles pour ce tableau.

...CORRECTION...

Le tableau contient 4 cases.

La longueur du tableau est donc 4.

  1. On évalue d'abord len(tableau) à 4.
  2. range(len(tableau)) revient donc à évaluer range(4), soit une séquence de 4 nombres allant de 0 à 3 (et pas 4 attention)
  3. list(range(len(tableau))) est donc équivalent ici à [0, 1, 2, 3]

Voyons maintenant le lien entre les tableaux et les boucles bornée.

3/3 - Association d'une boucle FOR et de LEN

On peut lire une à une les cases d'un tableau en utilisant une boucle FOR associée à la fonction native len().

Regardons comme lire les réservations de tables de notre restaurant :

1 2 3
tables = ['Alice', '-', 'Bob', '-', '-', 'Clark'] for indice in range( len(tables) ): print( tables[indice] )

Si vous lancez ce programme, vous obtiendrez cela :

Alice - Bob - - Clark

Exécution en image :

Lecture d'un tableau
CLIQUER SUR L'IMAGE pour ANIMER ou STOPPER

Comment ça fonctionne ?

  • La fonction native len() va renvoyer 6, la longueur du tableau : son nombre de cases.
  • On obtient donc for indice in range(6):
  • Cela revient donc à for indice in [0, 1, 2, 3, 4, 5]:
  • Et voilà : à l'aide de la boucle FOR, la variable de boucle indice va prendre tour à tour les valeurs 0, puis 1, puis 2...

Cela veut dire que le programme fourni est identique au programme suivant :

1 2 3 4 5 6 7
tables = ['Alice', '-', 'Bob', '-', '-', 'Clark'] print( tables[0] ) print( tables[1] ) print( tables[2] ) print( tables[3] ) print( tables[4] ) print( tables[5] )

Je ne sais pas vous, mais pour un tableau de 3000 cases, je préfère utiliser une boucle FOR plutôt que de taper 3000 lignes.

✎ 03° Modifiez un peu le fString dans la fonction d'interface print() ci-dessous de façon à forcer l'affichage proposé dans la console :

Réservation de la table n°0 : Alice Réservation de la table n°1 : - Réservation de la table n°2 : Bob Réservation de la table n°3 : - Réservation de la table n°4 : - Réservation de la table n°5 : Clark
1 2 3
tables = ['Alice', '-', 'Bob', '-', '-', 'Clark'] for indice in range( len(tables) ): print( f"{tables[indice]}" )

Rappel : un fString est string dont les guillemets d'ouverture sont précédes d'un f. A l'intérieur du string, on trouve des accolades {}. Le principe est simple : dans un fString, Python évalue l'expression entre accolades et place ce résultat à cet endroit dans le string. Exemple :

>>> a = "Alice" >>> b = "Bob" >>> c = f"Bonjour à {a} et à {b}" >>> c 'Bonjour à Alice et Bob'

✎ 04° Que va afficher ce programme :

1 2 3
destinations = ['Lille', 'Paris', 'Marseille', 'Brest', 'Strasbourg', 'Bordeaux'] for indice in range(3): print( f"{destinations[indice]}" )

✎ 05° Que va afficher ce programme :

1 2 3
destinations = ['Lille', 'Paris', 'Marseille', 'Brest', 'Strasbourg', 'Bordeaux'] for indice in range( len(destinations) ): print( f"{destinations[indice]}" )

2 - tkinter

Partie optonnelle : aucune connaissance Tkinter attendue pour le BAC

Uniquement pour ceux qui ont le temps et qui désirent en apprendre plus sur les interfaces graphiques. L'utilisation d'une interface graphique n'est pas au programme de NSI.

TK 01° Utiliser le programme suivant qui permet de créer une interface Tkinter. Seules les lignes 34 à 36 permettant d'afficher des Labels à l'aide d'une boucle sont à comprendre.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
# 1 - Importations import tkinter as tk import random as rd # 2 - Déclaration des constantes C_LAB = "#FF7777" # Couleur des widgets C_FND = "#000000" # Couleur de fond # 3 - Déclaration des fonctions def creation_interface(titre, couleur): '''Crée et renvoie la référence d'interface graphique :: param titre(str) :: le titre visible dans la barre de l'application :: param couleur(str) :: une couleur de fond valide pour l'application :: return (tk.Tk) :: la référence Tkinter de l'application ''' fe = tk.Tk() fe.geometry("600x300") fe.title(titre) fe.configure(bg=couleur) return fe # 4 - Programme # 4-1 - Création et configuration de la fenêtre du logiciel fenetre = creation_interface("Le For et Tkinter", C_FND) # 4-2 - Création-configuration des Labels et affichage for i in range(0, 9, 1): zone = tk.Label(fenetre, text=i, width=5, height=3) zone.place(x=20+60*i, y=20) # 4-3 - Création-configuration d'un Label et affichage # 4-4 - Surveillance des événements fenetre.mainloop()

Questions

  1. Quelles sont les valeurs successives prises par la variable de boucle i ?
  2. Quelles sont les coordonnées x et y du premier widget (celui qui contient 0) ?
  3. Quelles sont les coordonnées x et y du deuxième widget (celui qui contient 1) ?

...CORRECTION...

  1. Puisqu'on a for i in range(0, 9, 1):, la variable va prendre les valeurs 0, 1, 2, 3, 4, 5, 6, 7 et 8.
  2. Ligne 36, on voit le calcul à faire avec i = 0 : x = 20 + 60*0 = 20 et y = 20
  3. Ligne 36, on voit le calcul à faire avec i = 1 : x = 20 + 60*1 = 80 et y = 20

TK 02° Modifier le programme pour parvenir à afficher ceci :

Fournir uniquement la ligne à modifier, pas tout le programme.

TK 03° Expliquer le placement des carrés de 0 à 8 en analysant uniquement les trois lignes surlignées. Vous pourriez pas exemple fournir des explications sur les coordonnées des widgets numéro 0 à numéro 4.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
# 1 - Importations import tkinter as tk import random as rd # 2 - Déclaration des constantes C_LAB = "#FF7777" # Couleur des widgets C_FND = "#000000" # Couleur de fond # 3 - Déclaration des fonctions def creation_interface(titre, couleur): '''Crée et renvoie la référence d'interface graphique :: param titre(str) :: le titre visible dans la barre de l'application :: param couleur(str) :: une couleur de fond valide pour l'application :: return (tk.Tk) :: la référence Tkinter de l'application ''' fe = tk.Tk() fe.geometry("600x300") fe.title(titre) fe.configure(bg=couleur) return fe # 4 - Programme # 4-1 - Création et configuration de la fenêtre du logiciel fenetre = creation_interface("Le For et Tkinter", C_FND) # 4-2 - Création-configuration des Labels et affichage for i in range(0, 9, 1): zone = tk.Label(fenetre, text=i, width=5, height=3) zone.place(x=20+60*(i//3), y=20+60*(i%3)) # 4-3 - Création-configuration d'un Label et affichage # 4-4 - Surveillance des événements fenetre.mainloop()

TK 04° Fournir les trois lignes permettant de passer à ceci :

3 - FAQ

J'ai vu un code bizarre une variable... bizarre aussi. C'est quoi ?

Le code ressemble peut-être à ceci, avec une variable de boucle limité à un underscore :

1 2 3 4 5
def polygone(feutre, nbr, longueur): '''Crée un polygone à nbr cotés ayant chacun la longueur voulue.''' angle = 360 // nbr for _ in range(nbr): avance_et_tourne(feutre, longueur, angle)

C'est juste une notation qui permet en gros de dire : "La variable de boucle n'a aucune importance : on fait X fois la même chose"

Remplacez ce nom de variable de boucle par choucroute et ca marchera toujours aussi bien. Du coup, certains aiment bien mettre un underscore dans ce cas. Pourquoi pas ?

Il est temps de passer aux instructions conditionnelles.

Activité publiée le 13 11 2021
Dernière modification : 13 11 2021
Auteur : ows. h.