diff --git a/Projet/Readme.md b/Projet/Readme.md
index ea174b9bc41d171ec2e2740ee9336082f5a0e5f3..c33b23bd0408d4821f78a512d0807df99c1acd09 100644
--- a/Projet/Readme.md
+++ b/Projet/Readme.md
@@ -40,6 +40,30 @@ Si le bloc n'est pas uniforme, l'image sera divisée en quatre sous-blocs égaux
 
 Enfin, l'image créée est retournée par la fonction.
 
+-# Cette fonction est définie dans une classe et s'appelle "image_recursive". Elle prend un argument "ordre" en entrée:
+Si l'ordre est supérieur à zéro :
+
+    Diviser l'image en quatre sous-blocs en utilisant la méthode "diviser_en_quatre".
+    Pour chaque sous-bloc, appeler récursivement la fonction "image_recursive" en passant l'ordre - 1.
+    Vérifier si tous les sous-blocs sont proches en utilisant la méthode "blocs_proches".
+    Si tous les sous-blocs sont proches, définir la couleur de l'image comme la couleur moyenne en utilisant la méthode "couleur_moyenne" et vider la liste "sous_blocs".
+    Sinon, modifier la couleur de l'image en utilisant la méthode "modife_couleur".
+    
+et enfin voici l'explication pour manipuler l'image :
+image = Image.open('calbuth.png') : Cette ligne ouvre l'image PNG nommée "calbuth.png" et l'assigne à une variable nommée image.
+
+image_rgb = image.convert('RGB') : Cette ligne convertit l'image en mode de couleur RGB (Rouge, Vert, Bleu) et l'assigne à une variable nommée image_rgb.
+
+bloc_initial = Bloc(image_rgb, (0, 0,0), (image_rgb.width, image_rgb.height)) : Cette ligne crée un nouvel objet Bloc avec l'image RGB en argument, ainsi que des arguments optionnels pour la couleur initiale (0, 0, 0) qui correspond au noir, et les dimensions de l'image (largeur et hauteur).
+
+bloc_initial.image_recursive(1) : Cette ligne appelle la méthode image_recursive sur l'objet bloc_initial avec un argument de 1. Cette méthode semble être une fonction de segmentation d'image qui divise l'image en sous-blocs et répète le processus jusqu'à ce que tous les sous-blocs soient proches en termes de couleur.
+
+image_finale = bloc_initial.creer_image() : Cette ligne crée une nouvelle image à partir de l'objet bloc_initial et l'assigne à une variable nommée image_finale.
+
+image_finale.show() : Cette ligne affiche l'image finale dans une fenêtre.
+
+
+
 
 # documentation
 06/03: # importation des bibliotheques necessaires pou rmanipuler les images
@@ -65,3 +89,6 @@ _# utilisation de la methode blocs_proches qui verifie si deux blocs sont proche
 
 _#utilisation de la methode creer_image pour creer une image de la meme taille que le blocs
 
+-# Creation de l'algorithme nommé image recursive qui prend en parametre un ordre et self
+-# quelque fonctionnalite pour manipuler l'image
+
diff --git a/Projet/src/calbuth.png b/Projet/src/calbuth.png
new file mode 100644
index 0000000000000000000000000000000000000000..52cddb60956a9906dfa71ed6d0f4b3065c803e32
Binary files /dev/null and b/Projet/src/calbuth.png differ
diff --git a/Projet/src/projet.py b/Projet/src/projet.py
index 5b8f8b249cc9e99e6f718eb1e93429313e3ab577..b0cbbb795fd71a32ac560886bf7067a921f02827 100644
--- a/Projet/src/projet.py
+++ b/Projet/src/projet.py
@@ -1,4 +1,3 @@
-#importation des bibliotheques necessaires pourmanipuler les images
 from PIL import Image, ImageDraw
 
 # Creation de la classe Bloc et ses differentes methodes
@@ -156,5 +155,35 @@ class Bloc:
 
         return image
 
+    
+    def image_recursive(self, ordre):
+        """Implémentation de l'algo
+
+        Précondition :
+        Exemple(s) :
+        $$$
 
-    
\ No newline at end of file
+        """
+        
+        if ordre > 0:
+            self.sous_blocs = self.diviser_en_quatre()
+            for sous_bloc in self.sous_blocs:
+                sous_bloc.image_recursive(ordre - 1)
+            if all(self.blocs_proches(sous_bloc) for sous_bloc in self.sous_blocs):
+                self.couleur = self.couleur_moyenne()
+                self.sous_blocs = []
+            else:
+                self.modife_couleur()
+        else:
+            self.couleur = self.couleur_moyenne()
+    
+    
+    
+    
+# manipulation de l'algo   
+image = Image.open('calbuth.png')
+image_rgb = image.convert('RGB')
+bloc_initial = Bloc(image_rgb, (0, 0,0), (image_rgb.width, image_rgb.height))
+bloc_initial.image_recursive(1)
+image_finale = bloc_initial.creer_image()
+image_finale.show()
diff --git a/TP3/Recursion/gestion_promo_etudiants.py b/TP3/Recursion/gestion_promo_etudiants.py
new file mode 100644
index 0000000000000000000000000000000000000000..aab0d20f7081957974c452c81a43fc34efa720f8
--- /dev/null
+++ b/TP3/Recursion/gestion_promo_etudiants.py
@@ -0,0 +1,142 @@
+from etudiant import Etudiant
+from date import Date
+#1 Préliminaire
+
+def pour_tous(seq_bool: list[bool]) -> bool:
+    """
+    Renvoie True ssi `seq_bool` ne contient pas False
+
+    Exemples:
+
+    $$$ pour_tous([])
+    True
+    $$$ pour_tous([True, True, True])
+    True
+    $$$ pour_tous([True, False, True])
+    False
+    """
+    i=0
+    while i<len(seq_bool) and seq_bool[i]==True:
+        i=i+1
+    return i== len(seq_bool)
+
+def il_existe(seq_bool: list[bool]) -> bool:
+    """
+
+    Renvoie True ssi seq_bool contient au moins une valeur True, False sinon
+
+    Exemples:
+
+    $$$ il_existe([])
+    False
+    $$$ il_existe([False, True, False])
+    True
+    $$$ il_existe([False, False])
+    False
+    """
+    i=0
+    while i<len(seq_bool) and seq_bool[i]==False:
+        i=i+1
+    if i<len(seq_bool):
+        res=True
+    else:
+        res=False
+    return res
+
+
+def charge_fichier_etudiants(fname: str) -> list[Etudiant]:
+    """
+    Renvoie la liste des étudiants présents dans le fichier dont
+    le nom est donné en paramètre.
+
+    précondition: le fichier est du bon format.
+    """
+    res = []
+    with open(fname, 'r') as fin:
+        fin.readline()
+        ligne = fin.readline()
+        while ligne != '':
+            nip, nom, prenom, naissance, formation, groupe = ligne.strip().split(';')
+            y, m, d = naissance.split('-')
+            date_naiss = Date(int(d.lstrip('0')), int(m.lstrip('0')), int(y))
+            res.append(Etudiant(nip, nom, prenom, date_naiss, formation, groupe))
+            ligne = fin.readline()
+    return res
+
+
+L_ETUDIANTS = charge_fichier_etudiants("etudiants.csv")
+COURTE_LISTE = L_ETUDIANTS[:10]
+
+def est_liste_d_etudiants(x) -> bool:
+    """
+    Renvoie True si ``x`` est une liste de d'étudiant, False dans le cas contraire.
+
+    Précondition: aucune
+
+    Exemples:
+
+    $$$ est_liste_d_etudiants(COURTE_LISTE)
+    True
+    $$$ est_liste_d_etudiants("Timoleon")
+    False
+    $$$ est_liste_d_etudiants([('12345678', 'Calbuth', 'Raymond', 'Danse', '12') ])
+    False
+    """
+    return all(isinstance(i,Etudiant) for i in x)
+
+#Gestion de la promotion
+
+#Q4-NBRE_ETUDIANTS=603
+#Q5-NIP=42325167
+#l'étudiant se trouvant s'appelle Le Roux Céline
+#Q6-
+L_moins_vingt_ans=[L_ETUDIANTS[i] for i in range(0,len(L_ETUDIANTS)) if Date(2,2,2004)<L_ETUDIANTS[i].naissance]
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/TP5/minesweeper/minesweeper.py b/TP5/minesweeper/minesweeper.py
index 9caa1020eb922a3dfb0b3c115d7eecb6f44a3e68..4b776c47bafebc8d00800d9522b6493bca2cf64e 100644
--- a/TP5/minesweeper/minesweeper.py
+++ b/TP5/minesweeper/minesweeper.py
@@ -186,7 +186,15 @@ class Minesweeper():
         précondition: none
 
         """
-        ...
+        res=True
+        for i in range(self.width):
+            for j in range(self.height):
+                cell=self.grid[j][i]
+                if not (cell.is_revealed and cell.is_bomb):
+                    res=False
+        return res
+
+
 
     def reveal_all_cells_from(self, x, y):
         """
@@ -224,14 +232,7 @@ class Minesweeper():
         $$$ game.state
         GameState.losing
         """
-        res=True
-        for i in range(self.width):
-            for j in range(self.height):
-                cell=self.grid[j][i]
-                if not (cell.is_revealed and cell.is_bomb):
-                    res=False
-        return res
-
+        
 
 
 if (__name__ == '__main__'):
diff --git a/TP6/associations/dicotrie.py b/TP6/associations/dicotrie.py
old mode 100644
new mode 100755
index 4c693433d5a13a3104891f77312cdd62d6a1a7df..a5e037954aa2bf5e9fad0deb1644817e06b02640
--- a/TP6/associations/dicotrie.py
+++ b/TP6/associations/dicotrie.py
@@ -23,7 +23,7 @@ class DicoTrie:
     def __init__(self, liste_assos: list[Association]):
         """
         """
-        ...
+        self.liste_assos = liste_assos
 
     def __repr__(self) -> str:
         """
@@ -34,7 +34,9 @@ class DicoTrie:
         $$$ repr(DicoTrie([Association('c', 3), Association('a', 2), Association('b', 1)]))
         "DicoTrie([Association('a', 2), Association('b', 1), Association('c', 3)])"
         """
-        ...
+        return f"DicoTrie({self.liste_assos})"
+            
+            
 
     def __eq__(self, autre) -> bool:
         """
diff --git a/TP6/associations/recherches.py b/TP6/associations/recherches.py
index 670b56562bc15c38754d5e579f43b8ccd6e46405..fc0661873b0267ee456ee79d36ed64477aa8c788 100755
--- a/TP6/associations/recherches.py
+++ b/TP6/associations/recherches.py
@@ -13,6 +13,7 @@
 from typing import TypeVar, Callable
 from types import NoneType
 
+
 # On définit un type générique :
 C = TypeVar('C')
 
@@ -49,34 +50,51 @@ def indice_seq(elem: C, liste: list[C], comp: Callable[[C, C], int]) \
         trouve = True
     return (trouve, i)
 
-# def indice_dicho(elem: C, liste: list[C], comp: Callable[[C, C], int]) \
-#                                     -> tuple[bool, int]:
-#     """Renvoie un couple (trouve, i) tel que:
-#         - si elem est un élément de liste,
-#              * trouve = True
-#              * i est l'indice de première occurence de elem dans liste
-#         - si elem n'est pas un élément de la liste :
-#              * trouve = False
-#              * pour tout j < i, liste[j] < liste[i]
-#              * pour tout j > i, liste[j] > liste[i]
-# 
-#     Précondition : comp est une fonction de comparaison et liste est triée pour comp
-# 
-#     $$$ def compare(x, y): return 0 if x == y else 1 if x > y else -1
-#     $$$ indice_dicho(0, [1, 3, 5], compare)
-#     (False, 0)
-#     $$$ indice_dicho(3, [1, 3, 5], compare)
-#     (True, 1)
-#     $$$ indice_dicho(4, [1, 3, 5], compare)
-#     (False, 2)
-#     $$$ indice_dicho(5, [1, 3, 5], compare)
-#     (True, 2)
-#     $$$ indice_dicho(6, [1, 3, 5], compare)
-#     (False, 3)
-#     $$$ indice_dicho(42, [], compare)
-#     (False, 0)
-#     """
-#    ...
+def indice_dicho(elem: C, liste: list[C], comp: Callable[[C, C], int]) \
+                                    -> tuple[bool, int]:
+    """Renvoie un couple (trouve, i) tel que:
+        - si elem est un élément de liste,
+             * trouve = True
+             * i est l'indice de première occurence de elem dans liste
+        - si elem n'est pas un élément de la liste :
+             * trouve = False
+             * pour tout j < i, liste[j] < liste[i]
+             * pour tout j > i, liste[j] > liste[i]
+
+    Précondition : comp est une fonction de comparaison et liste est triée pour comp
+
+    $$$ def compare(x, y): return 0 if x == y else 1 if x > y else -1
+    $$$ indice_dicho(0, [1, 3, 5], compare)
+    (False, 0)
+    $$$ indice_dicho(3, [1, 3, 5], compare)
+    (True, 1)
+    $$$ indice_dicho(4, [1, 3, 5], compare)
+    (False, 2)
+    $$$ indice_dicho(5, [1, 3, 5], compare)
+    (True, 2)
+    $$$ indice_dicho(6, [1, 3, 5], compare)
+    (False, 3)
+    $$$ indice_dicho(42, [], compare)
+    (False, 0)
+    """
+    trouve =  False
+    i = 0
+    res = 0
+    for elt1 in range(0,len(liste)-1):
+        for elt2 in range(1,len(liste)):
+            trouve = True
+            if comp([elt1, elt2])==0:
+                res = (trouve , liste[elt1])
+            elif comp([elt1, elt2]) < 0:
+                trouve = False
+                res = (trouve, liste[elt1])
+            elif comp([elt1, elt2]) > 0:
+                res = (trouve, liste[elt2])
+    return res
+                
+                
+            
+            
 
 def inserer(indice: int, elem: C, liste: list[C]) -> NoneType:
     """Insère l'élément elem à l'indice indice de la liste liste.
@@ -98,16 +116,7 @@ def inserer(indice: int, elem: C, liste: list[C]) -> NoneType:
     $$$ vide
     [42]
     """
-    i = 0
-    liste = []
-    elem.append(liste)
-    i= len(liste)-1
-    while i > 1:
-        liste[i] = liste[i-1]
-        i = i-1
-        liste[i] = elem
-    return liste
-    
+    return liste.insert(indice, elem)
     
 
 if __name__ == '__main__':
diff --git a/TP8/apl1test.py b/TP8/apl1test.py
new file mode 100644
index 0000000000000000000000000000000000000000..8533ccaca5d99e7cfb83d6d86aa9334bb6a73a40
--- /dev/null
+++ b/TP8/apl1test.py
@@ -0,0 +1,89 @@
+import thonnycontrib
+from thonnycontrib.backend.evaluator import Evaluator
+import thonnycontrib.backend.l1test_backend
+from thonny.plugins.cpython_backend.cp_back import MainCPythonBackend
+import thonnycontrib.backend.doctest_parser 
+from thonnycontrib.backend.doctest_parser import ExampleWithExpected, ExampleWithoutExpected
+import thonnycontrib.backend.ast_parser
+from thonnycontrib.backend.ast_parser import L1DocTest
+import thonnycontrib.backend.verdicts
+from thonnycontrib.backend.verdicts.ExceptionVerdict import ExceptionVerdict 
+
+import inspect
+import tempfile
+import os
+import sys
+        
+class MockBackend(MainCPythonBackend):
+    """
+    Fake backend.
+    """
+    def __init__(self):
+        ...
+
+    def send_message(self, msg) -> None:
+        ...
+
+# register backend
+thonnycontrib.backend.l1test_backend.BACKEND = MockBackend()
+
+def l1test_to_org(filename: str, source: str=""):
+    """
+    Return an org abstract of the tests presents in `filename` file.
+    """
+    abstract = {'total': 0,
+                'success': 0,
+                'failures': 0,
+                'errors': 0,
+                'empty': 0}
+
+    if source == "":
+        with open(filename, 'rt') as fin:
+            source = fin.read()
+    evaluator = Evaluator(filename=filename,
+                          source=source)
+    tests = evaluator.evaluate()
+    n = len(tests)
+    abstract['total'] = n
+    res = ""
+    for test in tests:
+        examples = test.get_examples()
+        res_examples = ""
+        nb_test, nb_test_ok = 0, 0
+        empty = True
+        for example in examples:
+            verdict = test.get_verdict_from_example(example)
+            if isinstance(example, ExampleWithExpected):
+                nb_test += 1
+                if verdict.isSuccess():
+                    nb_test_ok += 1
+                    abstract['success'] += 1
+                else:
+                    abstract['failures'] += 1
+                empty = False
+            if isinstance(verdict, ExceptionVerdict):
+                abstract['errors'] += 1
+                empty = False
+            res_examples += f"** {verdict}\n\n"
+            if not verdict.isSuccess():
+                res_examples += f"   {verdict.get_details()}\n\n"
+        if not empty: 
+            res += f"* {test.get_name()} ~ {nb_test_ok}/{nb_test} réussis\n\n"
+        else:
+            abstract['empty'] += 1
+            res += f"* {test.get_name()}\n\n Aucun test trouvé !\n\n"
+        res += res_examples
+    res = f"Tests exécutés : {abstract['total']}\nSuccès: {abstract['success']}, \
+Echecs: {abstract['failures']}, Erreurs: {abstract['errors']}, \
+Vide: {abstract['empty']}\n\n" + res
+    return res
+
+
+def testmod(modulename: str):
+    """
+    mimic the doctest.testmod function
+    for `modulename` module
+    """
+    print(l1test_to_org(modulename))
+
+
diff --git a/TP8/apqueue.py b/TP8/apqueue.py
new file mode 100644
index 0000000000000000000000000000000000000000..909668a52ff5b57b848310df0c193f8622a3d222
--- /dev/null
+++ b/TP8/apqueue.py
@@ -0,0 +1,109 @@
+#!/usr/bin/python3
+# -*- coding: utf-8 -*-
+
+"""
+:mod:`apqueue` module
+
+:author: `FIL - Faculté des Sciences et Technologies -
+          Univ. Lille <http://portail.fil.univ-lille1.fr>`_
+
+:date: 2015, september
+:last revision: 2024, March
+
+A module for queue data structure.
+
+:Provides:
+
+* class ApQueue
+
+and methods
+
+* `enqueue`
+* `dequeue`
+* `is_empty`
+"""
+from typing import TypeVar
+T = TypeVar('T')
+
+class ApQueueEmptyError(Exception):
+    """
+    Exception for empty stacks
+    """
+    def __init__(self, msg):
+        self.message = msg
+
+
+class ApQueue():
+    """
+    $$$ ap_queue = ApQueue()
+    $$$ ap_queue.is_empty()
+    True
+    $$$ ap_queue.enqueue(1)
+    $$$ ap_queue.is_empty()
+    False
+    $$$ ap_queue.enqueue(2)
+    $$$ str(ap_queue)
+    '→2|1→'
+    $$$ ap_queue.dequeue()
+    1
+    $$$ ap_queue.dequeue()
+    2
+    $$$ ap_queue.is_empty()
+    True
+    $$e ap_queue.dequeue()
+    ApQueueEmptyError
+    """
+    ARROW = chr(0x2192)
+
+    def __init__(self):
+        """
+        build  a new empty queue
+        precondition: none
+        """
+        self.__content = []
+
+    def enqueue(self, elt: T):
+        """
+        insert an element at the begining of the queue
+        precondition: none
+        """
+        self.__content.insert(0, elt)
+
+    def dequeue(self) -> T:
+        """
+        return the element on top of self
+        Side effect: self contains an element less
+        precondition: self must be non empty
+        """
+        if len(self.__content) > 0:
+            res = self.__content.pop()
+        else:
+            raise ApQueueEmptyError('empty queue, nothing to dequeue')
+        return res
+
+    def is_empty(self) -> bool:
+        """
+        return:
+          * ``True`` if s is empty
+          * ``False`` otherwise
+        precondition: none
+        """
+        return self.__content == []
+
+    def __str__(self) -> str:
+        """
+        return the string representation of this queue.
+        """
+        return ApQueue.ARROW + \
+            "|".join(str(el) for el in self.__content[::-1]) + \
+            ApQueue.ARROW
+
+    def __len__(self) -> int:
+        """
+        return the length of this queue
+        """
+        return len(self.__content)
+
+if __name__ == '__main__':
+    import apl1test
+    apl1test.testmod('apqueue.py')
diff --git a/TP8/apstack.py b/TP8/apstack.py
new file mode 100644
index 0000000000000000000000000000000000000000..16b68409a76d56573cb2e28f06ffcd1305947d0c
--- /dev/null
+++ b/TP8/apstack.py
@@ -0,0 +1,132 @@
+#!/usr/bin/python3
+# -*- coding: utf-8 -*-
+
+"""
+:mod:`stack` module
+
+:author: `FIL - Faculté des Sciences et Technologies - 
+          Univ. Lille <http://portail.fil.univ-lille1.fr>`_
+
+:date: 2015, september
+:last revision: 2017, october
+
+A module for stack data structure.
+
+:Provides:
+
+* class ApStack
+
+and methods
+
+* `push`
+* `pop`
+* `top`
+* `is_empty`
+
+:Examples:
+"""
+from typing import TypeVar
+T = TypeVar('T')
+
+class ApStackEmptyError(Exception):
+    """
+    Exception for empty stacks
+    """
+    def __init__(self, msg):
+        self.message = msg
+
+
+class ApStack():
+    """
+    $$$ stak = ApStack()
+    $$$ stak.is_empty()
+    True
+    $$$ stak.push(1)
+    $$$ stak.is_empty()
+    False
+    $$$ stak.push(2)
+    $$$ stak.top()
+    2
+    $$$ stak.pop()
+    2
+    $$$ stak.top()
+    1
+    $$$ stak.pop()
+    1
+    $$$ stak.is_empty()
+    True
+    $$e stak.pop()
+    ApStackEmptyError
+    """
+    
+    def __init__(self):
+        """
+        build a new empty stack
+        précondition : none
+        """
+        self.__content = []
+        
+    def push(self, el: T):
+        """
+        add el on top of the stack.
+        précondition : none
+        """
+        self.__content.append(el)
+
+    def pop(self) -> T:
+        """
+        return the element on top of self
+        
+        Side effect: self contains an element less
+        
+        précondition : self must be non empty
+        """
+        if len(self.__content) == 0:
+            raise ApStackEmptyError('empty stack, nothing to pop')
+        return self.__content.pop()
+
+    def top(self) -> T:
+        """
+        return the element on top of self without removing it
+        
+        précondition : self must be non empty
+        """
+        if len(self.__content) == 0:
+            raise ApStackEmptyError('empty stack, nothing to pop')
+        return self.__content[-1]
+
+    def is_empty(self) -> bool:
+        """
+        return:
+           * ``True`` if s is empty
+           * ``False`` otherwise
+                précondition : none
+        """
+        return self.__content == []
+
+    def __str__(self) -> str:
+        """
+        return a stack representation 
+        """
+        mlen = 1
+        if not self.is_empty():
+            mlen = max(len(str(el)) for el in self.__content)
+        res = []
+        for el in self.__content:
+            pad = mlen - len(str(el))
+            left = pad // 2
+            right = pad - left
+            res.insert(0, "|" + " " * left + str(el) + " " * right + "|")
+        res.append("+" + "-" * mlen + "+")
+        return "\n".join(res)
+
+    def __len__(self) -> int:
+        """
+        Return the stack length.
+        """
+        return len(self.__content)
+
+
+if (__name__ == '__main__'):
+    import apl1test
+    apl1test.testmod('apstack.py')
diff --git a/TP8/war.py b/TP8/war.py
new file mode 100755
index 0000000000000000000000000000000000000000..877157de16db626e4c682748250e72917c6487a7
--- /dev/null
+++ b/TP8/war.py
@@ -0,0 +1,120 @@
+#!/usr/bin/python3
+# -*- coding: utf-8 -*-
+
+"""
+:mod:`war` game
+
+:author: `FIL - Faculté des Sciences et Technologies -
+         Univ. Lille <http://portail.fil.univ-lille1.fr>`
+
+:date: 2021, april.
+:last revision: 2024, march.
+"""
+
+from card import Card
+from apqueue import *
+from apstack import *
+
+def distribute(n_card: int) -> tuple[ApQueue, ApQueue]:
+    """
+    renvoie un couple (m1, m2) constitué de deux files,
+    contenant pour chacune `n_card` cartes
+
+    precondition : n_card > 0
+    exemples :
+
+    $$$ m1, m2 = distribute( 4 )
+    $$$ len(m1) == 4
+    True
+    $$$ len(m2) == 4
+    True
+    $$$ type(m1) == ApQueue
+    True
+    $$$ type(m2) == ApQueue
+    True
+    $$$ carte = m1.dequeue()
+    $$$ isinstance(carte, Card)
+    True
+    """
+    deck = Card.deck(n_card * 2)
+    random.shuffle(deck)
+    m1 = ApQueue(deck[:n_card])
+    m2 = ApQueue(deck[n_card:])
+    return m1, m2
+
+def gather_stack(main: ApQueue, pile: ApStack) -> None:
+    """
+    ajoute les carte de la pile dans la main
+
+    exemples :
+
+    $$$ cartes = Card.deck(4)
+    $$$ main = ApQueue()
+    $$$ pile = ApStack()
+    $$$ for c in cartes: pile.push(c)
+    $$$ gather_stack( main, pile )
+    $$$ len( main ) == 4
+    True
+    $$$ all( main.dequeue() == cartes[ 3 - i ] for i in range(3))
+    True
+    """
+    while not pile.is_empty():
+        main.enqueue(pile.pop())
+
+def play_one_round(m1: ApQueue, m2: ApQueue, pile: ApStack) -> None:
+    """
+    Simule une étape du jeu :
+    `j1`` et ``j2`` prennent la première carte de leur
+    main. On compare les deux cartes :
+
+    * Si la carte de ``j1`` est supérieure à celle de ``j2``, alors
+    ``j1`` remporte toutes les cartes de la pile ;
+    * Si la carte de ``j1`` est inférieure à celle de ``j2``, alors
+    ``j2`` remporte toutes les cartes de la pile ;
+    * Si les cartes sont égales, alors elles sont *empilées* sur la
+      pile.
+
+    precondition : m1 et m2 ne sont pas vides
+    """
+    card1 = m1.dequeue()
+    card2 = m2.dequeue()
+    print(f"joueur 1 joue {card1} et joueur 2 joue {card2}")
+    if card1.compare(card2) == 1:
+        print("joueur 1 gagne")
+        gather_stack(m1, pile)
+    elif card1.compare(card2) == -1:
+        print("joueur 2 gagne")
+        gather_stack(m2, pile)
+    else:
+        print("Bataille !!")
+        pile.push(card1)
+        pile.push(card2)
+
+
+def play(n_card: int, n_round: int) -> None:
+    """
+    simule une partie de bataille
+
+    n_card: le nombre de cartes à distribuer à chaque joueur.
+    n_round: le nombre maximal de tours
+    """
+    m1, m2 = distribute(n_card)
+    pile = ApStack()
+    for i in range(n_round):
+        print(f"------ Tour {i+1} --------")
+        play_one_round(m1, m2, pile)
+        print(f"Le joueur 1 a {len(m1)} cartes et le joueur 2 a {len(m2)} cartes")
+        if m1.is_empty() or m2.is_empty():
+            break
+    if len(m1) > len(m2):
+        print("Le joueur 1 a gagné")
+    elif len(m1) < len(m2):
+        print("Le joueur 2 a gagné")
+    else:
+        print("Égalité")
+
+
+if __name__ == "__main__":
+    import apl1test
+    apl1test.testmod("war.py")
+
diff --git a/tp1/Tp1.py b/tp1/Tp1.py
deleted file mode 100644
index 5031306a8db1c71f8be1c298e437461a6341fe23..0000000000000000000000000000000000000000
--- a/tp1/Tp1.py
+++ /dev/null
@@ -1,66 +0,0 @@
-#METHODE SPLIT
-
-#1) ['la', 'méthode', 'split', 'est', 'parfois', 'bien', 'utile']
-# ['la m', 'thode split est parfois bien utile']
-# ['la méthod', ' split ', 'st parfois bi', 'n util', '']
-# ['la', 'méthode', 'split', 'est', 'parfois', 'bien', 'utile']
-# ['la méthode ', ' est parfois bien utile']
-# pour s.split('') il y'a une erreur.
-# 
-# 2) la methode split permet de decouper un caractere ou plusieurs chaines de caracteres en plusieurs elements en utilisant les separateurs.
-# 3) oui cette methode modifie la chaine a laquelle elle s'applique'
-
-
-# METHODE JOIN
-
-#1)
-#'laméthodesplitestparfoisbienutile'
-#'la méthode split est parfois bien utile'
-#'la;méthode;split;est;parfois;bien;utile'
-#'la tralala méthode tralala split tralala est tralala parfois tralala bien tralala utile'
-#la
-#méthode
-#split
-#est
-#parfois
-# bien
-# utile
-# 'la méthode split est parfois bien utile'
-# 'l!a! !m!é!t!h!o!d!e! !s!p!l!i!t! !e!s!t! !p!a!r!f!o!i!s! !b!i!e!n! !u!t!i!l!e'
-# pour "".join() il y'a une erreur
-# ''
-# pour "".join([1,2]) il y'a une erreur
-# 
-# 2) la fonction split permet de creer et renvoyer une nouvelle chaine de caractere en concatenant tous les elements d'un tableau
-# 3)non elle modifie par la chaine a laqulele elle s'applique
-
-# METHODE SORT
-# 1)
-# l=['e', 'i', 'l', 'm', 'n', 'o', 'o', 't']
-# l  est rangé : ['J', 'e', ' ', 'n', "'", 'a', 'i', ' ', 'j', 'a', 'm', 'a', 'i', 's', ' ', 'j', 'o', 'u', 'é', ' ', 'd', 'e', ' ', 'f', 'l', 'û', 't', 'e', '.']
-# 2) pour l = ['a', 1] on n'a une erreur car la fonction sort modidie uniquement soit une chaine de caractere uniquement dalsn la liste ou soit une liste d'entier uniquement mais elle renvoie unerreur lorsqu'on a une chaine de caractere et un entiers dans la meme liste 
-
-# UNE FONCTION sort POUR LES CHAINES
-
-def sort(s:str)-> str:
-    """Renvoie une chaîne de caractères contenant les caractères de `s` triés dans l'ordre croissant.
-
-    Précondition : aucune
-    Exemple(s) :
-    $$$ sort('timoleon')
-    'eilmnoot'
-
-    """
-    chaine =''
-    l=list(s)
-    l.sort()
-    for elt in range(len(l)):
-        chaine += l[elt]
-    return chaine
-    
-        
-
-    
-
-
-