Mission 1 — Créer le paquet
Représente une carte par (valeur, couleur), avec 2 à 14 pour la valeur, et quatre couleurs. Construis 52 cartes, mélange-les puis distribue deux files de 26 cartes. Vérifie qu'aucune carte n'est perdue ou dupliquée.
Cinq activités, deux structures, une nouvelle façon de résoudre des problèmes.
Tu hésites encore avec les listes ou les boucles ? Ce parcours fait partie du TP2. Commence par lire et modifier quelques lignes, puis construis une petite file d’attente. Pas de classes, pas de récursivité.
Étapes 1 à 6 : listes, parcours, fonctions et ajouts. Étapes 7 à 10 : piles, files et premier embarquement à PyLand. Avance à ton rythme, en une ou plusieurs séances.
Commencer les 10 petits exercices guidés →
Une consigne, un petit code, deux indices facultatifs et des essais ciblés à chaque étape. Les jeux ci-dessous sont des projets à choisir ensuite avec le professeur, pas une course à terminer tous les niveaux.
Observe la démo, fais une prédiction sur papier, puis écris ton algorithme avant d'ouvrir un indice. Les démonstrations sont des modèles à expliquer : ton programme Python reste à construire dans l’atelier en ligne ou dans ton IDE. Coche une mission seulement lorsque tu sais justifier et tester ton code.
Piles et assiettes · Files d’attente. Les petites ampoules ci-dessous donnent des explications à ouvrir seulement si nécessaire.
raise déclenche une exception : Python interrompt l’exécution normale et cherche un bloc except capable de la traiter. Sans traitement, le programme s’arrête avec un message d’erreur. Ce n’est ni un affichage (print), ni une valeur renvoyée (return).
def retirer(file):
if not file:
raise ValueError("La file est vide")
return file.pop(0)
try:
retirer([])
except ValueError as erreur:
print(erreur) # affiche La file est videDans les squelettes, raise NotImplementedError("Mission à compléter") est un repère volontaire. Remplace cette ligne par ton algorithme lorsque tu programmes la fonction. Le message ne signifie pas que Python est mal installé.
ValueError signale ici une opération refusée ; IndexError apparaît notamment avec un retrait invalide dans une liste. Respecte le contrat de chaque activité : dans PyLand, retirer d’une file vide renvoie None, tandis que la Bataille demande une exception.
Alice et Bob jouent la première carte de leur paquet. Le gagnant ajoute les cartes jouées à la fin du sien. Comment conserver cet ordre ?
Début à gauche → fin à droite. Les 8 prochaines cartes sont visibles ; les compteurs portent sur les files entières.
Une égalité laisse les cartes au centre. Chaque joueur pose une carte cachée, puis compare la suivante au prochain tour. On répète si nécessaire. Pour poursuivre, il faut donc au moins deux cartes chacun. Si un joueur ne peut pas continuer, celui qui conserve le plus de cartes gagne l'enjeu et la partie ; à égalité d'effectif, le résultat est nul. Le gagnant reçoit l'enjeu dans l'ordre où les cartes ont été déposées : Alice puis Bob à chaque dépôt.
La démo s'arrête après 1 000 comparaisons si nécessaire : certaines parties peuvent être très longues ou cycliques.
Représente une carte par (valeur, couleur), avec 2 à 14 pour la valeur, et quatre couleurs. Construis 52 cartes, mélange-les puis distribue deux files de 26 cartes. Vérifie qu'aucune carte n'est perdue ou dupliquée.
Complète enfiler, defiler et est_vide. Le début de liste contient la prochaine carte à jouer. Teste une file vide, une file d'un élément et plusieurs ajouts/retraits successifs.
Retire une carte de chaque file, compare leurs valeurs et ajoute l'enjeu chez le gagnant. Affiche le numéro du tour, les deux cartes, le gagnant du pli et les tailles des files. Vérifie que len(alice) + len(bob) + len(enjeu) == 52.
Applique la règle de la démo. L'enjeu doit survivre d'un tour au suivant. Fabrique un petit paquet de test qui force deux égalités consécutives, puis un cas où il manque des cartes.
Répète les tours jusqu'à ce qu'une file soit vide ou qu'un résultat terminal soit annoncé. Compte les tours et ajoute une limite de sécurité : une interruption n'est pas une victoire.
Une file suit l'ordre FIFO : First In, First Out. Le premier arrivé est le premier sorti. Avec une liste Python, retirer à l'indice 0 décale les éléments : coût linéaire. L'interface abstraite d'une file n'impose pas cette implémentation ; collections.deque permet des opérations aux extrémités en temps constant.
Lance 100 parties. Calcule la moyenne des tours des parties terminées, repère la plus longue et compte séparément les parties interrompues. Compare plusieurs mélanges.
Bienvenue à PyLand Adventure Park ! La nacelle part toutes les deux minutes. À toi de gérer les visiteurs, puis de vérifier si une plus grande capacité réduit réellement leur attente.
Après les files de cartes de la Bataille, une file de dictionnaires. Prérequis : listes, dictionnaires, fonctions, boucles. Aucun besoin d’écrire une classe. Revoir les files dans le cours.
Choisis les réglages, prédis le prochain groupe, puis avance d’un tour. Pour comparer, recommence avec une autre capacité : les arrivées restent identiques.
Les réglages sont figés après le premier tour. Limite pédagogique : 30 tours. Le navigateur simule en JavaScript ; ton programme Python est à construire dans l’atelier en ligne ou dans ton IDE.
Au début : V1 à V4 attendent depuis t = 0, avec une satisfaction de 75. Pour les suivants, 50 + (numero * 17) % 51 fournit une satisfaction initiale reproductible entre 50 et 100. Ces règles sont un modèle pédagogique choisi, pas une mesure réelle de satisfaction.
Attente = heure de départ − heure d’arrivée. Les deux minutes dans l’attraction ne sont pas de l’attente. Les moyennes portent sur les 20 premiers visiteurs sortis, pas ceux qui restent dans la file. Avant 20 sorties, elles sont provisoires.
Capacité 2, sans mascotte : qui embarque au premier tour ? Au deuxième ? Combien de minutes V5 aura-t-il attendu à son départ ? Écris ta trace avant d’appuyer sur le bouton.
Complète creer_visiteur(nom, arrivee, satisfaction). Il renvoie un dictionnaire avec ces trois clés. Crée deux visiteurs indépendants : modifier l’un ne doit pas modifier l’autre.
Implémente ajouter_visiteur et retirer_visiteur avec une liste. Ajout en fin ; retrait et retour du plus ancien. Notre contrat : retirer d’une file vide renvoie None. Teste A, B, C : ils doivent sortir dans cet ordre.
Complète embarquer(file, capacite, heure). Renvoie la liste des passagers et ajoute à chacun la clé attente. Vérifie les cas 0, 1, 2 et 3 visiteurs pour une capacité de 2. Ne saute pas de visiteur et ne retire personne deux fois.
Complète mettre_a_jour(file, passagers) : −5 pour la file, +10 pour les passagers. Teste les frontières : 3 devient 0 après l’attente et 95 devient 100 après l’attraction. Le déroulement des tours est déjà fourni dans simuler.
Complète statistiques(sortis) : renvoyer (effectif, attente_moyenne, satisfaction_moyenne) sur les 20 premiers sortis. Sans sortie : (0, None, None). Compare ensuite 2 et 4 places sur 15 tours identiques, sans mascotte.
Au premier départ : V1 et V2, attente 0 minute. Au deuxième : V3 et V4, attente 2 minutes. V5 embarque à t = 4 : son attente vaut 4 minutes. Après le premier retour, V3 a 70 points et V1 en a 85. Reproduis ces résultats dans ton programme.
| Capacité | Sorties totales | Taille finale de la file | Attente des 20 premiers | Satisfaction des 20 premiers |
|---|---|---|---|---|
| 2 places | À mesurer | À mesurer | À mesurer | À mesurer |
| 4 places | À mesurer | À mesurer | À mesurer | À mesurer |
Sur ce scénario, 15 personnes arrivent tous les 5 tours. Combien de places offre une capacité de 2 pendant ce temps ? Pourquoi la file risque-t-elle de s’allonger ? Une moyenne calculée seulement sur les sortants représente-t-elle tous les visiteurs ?
deque et pop(0) par popleft(). Garde les mêmes contrats. Explique pourquoi retirer en tête d’une liste est en O(n), contrairement à deque.random.Random(42), des arrivées entre 1 et 5 et des satisfactions entre 50 et 100. Génère le scénario avant les deux essais pour conserver exactement les mêmes entrées. Ce sera un autre scénario que celui de la démo.À rendre : ton programme sans classes, les résultats des tests, la trace des trois premiers tours, le tableau des deux essais et une conclusion distinguant attente, satisfaction et personnes encore dans la file.
Observe ce qui arrive aux différentes cases du serpent lorsqu'il avance. Quelle structure de données étudiée pourrait modéliser ce comportement ? Justifie ta réponse avant de coder.
Coordonnées (ligne, colonne), de 0 à 9. La liste est affichée dans l'ordre queue → tête.
Le scénario pomme repart de la même position et place une pomme juste devant la tête : prédis la liste, puis avance d'un pas. La démo va vers la droite jusqu'au mur ; le squelette Python permet de tourner.
Pars de [(5, 3), (5, 4), (5, 5), (5, 6)]. Écris la liste attendue après deux déplacements à droite, puis après un déplacement avec une pomme. Identifie l'élément le plus ancien.
Écris nouvelle_tete(serpent, direction). La direction est un tuple : haut (-1, 0), droite (0, 1), bas (1, 0), gauche (0, -1). Teste les quatre directions sans modifier le serpent.
Complète deplacer(serpent, tete, grandit). Sans pomme, la longueur doit rester constante. Avec une pomme, elle augmente de un. Distingue bien calculer une tête et modifier le corps.
Construis les coordonnées libres, puis choisis-en une au hasard. Une pomme ne doit jamais apparaître sur le serpent. Que renvoyer si toutes les cases sont occupées ? Le contrat prévoit None.
Écris collision(serpent, tete, grandit). Teste les quatre murs, un contact avec le corps et le déplacement vers la case de la queue lorsque celle-ci va disparaître. Ensuite seulement, lance le jeu complet.
Teste la collision avant de modifier le corps. Sans croissance, la queue libère sa case : elle ne constitue donc plus un obstacle au prochain état.
Les cases du corps suivent l'ordre FIFO : une nouvelle position entre côté tête, la plus ancienne sort côté queue. Le corps se modélise donc par une file. Manger suspend un retrait, ce qui augmente sa longueur. Les tests de collision demandent aussi de consulter les positions du corps.
Ajoute un score, une vitesse progressive, des obstacles ou la téléportation sur les bords. Puis un meilleur score local, ou un mode deux joueurs. Définis les règles avant de modifier le programme.
Une fonction est récursive lorsqu’elle s’appelle elle-même pour traiter un problème plus petit. Il faut un cas d’arrêt et s’en rapprocher à chaque appel.
def compte_a_rebours(n):
# Précondition : n est un entier positif ou nul.
if n == 0:
print("Départ !")
return
print(n)
compte_a_rebours(n - 1)
compte_a_rebours(3) # affiche 3, 2, 1, puis Départ !Trace : appel avec 3 → 2 → 1 → 0 ; puis les appels se terminent dans l’ordre inverse. Les appels en attente forment une pile. Sans arrêt, ou sans diminution de n, les appels finissent par provoquer une erreur RecursionError.
Pour Hanoï, résoudre avec n disques se ramène à déplacer n−1 disques, déplacer le plus grand, puis déplacer à nouveau les n−1 petits. Commence par les déplacements manuels : la résolution récursive est un prolongement guidé, pas un prérequis.
Transfère tous les disques de A vers C. Un seul disque à la fois, et jamais un grand disque sur un plus petit.
Clique sur une tour de départ, puis sur une tour d'arrivée. Au clavier : Tab pour choisir, Entrée ou Espace pour sélectionner.
Représente les tours par A = [5, 4, 3, 2, 1], B = [], C = []. La fin de liste est le sommet. Quel disque est accessible ? Quel invariant doit vérifier chaque liste ?
Complète deplacer(depart, arrivee). Renvoie un booléen et refuse les déplacements interdits sans modifier les piles. Teste un départ vide, une arrivée vide, un grand disque sur un petit et la même tour choisie deux fois.
Résous le puzzle à trois disques et note tes déplacements. Combien en as-tu effectués ? Rejoue si nécessaire : peux-tu faire mieux ? Reproduis ta séquence avec des appels à deplacer en Python.
Pour déplacer le plus grand disque, où doivent se trouver les autres ? Décompose le problème en déplacements de n-1 disques, puis complète hanoi(n, depart, intermediaire, arrivee). Quel est le cas de base ?
Une pile est LIFO : Last In, First Out. Seul son sommet est directement accessible. Les tours sont des piles de disques ; l'exécution récursive utilise aussi une pile d'appels, qui mémorise les appels suspendus avant d'y revenir.
Relève le minimum pour 1, 2, 3, 4 disques. Explique la relation M(n) = 2*M(n-1) + 1 avec M(0) = 0, puis conjecture une formule.
Le minimum est 2**n - 1. Peux-tu justifier cette formule par récurrence ?
Une matrice, une entrée, une sortie. Explore sans tourner en rond, puis compare deux stratégies avec exactement les mêmes voisins.
# mur · . passage · S départ · E sortie. Coordonnées : (ligne, colonne).
Voisins ajoutés dans l'ordre haut, gauche, bas, droite. Pour la pile, le sommet est à droite ; pour la file, le prochain retrait est à gauche.
Termine une exploration avec chaque structure pour comparer les résultats.
###########
#S..#.....#
#.#.#.###.#
#.#...#...#
#.#####.#E#
#.........#
###########Écris voisins(case, labyrinthe) : quatre directions, dans les bornes et sans mur. Départ et sortie sont accessibles. Teste un couloir, une intersection, une impasse et une case au bord.
Place le départ dans la pile. Retire une case, visite-la, puis ajoute ses voisins encore inconnus. Marque une case dès son ajout pour éviter de l'ajouter plusieurs fois. Prédis trois étapes avant de lancer la démo.
C'est un parcours en profondeur, ou DFS (Depth-First Search). Le dernier voisin ajouté est exploré en premier ; on s'enfonce dans une branche avant de revenir aux autres cases en attente.
Reprends le même algorithme, les mêmes voisins et le même marquage. Change uniquement la façon de retirer la prochaine case. Compare l'ordre obtenu avec celui de la pile.
C'est un parcours en largeur, ou BFS (Breadth-First Search). On explore les cases par distance croissante depuis le départ, déplacement par déplacement.
Les deux méthodes trouvent-elles la sortie ? Explorent-elles dans le même ordre ? Trouvent-elles nécessairement le même chemin ? Laquelle garantit un nombre minimal de déplacements dans ce labyrinthe non pondéré ? Appuie ta réponse sur la démo, puis sur une propriété de la structure.
Mémorise le prédécesseur de chaque case au moment de sa découverte. Depuis la sortie, remonte ces liens jusqu'au départ et inverse le résultat. Teste aussi une sortie inaccessible.
La liste des cases visitées n'est pas forcément un chemin : deux visites consécutives peuvent être éloignées. Un chemin suit des cases voisines. Dans un graphe pondéré, BFS ne garantit pas un coût total minimal.
Chaque case accessible est un sommet. Deux cases voisines sont reliées par une arête. Un déplacement coûte toujours une unité ici. Si la sortie est accessible, les deux explorations la trouvent ; l'ordre des voisins influence leurs traces et peut départager plusieurs chemins de même longueur.
Modifie la matrice, ajoute une impasse, rends la sortie inaccessible, puis compare les cases explorées. Programme une course DFS/BFS ou un générateur de labyrinthes.