TP2 - Séquences range / list / tuple - itérations avec boucle for
Note : voir vos notes de cours, le TD2, le poly du cours chapitre IV, le mémento (Instruction Boucle Itérative, Séquences d’Entiers, Opérations Génériques sur Conteneurs, Opérations sur Listes).
La partie découverte interactive comporte des questions ou modifcations à apporter . Lorsque vous fait le travail, appelez votre enseignant pour qu’il vérife.
1 - Boucle for et séquences d’entiers
Qelle est la fonction qui permet de connaître le nombre d’éléments d’une séquence (chaîne de caractères, liste, tuple, range…) ?
1.1 - Affichages de l’exécution d’une boucle Soit les lignes de programme ci-dessous, :
1. print("La boucle for va commencer...")
2. nb_passage = 0
3. for var in range(27,30):
4. print("Voici la valeur de l'itérateur : ", var)
5. nb_passage = nb_passage + 1
6. print("La boucle for est terminée !")
7. print("Il y a eu", nb_passage, "passages dans la boucle") Remplissez le tableau de suivi ci-dessous pour pouvoir répondre aux questions :
• Qelles valeurs de la variable itérateur var vont être afchées ?
• Combien de fois va-t-on passer dans la boucle ?
n° ligne : nb_passage var Afchage à l'écran :
Ouvrez le fchier TP2_bouclefor.py, qui contient ce programme, et exécutez-le : 1.2 - Exécution en débuging pas à pas d’une boucle
Dans un nouveau fchier module Python, saisissez le script de l’exercice 2 du TD2 :
1. nb = int(input("Entrez un nb strictement positif:"))
2. cpt = 0
3. for i in range(nb+1):
4. if i%2==0 and i%5==0:
5. cpt = cpt + 1 print("j'ai compté", cpt)
Avec Pyzo, placez un point d’arrêt sur la ligne 1, en cliquant sur la colonne grise à droite de la colonne des n° de ligne (cela place un point rouge indiquant le point d’arrêt).
Lancez l’exécution (F5). Dans l’outil Shells, vous devriez voir s’afcher :
>>> (executing file "<tmp 1>") (<module>)>>>
Vous êtes alors en mode débugage, le nouveau prompt (<module>)>>> est celui pour entrer au clavier les commandes du debuger (mais nous allons plutôt utiliser l’interface graphique pour piloter le debuger). L’exécution s’est mise en pause sur le point d’arrêt que vous avez placé.
Ouvrez l’outil Workspace s’il n’est pas déjà actif.
En utilisant la commande menu Shell → Débugage pas à pas principal (next) (ou dans l’outil Shells l’icône ), exécutez le script en pas à pas (chaque clic sur cete commande provoque l’exécution de la ligne suivante du script).
Les afchages et saisies se font toujours normalement dans la zone de l’outil Shells. À l’afchage de la question :
Entrez un nb strictement positif:
⇒ Saisissez la valeur : 10
Continuez en utilisant plusieurs fois la même commande de débugage pas à pas.
Remarquez le tiret vert afché en face de la prochaine ligne à exécuter.
Observez dans l’outil Workspace l’évolution des variables suivant les lignes qui sont exécutées dans la fenêtre du script.
Une fois que la dernière ligne du programme a été exécutée et a afché :
j'ai compté 2 --Return--
Cliquez sur la commande Shell → Arrêter le débugage (ou icône ) pour stopper (sinon vous allez continuer en débogant Pyzo… vous verrez s’afcher un script « channels_pubsub.py »).
Utilisez l’exécution en mode débogage pour vérifer un des tableaux de suivi faits en TD pour cet exercice.
1.1 - Séquences d’entiers avec range
Comme vous pouvez le voir, dès que l’on a besoin de faire une boucle for un nombre connu de fois, ou bien pour parcourir des séquences d’entiers avec un pas entre deux bornes, on utilise range(). Dans le shell Python, saisissez et exécutez les instructions suivantes, et comparez avec le dernier exercice du TP1 :
range(-10,11,7)
On va passer par une conversion en liste pour afcher les valeurs générées par range : list(range(-10,11,7))
list(range(-10, -21, -3)) list(range(11))
list(range(2,11,2)) list(range(5,50,5)) list(range(0,20,3))
[x/100 for x in range(0,20,3)]
A retenir, la valeur de fn du range() n’est pas inclue dans les valeurs générées par celui-ci.
La dernière notation crée une liste en compréhension (voir poly de cours page 33), en utilisant une boucle for directement dans l’expression de construction de liste.
1.2 - Contrôle de la variable de boucle Saisissez et exécutez le script suivant :
1. for i in range(5):
2. print("i début", i)
3. i = i + 100
4. print("i fin", i)
Observez les valeurs de la variable de boucle i.
Notez que Python vous protège en efectuant lui-même l’afectation de la variable de boucle à partir de la séquence parcourue et en ignorant les modifcations qui ont pu être apportées à cete variable. Mais ce n’est pas le cas avec d’autres langages. Pour prendre de bonnes habitudes nous vous demandons de ne pas modifer les variables de boucle et considérerons désormais que c’est une erreur. Si besoin, utilisez une autre variable dont la valeur est construite à partir de la variable de boucle.
2 - Boucles for imbriquées
Ouvrez le fchier TP2_forimbriques.py qui contient le programme suivant :
1. for a in range(2,8,2):
2. print("premier niveau, a =",a)
3. for b in range(1,4):
4. print(" second niveau, a =", a, "et b =", b)
5. for c in range(70, 80, 5):
6. print(" troisième niveau, a =", a, ", b =", b, "et c =", c)
7. print(" fin troisième niveau")
8. print(" fin second niveau")
9. print("fin premier niveau")
Qelles sont les valeurs qui seront générées par le range de la boucle pour a ?
Qelles sont les valeurs qui seront générées par le range de la boucle pour b ?
Qelles sont les valeurs qui seront générées par le range de la boucle pour c ?
Exécutez le script une première fois et observez les niveaux de boucles, les évolutions des variables de boucles (et donc les cycles efectués sur chaque variable).
Ajoutez un compteur permetant de savoir combien de fois au total est exécuté le corps de la boucle de troisième niveau, et afchez-le à la fn du programme après l’exécution des boucles.
3 - Parcours sur valeur / sur index / sur index et valeur
Testez le script suivant (ouvrez le fchier TP2_forvalindex.py) :
1. lst = ["maxime Duschmoll", "joe Amar", "amhad du Puy", "heinrich Yang"]
2. print("=== Parcours valeurs:")
3. for v in lst:
4. print(v, v.upper())
5.
6. print("\n=== Parcours index:")
7. for i in range(len(lst)):
8. nom = lst[i]
9. print(i, nom, nom.lower())
10.
11. print("\n=== Parcours index et valeur en même temps:")
12. for j,n in enumerate(lst):
13. print(j, n, n.title())
Pour les questions suivantes, vous pouvez essayer de modifer et ré-exécuter le script pour tester vos
Comment peut-on faire pour parcourir les valeurs sauf la première (revoir le cours) ?
Comment peut-on faire pour parcourir les valeurs sauf la dernière (revoir le cours) ?
Dans le parcours sur les index, notez l’utilisation de range(len(séquence)) pour obtenir les index correspondant aux valeurs d’une séquence.
Comment peut-on faire pour parcourir les index sauf le premier ?
Comment peut-on faire pour parcourir les index sauf le dernier ?
Dans le parcours sur les index et valeur en même temps, notez l’utilisation directe de deux variables de boucle (la fonction générateur enumerate() produit en efet deux valeurs à chaque itération : l’index et la valeur).
Une erreur courante lors des parcours sur index consiste à oublier le range() ou de len() dans l’expression de boucle. Modifez et ré-exécutez le programme avec chacune de ces erreurs.
Qelle erreur est indiquée lorsqu’on oublie le range() ?
Qelle erreur est indiquée lorsqu’on oublie le len() ?
4 - Parcours sur plusieurs séquences
Une généralisation du parcours avec deux variables de boucles que l’on vient de voir avec la fonction générateur enumerate().
Testez le script suivant (ouvrez le fchier TP2_formultiseq.py) :
1. seq1 = range(5)
2. seq2 = ['t', 'u', 'v', 'w', 'x']
3. seq3 = [84, 156, 12, -87, 0]
4.
5. for a,b,c in zip(seq1, seq2, seq3):
6. print(a, b, c)
La fonction générateur zip() se charge de regrouper dans des tuples les éléments de même index de chaque séquence qu’on lui fournit. On peut donc faire une boucle dessus en utilisant l’afectation de plusieurs variables dans le cadre de la boucle for (on aurait pu écrire une boucle for t in zip(…):
puis dans le corps de la boucle commencer par a,b,c=t pour décapsuler les trois valeurs du tuple).
Dans l’exemple les trois séquences ont le même nombre d’éléments (5).
Qe se passe-t-il si on supprime un élément de seq2, qui deviens alors plus petite que les deux autres séquences (modifez le script et testez) ?
5 - Construction de liste dans une boucle
Nous allons voir des opérations très courantes avec les boucles for pour construire des listes de valeurs issues de calculs… et en profter pour voir comment tracer facilement des courbes à partir de telles listes.
Testez le script suivant (ouvrez le fchier TP2_fabricliste.py) :
1. from math import log, sin
2. import matplotlib.pyplot as plt
3.
4. # Paramètres de construction de listes de valeurs:
5. debut = 0.5
6. pas = 0.04
7. fin = 12.0
8.
9. nbpoints = int((fin - debut) / pas)
10. print("Nombre de points:", nbpoints)
11.
12. # Construction de la liste des x:
13. lstx = []
14. val = debut
15. for i in range(nbpoints):
16. lstx.append(val)
17. val = val + pas
18. print("Liste des X ok", lstx[:5], "...") # on n'affiche pas tout=>lstx[:5]
19.
20. # Construction de la liste des y = f(x):
21. lsty = []
22. for x in lstx:
23. # Pour la fonction de calcul, adapter suivant les besoins…
24. y = 3*sin(x)**log(x)
25. lsty.append(y)
26. print("Liste des Y ok", lsty[:5], "...") # on n'affiche pas tout=>lsty[:5]
27.
28. plt.plot(lstx, lsty)
29. plt.xlabel('x (angle)')
30. plt.ylabel('y (calcul)')
31. plt.title('Un petit exemple de courbe')
32. plt.grid(True)
33. plt.show()
Notez comment est construite la liste des abscisses avec des nombres fotants pour les valeurs de début / fn / pas (pour des nombres entiers, on peut utiliser range(), pas pour des fotants). Puis comment la liste des ordonnées est construite à partir de la liste des abscisses. Retenez la méthode append() des listes, qui permet d’ajouter un nouvel élément à une liste.
Modifez ce script pour afcher sin(x) pour x entre 0 et 2π avec un pas de 0.01.
6 - Travail personnel à rendre
6.1 - Sapin
Créez un fchier TP2sapin.py.
En utilisant l'opérateur * de duplication des chaînes de caractères combiné à une boucle for, créez un programme qui demande à l'utilisateur quel nombre de lignes de sapin il désire, puis dessine un sapin comportant autant de lignes. Par exemple, pour 5 lignes, le programme afchera :
^ ^^^
^^^^^
^^^^^^^
^^^^^^^^^
6.2 - Recherche de mots
Créez un fchier TP2comptele.py pour cet exercice à rendre.
Pour rappel, la méthode split() des chaînes, utilisée sans paramètre, découpe une chaîne en une liste de chaînes en séparant sur les caractères « blancs » (espace, tabulation, retour à la ligne…). Testez par exemple l’expression "Une phrase de plusieurs mots, pour voir.".split() dans le shell Python pour observer le résultat.
Faites saisir à l’utilisateur une phrase, sans ponctuation, stockez-la en minuscules dans un chaîne s. Écrivez une boucle sur les mots de cete phrase, qui compte le nombre d’occurrences du mot "le" (on interdit d’utiliser la méthode count(), l’algorithme devra faire un test explicite de comparaison sur chaque mot). Testez l’algorithme avec plusieurs phrases permetant de compter 0, 1, 2 et plus mots "le".
Ajoutez à votre code, dans la même boucle, le remplissage d’une liste positions avec les index des mots "le" trouvés dans les mots de la phrase, re-testez avec les diférents cas en afchant cete liste d’index.
Note : pour tester les diférents cas, vous êtes autorisé à remplacer la saisie utilisateur par une boucle sur une liste de cas à tester — pour autant que vous sachiez imbriquer votre algorithme dans cete première boucle.
6.3 - Combinaisons Créez un fchier TP2combine.py. À partir des deux listes suivantes :
vehicules = ["train", "bus", "voiture", "vélo"]
couleurs = ["rouge", "vert", "bleu", "jaune"]
Créez de façon automatique une liste lst contenant des chaînes avec toutes les combinaisons de véhicule et couleur : ["train rouge","train vert",… "vélo jaune"].
Modifez le script pour que la combinaison "voiture vert" ne soit pas ajoutée à la liste lst lors de sa construction.
6.4 - Combinaisons génétiques
Reprenez le fchier TP2gene.py fourni (et à modifer) pour cet exercice à rendre.
Le code déjà en place fabrique une liste seq contenant 100000 chaînes de 3 caractères chacune, qui sont des combinaisons avec les letres AGCT.
À la suite du code en place, écrivez un programme qui compte combien de fois on trouve dans la liste seq une chaîne "ATG" avec à l'index immédiatement suivant une chaîne "GCA".
6.5 - Tirages loto Créez un fchier TP2loto.py.
Le module random comporte une fonction randrange() qui tire un nombre entier aléatoire issu d'une séquence d'un générateur range(). Pour l'utiliser, faites simplement :
from random import randrange
Faites quelques essais avec randrange() dans le shell Python.
Le type list comporte une méthode pop() permetant d'extraire une valeur d'une liste et de la retourner (voir les informations dans le cours, le mémento et faites vos tests personnels dans le shell Python).
Dans le script, simulez un tirage de loto, de 5 numéros + un complémentaire, parmi une collection de 49 numéros (de 1 à 49) où dans un tirage chaque numéro ne peut sortir qu'une seule fois. À chaque lancement du script, afchez un nouveau tirage.
6.6 - Somme de Riemann
Vous avez réalisé une approximation de l'intégration de la courbe
y=sin(x) entre 0.3 et 2.4 par l'algorithme de la somme de Riemann. Faites divers tests en modifant le pas sur x et afchez à chaque fois le pas et la valeur d'intégration obtenue (recopiez bien sûr ces diférents résultats à la suite du code dans une chaîne triple-guillemets).
6.7 - Détente avec turtle
Ouvrez le fchier TP2_turtle.py fourni, il sert de base pour découvrir le module turtle.
Le module Python turtle ofre une interface de programmation similaire au langage LOGO utilisé il y a longtemps pour l'enseignement dans les écoles primaires. Il permet de contrôler une « tortue », représentée à l'écran par une pointe de fèche orientée dans une direction, que l'on peut faire tourner,
ou avancer. La tortue a deux états, un état bas où elle laisse des traces lors de ses déplacements, et un état haut où elle se déplace sans laisser de trace. Voici la description rapide de quelques fonctions que nous utiliserons :
• up() lève la tortue (ne laisse plus de trace lors des déplacements)
• down() baisse la tortue (laisse des traces lors des déplacements)
• forward(n) avance la tortue de n pixels
• left(a) tourne la tortue à gauche d'un angle de a degrés
• right(a) tourne la tortue à droite d'un angle de a degrés
• reset() réinitialise la zone de tracé et replace la tortue au centre
• speed(n) fxe la vitesse de la tortue (de n=1 pour lent à n=10 pour rapide, avec un défaut normal de 6
Il existe d'autres fonctions dans ce module, voir htps://docs.python.org/3.4/library/turtle.html
Créez un fchier TP2detente.py. À l'aide du module turtle et d'une boucle, écrivez dans le fchier les instructions permetant de reproduire un dessin similaire à celui ci-dessous :