TD: Listes en Python

Introduction

(L'introduction est la même pour tous les TDs)

Ce TD présente des exercices de difficultés progressives.
Pour chaque exercice, lire l'énoncé, puis copier/coller le programme (le contenu du cadre) dans un éditeur Python, par exemple spyder, thonny, ou un éditeur en ligne comme repl.it.

Certains exercices demandent simplement de "lire et exécuter" le programme, il n'y a donc rien à programmer vous-même (il faut juste comprendre les explications, en général c'est une aide pour les questions suivantes). Les autres exercices vous demandent d'"écrire" une fonction ou un programme, il faut alors modifier ce que vous avez collé dans l'éditeur pour répondre à la question. (Attention, il ne faut pas coller le programme dans la partie "console" de l'éditeur, sinon vous ne pourrez pas facilement le modifier.)

Lorsqu'un exercice est fini, passer au suivant. Vous pouvez effacer l'ancien programme pour coller le nouveau, ou alors mettre le nouveau à la suite du précédent (dans ce cas bien sûr l'ancien programme continuera d'afficher du texte lorsque vous exécutez le fichier). C'est surtout utile lorsque les questions s'enchaînent et que la nouvelle solution est basée sur l'ancienne. Vous pouvez aussi ouvrir un deuxième fichier dans l'éditeur (ou avoir un fichier pour conserver toutes vos anciennes solutions).

Beaucoup d'exercices ont des "indications", c'est à dire de l'aide. Essayer toujours d'abord de faire l'exercice sans les lire.

Conseils généraux pour tous les exercices:

Exercice 1 : affiche_liste

Lire et exécuter ce programme.

Il fonctionne en deux étapes:

1) D'abord, une fonction 'affiche_liste' est définie (avec l'instruction 'def'). Elle reçoit un argument, L, puis commence une boucle 'for' qui répète des instructions 'len(L)' fois. L'expression 'len(L)' est égale à la longueur de la liste L, donc si la liste a 5 éléments (par exemple si L est égale à [0,2,4,6,8]), il y a 5 tours de boucle. Les instructions répétées sont 'print(L[a])' et 'a=a+1'. La première fois, a est égal à 0, donc le programme exécute print(L[0]). Puis à chaque tour de boucle, a est augmenté de 1 (le programme exécute donc print(L[1]), puis print(L[2]) etc). Au final, chaque élément est bien affiché.

2) L'étape précédente définie la fonction (avec 'def'), mais ne la lance pas. Ce sont les deux lignes après la définition ('affiche_liste([0,2,4,6,8])' et 'affiche_liste([12,9,9])') qui lancent la fonction, en donnant à chaque fois une valeur pour L (la première fois, la fonction est lancée avec L égale à [0,2,4,6,8], la deuxième fois avec L égale à [12,3,8,7,9,9,9,0]).

Remarquer aussi que cette fonction n'a pas de 'return': en effet, elle affiche du texte mais n'a pas de résultat.
def affiche_liste(L):
    """Affiche les éléments un par un"""
    a= 0
    for i in range(len(L)):
        print(L[a])
        a= a+1

affiche_liste([0,2,4,6,8])
affiche_liste([12,9,9])

print("Exercice réussi: affiche_liste")

Exercice 2 : affiche_liste_bis

Lire et exécuter ce programme.

Ce programme est identique au précédent, mais l'instruction 'print' a été remplacée par la fonction 'printbis', qui est définie au début du programme. La fonction 'printbis' affiche son argument, puis ajoute le texte à la variable 'affichage' en revenant à la ligne. Ceci permet de tester l'affichage du programme avec un 'assert' (vous n'avez pas besoin de comprendre la la fonction printbis pour faire les exercices). Remarquer que le 'assert' tient sur plusieurs lignes, car il compare la variable 'affichage' à une chaîne de caractères sur plusieurs lignes (en utilisant des triples guillemets).

1) Lancer le programme et vérifier qu'il affiche bien que l'exercice est réussi.

2) Taper 'print(affichage)' dans la console APRES avoir lancé le programme. Vérifier que ceci correspond bien à l'affichage de la fonction.
affichage= ""
def printbis(x):
    global affichage
    print(x)
    affichage= affichage + "\n" + str(x)

def affiche_liste_bis(L):
    """Affiche les éléments un par un avec printbis"""
    a= 0
    for i in range(len(L)):
        printbis(L[a])
        a= a+1

affiche_liste_bis([0,2,4,6,8])
assert affichage == """
0
2
4
6
8"""
affichage= ""
affiche_liste_bis([12,9,9])
assert affichage == """
12
9
9"""

print("Exercice réussi: affiche_liste_bis")

Exercice 3 : affiche_triple_liste

Écrire maintenant la affiche_triple_liste, en utilisant la fonction printbis. Une version fausse de la fonction est donnée. Vous devez donc la corriger. Bien sûr, le but du jeu est de modifier la definition de la fonction, et PAS les 'assert' (les 'assert' sont des tests, qui permettent de vérifier si votre fonction est correcte).

(Une fois la fonction écrite, il faut bien sûr lancer le programme pour vérifier que le 'assert' fonctionne, et que le texte 'Exercice 6 réussi' s'affiche bien. Si vous lancez le programme sans le corriger, Python affiche une 'AssertionError' en indiquant la ligne qui du test qui n'a pas fonctionné)

Remarquer que, pour le deuxième test (assert affichage == "\n36\n27\n27"), au lieu d'utiliser une chaîne de caractères avec des retours à la lignes, on utilise le caractère spécial '\n', qui est interprété comme un retour à la ligne. Les triples guillemets ne sont donc plus nécessaires.

Indication (aide): La fonction déjà écrite est fausse, car elle n'affiche pas le triple de chaque élément. Que fait-elle? Quel nombre faut-il donc modifier dans la définition?
affichage= ""
def printbis(x):
    global affichage
    print(x)
    affichage= affichage + "\n" + str(x)

def affiche_triple_liste(L):
    """Affiche le triple de chaque élément"""
    a= 0
    for i in range(len(L)):
        printbis(2*L[a])
        a= a+1

affiche_triple_liste([0,2,4,6,8])
assert affichage == """
0
6
12
18
24"""
affichage= ""
affiche_triple_liste([12,9,9])
assert affichage == "\n36\n27\n27"

print("Exercice réussi: affiche_triple_liste")

Exercice 4 : carrés

Écrire la fonction carrés, en utilisant la fonction printbis. Bien lire la description à l'interieur de la fonction. Il faut à nouveau compléter la fonction, en s'inspirant des questions précédentes (donc ici il faut écrire la ligne manquante avant le 'a=a+1').

Attention, ne pas oublier d'utiliser printbis à la place de print. Sinon votre fonction affichera le bon texte, mais la variable 'affichage' restera vide, et donc les 'assert' ne marcheront pas.

Rappel: Pour calculer le carré d'un nombre, par exemple n, on peut écrire n**2 (n puissance 2) ou simplement n*n.
affichage= ""
def printbis(x):
    global affichage
    print(x)
    affichage= affichage + "\n" + str(x)

def carrés(L):
    """Affiche le carré de chaque élément"""
    a= 0
    for i in range(len(L)):

        a= a+1

carrés([0,2,4,6,8])
assert affichage == "\n0\n4\n16\n36\n64"
affichage= ""
carrés([12,9,9])
assert affichage == "\n144\n81\n81"

print("Exercice réussi: carrés")

Exercice 5 : somme_liste

Lire et exécuter ce programme.

Remarquer que cette fonction n'affiche rien; elle retourne un résultat (avec l'instruction 'return').

Le but ici est de comprendre ce programme pour s'en inspirer dans les questions suivantes. Remarquer que la boucle 'fait quelque chose' pour chaque élément de la liste, mais ne retourne le résultat qu'après la boucle. Il faut donc que le programme puisse se souvenir de ces étapes. Ici, c'est la variable t (pour 'total') qui permet de s'en souvenir.

Remarquer aussi que somme_liste([]) == 0 est vrai. C'est parce que pour la liste '[]' (la liste vide), la variable t garde sa valeur initiale, égale à 0.
def somme_liste(L):
    """Retourne la somme de tous les éléments."""
    t= 0
    a= 0
    for i in range(len(L)):
        t= t + L[a]
        a= a + 1
    return t

assert somme_liste([1,2,3]) == 6
assert somme_liste([]) == 0
assert somme_liste([-3,1,2,3]) == 3
assert somme_liste([0,2,4,6,8]) == 20
assert somme_liste([12,9,9]) == 30


print("Exercice réussi: somme_liste")

Exercice 6 : somme_carrés

Écrire la fonction somme_carrés. Il faut à nouveau corriger la fonction donnée, qui est fausse.
def somme_carrés(L):
    """Retourne la somme des carrés de tous les éléments."""
    t= 0
    a= 0
    for i in range(len(L)):
        t= t + L[a]
        a= a + 1
    return t

assert somme_carrés([1,2,3]) == 14
assert somme_carrés([]) == 0
assert somme_carrés([-3,1,2,3]) == 23
assert somme_carrés([0,2,4,6,8]) == 120
assert somme_carrés([12,9,9]) == 306

print("Exercice réussi: somme_carrés")