diff --git a/Tp7/Tp_tris.py b/Tp7/Tp_tris.py
new file mode 100644
index 0000000000000000000000000000000000000000..d7850c8a78c2212ad86474bf92675ce566e5bd04
--- /dev/null
+++ b/Tp7/Tp_tris.py
@@ -0,0 +1,80 @@
+# l'expression qui permet de construire une liste des entiers
+#de 0 àn-1 est range(n)
+
+
+from random import shuffle
+from typing import Callable
+from compare import compare
+from ap_decorators import count
+from tris import *
+import matplotlib.pyplot as plt
+from anlyse_tris import tri_select
+import timeit
+from math import sqrt
+
+
+def liste_alea(n:int)->list[int]:
+    """construit une liste de longueur n contenant les entiers 0 à n-1 mélangés.
+
+    Précondition : n>=0
+    Exemple(s) :
+    $$$ liste_alea(5)
+    [3, 2, 0, 4, 1 ]
+    $$$ liste_alea(3)
+    [2, 1, 0]
+    $$$ liste_alea(2)
+    [0, 1]
+
+    """
+   
+    L=list(range(n))
+    random.shuffle(L)
+    return L
+
+#Representation graphique evec Matpotlib:
+
+import matplotlib.pyplot as plt
+abscisses = [1, 2, 4]
+ordonnees = [2, 5, 0]
+plt.plot(abscisses, ordonnees, color='blue')
+plt.show()
+
+#Évaluation expérimentale de la complexité en temps
+compare = count(compare)
+
+def analyser_tri(tri: Callable[[list[T], Callable[[T, T], int]], NoneType],
+                 nbre_essais: int,
+                 taille: int) -> float:
+    """
+    renvoie: le nombre moyen de comparaisons effectuées par l'algo tri
+         pour trier des listes de taille t, la moyenne étant calculée
+         sur n listes aléatoires.
+    précondition: n > 0, t >= 0, la fonc
+    """
+    res = 0
+    for i in range(nbre_essais):
+        compare.counter = 0
+        l = [k for k in range(taille)]
+        shuffle(l)
+        tri(l, compare)
+        res += compare.counter
+    return res / nbre_essais
+
+
+
+
+#calcul de nombres moyens de compraisons pour des listes 
+
+TAILLE_MAX = 100
+L=[]
+t=[]
+
+
+for t in range(TAILLE_MAX+1):
+    
+    
+    
+
+
+
+
diff --git a/Tp7/analyse-tris.zip b/Tp7/analyse-tris.zip
new file mode 100644
index 0000000000000000000000000000000000000000..93aed14f5508d1cbd03c4263483fdc9826249941
Binary files /dev/null and b/Tp7/analyse-tris.zip differ
diff --git a/Tp7/analyse-tris/analyse_tris.py b/Tp7/analyse-tris/analyse_tris.py
new file mode 100644
index 0000000000000000000000000000000000000000..9d12c3495eb527f26efa2ed40a25f584acada2ae
--- /dev/null
+++ b/Tp7/analyse-tris/analyse_tris.py
@@ -0,0 +1,79 @@
+#!/usr/bin/python3
+# -*- coding: utf-8 -*-
+
+"""
+:mod:`analyse_tris` module
+:author: FIL - Faculté des Sciences et Technologies - Univ. Lille <http://portail.fil.univ-lille1.fr>_
+:date: janvier 2017
+:dernières révisions: février 2018, février 2019
+
+Analyse empirique des tris
+
+"""
+from random import shuffle
+from typing import Callable
+from compare import compare
+from ap_decorators import count
+from tris import *
+
+################################################
+#  ANALYSE EMPIRIQUE DES TRIS                  #
+################################################
+
+# ajout d'un compteur à la fonction compare
+compare = count(compare)
+
+def analyser_tri(tri: Callable[[list[T], Callable[[T, T], int]], NoneType],
+                 nbre_essais: int,
+                 taille: int) -> float:
+    """
+    renvoie: le nombre moyen de comparaisons effectuées par l'algo tri
+         pour trier des listes de taille t, la moyenne étant calculée
+         sur n listes aléatoires.
+    précondition: n > 0, t >= 0, la fonc
+    """
+    res = 0
+    for i in range(nbre_essais):
+        compare.counter = 0
+        l = [k for k in range(taille)]
+        shuffle(l)
+        tri(l, compare)
+        res += compare.counter
+    return res / nbre_essais
+
+
+if (__name__ == '__main__'):
+    from matplotlib import pyplot as plt
+    
+    # Calcul de nombres moyens de comparaison pour des listes
+    # de tailles comprises entre 0 et TAILLE_MAX
+    NB_ESSAIS = 50
+    TAILLE_MAX = 100
+    c_select = [0.0] * (TAILLE_MAX + 1)
+    c_insert = [0.0] * (TAILLE_MAX + 1)
+    
+    for t in range(TAILLE_MAX + 1):
+        c_select[t] = analyser_tri(tri_select, 1, t)
+        # inutile de moyenner pour le tri par sélection
+        c_insert[t] = analyser_tri(tri_insert, NB_ESSAIS, t)
+
+    # Sauvegarde des données calculées dans un fichier au format CSV
+    prem_ligne = 'taille;"tri séléction";"tri insertion"\n'
+    ligne = '{:3d};{:8.2f};{:8.2f}\n'
+    with open('analyse_tris.csv', 'wt', encoding='utf8') as sortie:
+        sortie.write(prem_ligne)
+        for t in range(TAILLE_MAX + 1):
+            sortie.write(ligne.format(t,
+                                      c_select[t],
+                                      c_insert[t]))
+
+    # Représentation graphique
+    plt.plot(list(range(TAILLE_MAX + 1)), c_select, 'b.', label='Tri sélection')
+    plt.plot(list(range(TAILLE_MAX + 1)), c_insert, 'r.', label='Tri insertion')
+    plt.title('Tris : nbre de comparaisons')
+    plt.legend()
+    plt.xlabel('n = taille des listes')
+    plt.ylabel('c(n) = nbre de comparaisons')
+    plt.savefig('tris_nbcomp.png')
+    plt.show()
+
diff --git a/Tp7/analyse-tris/ap_decorators.py b/Tp7/analyse-tris/ap_decorators.py
new file mode 100644
index 0000000000000000000000000000000000000000..5f4adc9129d3d7ffef9d7dc68b59e4d6643d419d
--- /dev/null
+++ b/Tp7/analyse-tris/ap_decorators.py
@@ -0,0 +1,135 @@
+#!/usr/bin/python3
+# -*- coding: utf-8 -*-
+
+"""
+:module: ap_decorators  
+:author: FIL - Faculté des Sciences et Technologies -  Univ. Lille <http://portail.fil.univ-lille1.fr>_
+:date: 2018, september
+
+"""
+
+from functools import wraps
+
+
+def trace(fct):
+    '''
+    Decorator for tracing every call to fct.
+    Recursive calls are indented.
+
+    :Example:
+
+    >>> @trace
+    ... def fact(n):
+    ...     if n == 0:
+    ...         return 1
+    ...     else:
+    ...         return n * fact(n - 1)
+    
+    >>> fact(5)
+     -> fact((5,), {})
+    ... -> fact((4,), {})
+    ...... -> fact((3,), {})
+    ......... -> fact((2,), {})
+    ............ -> fact((1,), {})
+    ............... -> fact((0,), {})
+    ............... <- 1
+    ............ <- 1
+    ......... <- 2
+    ...... <- 6
+    ... <- 24
+    <- 120
+    120
+    '''
+    @wraps(fct)
+    def wrapper(*args, **kwargs):
+        dots = '...' * wrapper.__depth
+        print('{:s} -> {:s}{:s}'.format(dots, wrapper.__name__, repr((args, kwargs))))
+        wrapper.__depth += 1
+        y = fct(*args, **kwargs)
+        wrapper.__depth -= 1
+        print('{:s} <- {:s}'.format(dots, repr(y)))
+        return y
+    wrapper.__depth = 0
+    return wrapper
+
+def count(fct):
+    '''
+    decorator for counting  calls to  function fct
+    
+    :Example:
+
+    >>> @count
+    ... def fact(n):
+    ...     if n == 0:
+    ...         return 1
+    ...     else:
+    ...         return n * fact(n - 1)
+    
+    >>> fact.counter
+    0
+    >>> fact(5)
+    120
+    >>> fact.counter
+    6
+    '''
+    @wraps(fct) 
+    def wrapper(*args, **kwargs):
+        y = fct(*args, **kwargs)
+        wrapper.counter += 1
+        return y
+    wrapper.counter = 0
+    return wrapper
+
+
+def memoize(fct):
+    '''
+    decorator for memoizing computed values of  function fct
+    
+    :Example:
+
+    >>> @count
+    ... @memoize
+    ... def fact(n):
+    ...     if n == 0:
+    ...         return 1
+    ...     else:
+    ...         return n * fact(n - 1)
+    
+    >>> fact.counter
+    0
+    >>> fact(5)
+    120
+    >>> fact.counter
+    6
+    >>> fact.counter = 0
+    >>> fact(5)
+    120
+    >>> fact.counter
+    1
+    '''
+    cache = dict()
+    @wraps(fct)
+    def wrapper(*args, **kwargs):
+        key = repr((args, kwargs))
+        if key in cache:
+            return cache[key]
+        else:
+            y = fct(*args, **kwargs)
+            cache[key] = y
+            return y
+    return wrapper
+
+
+
+if __name__ == '__main__':
+    import doctest
+    doctest.testmod(optionflags=doctest.NORMALIZE_WHITESPACE | doctest.ELLIPSIS, verbose=False)
+    
+    
+
+
+
+
+
+
+
diff --git a/Tp7/analyse-tris/apl1test.py b/Tp7/analyse-tris/apl1test.py
new file mode 100644
index 0000000000000000000000000000000000000000..8533ccaca5d99e7cfb83d6d86aa9334bb6a73a40
--- /dev/null
+++ b/Tp7/analyse-tris/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/Tp7/analyse-tris/compare.py b/Tp7/analyse-tris/compare.py
new file mode 100644
index 0000000000000000000000000000000000000000..abad0a4c2af8427e32cf9f56cc7868fe742be0e1
--- /dev/null
+++ b/Tp7/analyse-tris/compare.py
@@ -0,0 +1,44 @@
+#!/usr/bin/python3
+# -*- coding: utf-8 -*-
+
+"""
+:mod:`compare` module
+:author: FIL - FST - Univ. Lille <http://portail.fil.univ-lille1.fr>_
+:date: 2016, january
+:dernière révision: février 2018
+
+Fonction de comparaison 
+pour l'analyse des algos de recherche et de tri
+
+"""
+from typing import TypeVar
+
+
+T = TypeVar('T')
+def compare(x: T, y: T) -> int:
+    """
+    renvoie:
+      - -1 si x < y
+      - 0 si x == y
+      - 1 si x > y
+    précondition: x et y doivent être d'un type pour lequel les opérateurs de comparaison <, <=, ==
+         peuvent s'appliquer
+    exemples:
+
+    $$$ compare(1, 3)
+    -1
+    $$$ compare(3, 1)
+    1
+    $$$ compare(3, 3)
+    0
+    """
+    if x == y:
+        return 0
+    elif x > y:
+        return 1
+    else:
+        return -1
+
+if (__name__ == '__main__'):
+    import apl1test
+    apl1test.testmod('compare.py')
diff --git a/Tp7/analyse-tris/tris.py b/Tp7/analyse-tris/tris.py
new file mode 100644
index 0000000000000000000000000000000000000000..18df74065a465ff7025f8fc807a4bd08958869a5
--- /dev/null
+++ b/Tp7/analyse-tris/tris.py
@@ -0,0 +1,193 @@
+#!/usr/bin/python3
+# -*- coding: utf-8 -*-
+
+"""
+:mod:`tris` module
+:author: FIL - Faculté des Sciences et Technologies -
+         Univ. Lille <http://portail.fil.univ-lille1.fr>_
+:date: 2015, january
+:dernière révision: février 2018
+
+
+Tris de listes
+
+- tri par sélection
+- tri par insertion
+
+"""
+
+from types import NoneType
+from typing import Callable, TypeVar
+from compare import compare
+T = TypeVar('T')
+
+def est_trie(liste: list[T], comp: Callable[[T, T], int] = compare) -> bool:
+    """
+    renvoir True si et seulement si liste est triée selon l'ordre défini par comp
+
+    précondition: les éléments de liste doivent être comparables selon comp
+
+    exemples:
+
+    $$$ est_trie([1, 2, 3, 4])
+    True
+    $$$ est_trie([1, 2, 4, 3])
+    False
+    $$$ est_trie([])
+    True
+    """
+    i = 0
+    res = True
+    while res and i < len(liste) - 1:
+        res = comp(liste[i], liste[i+1]) <= 0
+        i += 1
+    return res
+    # ou plus simplement
+    # return all(comp(liste[i], liste[i+1]) <= 0 for i in range(len(liste)-1))
+
+
+################################################
+#  TRI PAR SELECTION                           #
+################################################
+
+def echanger(liste: list[T], i: int, j: int) -> NoneType:
+    """
+    échange les éléments d'indice i et j de liste.
+
+    précondition: 0 <= i,j < len(liste)
+
+    exemples:
+
+    $$$ l1 =  [3, 1, 4, 9, 5, 1, 2]
+    $$$ l2 = l1.copy()
+    $$$ echanger(l2, 3, 5)
+    $$$ (l1[3], l1[5]) == (l2[5], l2[3])
+    True
+    """
+    liste[i], liste[j] = liste[j], liste[i]
+
+
+def select_min(liste: list[T], a: int, b: int, comp: Callable[[T, T], int]=compare) -> int:
+    """
+    renvoie l'indice du minimum dans la tranche liste[a:b]
+    précondition: 0 <= a < b <= long(liste),
+         éléments de liste comparables avec comp
+    exemples:
+
+    $$$ select_min([1, 2, 3, 4, 5, 6, 7, 0], 0, 8)
+    7
+    $$$ select_min([1, 2, 3, 4, 5, 6, 7, 0], 1, 7)
+    1
+    """
+    ind_min = a
+    # l'indice du plus petit élément de la tranche liste[a:a+1] est ind_min
+    for i in range(a + 1, b):
+        # supposons que l'indice du plus petit élément de la
+        # tranche liste[a:i] est ind_min
+        if comp(liste[i], liste[ind_min]) == -1:
+            ind_min = i
+        # alors l'indice du plus petit élément de la tranche liste[a:i+1]
+        # est ind_min
+    # à l'issue de l'itération l'indice du plus petit élément de la tranche
+    # liste[a:b] est ind_min
+    return ind_min
+
+
+def tri_select(liste: list[T], comp: Callable[[T, T], int] = compare) -> NoneType:
+    """
+    modifie la liste liste en triant ses éléments selon l'ordre défini par comp
+          Algorithme du tri par sélection du minimum
+    précondition: liste liste homogène d'éléments comparables selon comp
+    exemples:
+
+    $$$ liste = [3, 1, 4, 1, 5, 9, 2]
+    $$$ tri_select(liste)
+    $$$ liste == [1, 1, 2, 3, 4, 5, 9]
+    True
+    $$$ from random import randrange
+    $$$ l1 = [randrange(1000) for k in range(randrange(100))]
+    $$$ l2 = l1.copy()
+    $$$ tri_select(l2)
+    $$$ est_trie(l2)
+    True
+    $$$ all(l1.count(elt) == l2.count(elt) for elt in l1)
+    True
+    $$$ all(l1.count(elt) == l2.count(elt) for elt in l2)
+    True
+    """
+    n = len(liste)
+    # la tranche liste[0:1] est triée
+    for i in range(n - 1):
+        # supposons la tranche liste[0:i+1] triée
+        ind_min = select_min(liste, i, n, comp=comp)
+        echanger(liste, i, ind_min)
+        # alors la tranche liste[0:i+1] est triée
+    # à l'issue de l'itération la tranche liste[0:n] est triée
+
+
+################################################
+#  TRI PAR INSERTION                           #
+################################################
+
+def inserer(liste: list[T], i: int, comp: Callable[[T, T], int] = compare) -> NoneType:
+    """
+    insère l'élément liste[i] à sa place dans la tranche
+    liste[0:i+1] de sorte que cette tranche soit triée
+    si liste[0:i] l'est auparavant
+
+    précondition: 0 <= i < long(liste)
+         éléments de liste comparables par comp
+    exemples:
+
+    $$$ liste = [1, 2, 4, 5, 3, 7, 6]
+    $$$ inserer(liste, 4)
+    $$$ liste == [1, 2, 3, 4, 5, 7, 6]
+    True
+    $$$ inserer(liste, 5)
+    $$$ liste == [1, 2, 3, 4, 5, 7, 6]
+    True
+    $$$ inserer(liste, 6)
+    $$$ liste == [1, 2, 3, 4, 5, 6, 7]
+    True
+    """
+    aux = liste[i]
+    k = i
+    while k >= 1 and comp(aux, liste[k - 1]) == -1:
+        liste[k] = liste[k - 1]
+        k = k - 1
+    liste[k] = aux
+
+
+def tri_insert(liste: list[T], comp: Callable[[T, T], int] = compare) -> NoneType:
+    """
+    modifie la liste liste en triant ses éléments selon l'ordre défini par comp Algorithme du tri par insertion
+    précondition: liste liste homogène d'éléments comparables selon comp
+    exemples:
+
+    $$$ liste = [3, 1, 4, 1, 5, 9, 2]
+    $$$ tri_insert(liste)
+    $$$ liste == [1, 1, 2, 3, 4, 5, 9]
+    True
+    $$$ from random import randrange
+    $$$ l1 = [randrange(1000) for k in range(randrange(100))]
+    $$$ l2 = l1.copy()
+    $$$ tri_insert(l2)
+    $$$ est_trie(l2)
+    True
+    $$$ all(l1.count(elt) == l2.count(elt) for elt in l1)
+    True
+    $$$ all(l1.count(elt) == l2.count(elt) for elt in l2)
+    True
+    """
+    n = len(liste)
+    # la tranche liste[0:1] est triée
+    for i in range(1, n):
+        # supposons la tranche liste[0:i] triée
+        inserer(liste, i, comp=comp)
+        # alors la tranche liste[0:i+1] est triée
+    # à l'issue de l'itération la tranche liste[0:n] est triée
+
+
+if (__name__ == '__main__'):
+    import apl1test
+    apl1test.testmod('tris.py')
diff --git a/Tp7/analyse_tris2.py b/Tp7/analyse_tris2.py
new file mode 100755
index 0000000000000000000000000000000000000000..126de5b02a916977064221e4295c479d8e693dc2
--- /dev/null
+++ b/Tp7/analyse_tris2.py
@@ -0,0 +1,94 @@
+#!/usr/bin/python3
+# -*- coding: utf-8 -*-
+
+"""
+:mod:`analyse_tris` module
+:author: FIL - Faculté des Sciences et Technologies - Univ. Lille <http://portail.fil.univ-lille1.fr>_
+:date: janvier 2017
+:dernières révisions: février 2018, février 2019
+
+Analyse empirique des tris
+
+"""
+from random import shuffle
+from typing import Callable
+from compare import compare
+from ap_decorators import count
+from tris import *
+
+################################################
+#  ANALYSE EMPIRIQUE DES TRIS                  #
+################################################
+
+# ajout d'un compteur à la fonction compare
+compare = count(compare)
+
+def analyser_tri(tri: Callable[[list[T], Callable[[T, T], int]], NoneType],
+                 nbre_essais: int,
+                 taille: int) -> float:
+    """
+    renvoie: le nombre moyen de comparaisons effectuées par l'algo tri
+         pour trier des listes de taille t, la moyenne étant calculée
+         sur n listes aléatoires.
+    précondition: n > 0, t >= 0, la fonc
+    """
+    res = 0
+    for i in range(nbre_essais):
+        compare.counter = 0
+        l = [k for k in range(taille)]
+        shuffle(l)
+        tri(l, compare)
+        res += compare.counter
+    return res / nbre_essais
+
+def tris_sort(l:list[T], comp:callable[T, T], int= compare):
+    """à_remplacer_par_ce_que_fait_la_fonction
+
+    Précondition : 
+    Exemple(s) :
+    $$$ 
+
+    """
+    sorted (l,key= lambda x:comp(x,x))
+
+
+if (__name__ == '__main__'):
+    from matplotlib import pyplot as plt
+    
+    # Calcul de nombres moyens de comparaison pour des listes
+    # de tailles comprises entre 0 et TAILLE_MAX
+    NB_ESSAIS = 50
+    TAILLE_MAX = 100
+    c_select = [0.0] * (TAILLE_MAX + 1)
+    c_insert = [0.0] * (TAILLE_MAX + 1)
+    c_sort = [0.0] * (TAILLE_MAX + 1)
+    
+    
+    
+    
+    for t in range(TAILLE_MAX + 1):
+        c_select[t] = analyser_tri(tri_select, 1, t)
+        # inutile de moyenner pour le tri par sélection
+        c_insert[t] = analyser_tri(tri_insert, NB_ESSAIS, t)
+        c_insert[t] = analyser_tri(tri_sort, NB_ESSAIS, t)
+
+    # Sauvegarde des données calculées dans un fichier au format CSV
+    prem_ligne = 'taille;"tri séléction";"tri insertion"\n'
+    ligne = '{:3d};{:8.2f};{:8.2f}\n'
+    with open('analyse_tris.csv', 'wt', encoding='utf8') as sortie:
+        sortie.write(prem_ligne)
+        for t in range(TAILLE_MAX + 1):
+            sortie.write(ligne.format(t,
+                                      c_select[t],
+                                      c_insert[t]))
+
+    # Représentation graphique
+    plt.plot(list(range(TAILLE_MAX + 1)), c_select, 'b.', label='Tri sélection')
+    plt.plot(list(range(TAILLE_MAX + 1)), c_insert, 'r.', label='Tri insertion')
+    plt.plot(list(range(TAILLE_MAX + 1)), c_insert, 'green.', label='Tri sort')
+    plt.title('Tris : nbre de comparaisons')
+    plt.legend()
+    plt.xlabel('n = taille des listes')
+    plt.ylabel('c(n) = nbre de comparaisons')
+    plt.savefig('tris_nbcomp.png')
+    plt.show()
diff --git a/Tp7/ap_decorators.py b/Tp7/ap_decorators.py
new file mode 100644
index 0000000000000000000000000000000000000000..5f4adc9129d3d7ffef9d7dc68b59e4d6643d419d
--- /dev/null
+++ b/Tp7/ap_decorators.py
@@ -0,0 +1,135 @@
+#!/usr/bin/python3
+# -*- coding: utf-8 -*-
+
+"""
+:module: ap_decorators  
+:author: FIL - Faculté des Sciences et Technologies -  Univ. Lille <http://portail.fil.univ-lille1.fr>_
+:date: 2018, september
+
+"""
+
+from functools import wraps
+
+
+def trace(fct):
+    '''
+    Decorator for tracing every call to fct.
+    Recursive calls are indented.
+
+    :Example:
+
+    >>> @trace
+    ... def fact(n):
+    ...     if n == 0:
+    ...         return 1
+    ...     else:
+    ...         return n * fact(n - 1)
+    
+    >>> fact(5)
+     -> fact((5,), {})
+    ... -> fact((4,), {})
+    ...... -> fact((3,), {})
+    ......... -> fact((2,), {})
+    ............ -> fact((1,), {})
+    ............... -> fact((0,), {})
+    ............... <- 1
+    ............ <- 1
+    ......... <- 2
+    ...... <- 6
+    ... <- 24
+    <- 120
+    120
+    '''
+    @wraps(fct)
+    def wrapper(*args, **kwargs):
+        dots = '...' * wrapper.__depth
+        print('{:s} -> {:s}{:s}'.format(dots, wrapper.__name__, repr((args, kwargs))))
+        wrapper.__depth += 1
+        y = fct(*args, **kwargs)
+        wrapper.__depth -= 1
+        print('{:s} <- {:s}'.format(dots, repr(y)))
+        return y
+    wrapper.__depth = 0
+    return wrapper
+
+def count(fct):
+    '''
+    decorator for counting  calls to  function fct
+    
+    :Example:
+
+    >>> @count
+    ... def fact(n):
+    ...     if n == 0:
+    ...         return 1
+    ...     else:
+    ...         return n * fact(n - 1)
+    
+    >>> fact.counter
+    0
+    >>> fact(5)
+    120
+    >>> fact.counter
+    6
+    '''
+    @wraps(fct) 
+    def wrapper(*args, **kwargs):
+        y = fct(*args, **kwargs)
+        wrapper.counter += 1
+        return y
+    wrapper.counter = 0
+    return wrapper
+
+
+def memoize(fct):
+    '''
+    decorator for memoizing computed values of  function fct
+    
+    :Example:
+
+    >>> @count
+    ... @memoize
+    ... def fact(n):
+    ...     if n == 0:
+    ...         return 1
+    ...     else:
+    ...         return n * fact(n - 1)
+    
+    >>> fact.counter
+    0
+    >>> fact(5)
+    120
+    >>> fact.counter
+    6
+    >>> fact.counter = 0
+    >>> fact(5)
+    120
+    >>> fact.counter
+    1
+    '''
+    cache = dict()
+    @wraps(fct)
+    def wrapper(*args, **kwargs):
+        key = repr((args, kwargs))
+        if key in cache:
+            return cache[key]
+        else:
+            y = fct(*args, **kwargs)
+            cache[key] = y
+            return y
+    return wrapper
+
+
+
+if __name__ == '__main__':
+    import doctest
+    doctest.testmod(optionflags=doctest.NORMALIZE_WHITESPACE | doctest.ELLIPSIS, verbose=False)
+    
+    
+
+
+
+
+
+
+
diff --git a/Tp7/compare.py b/Tp7/compare.py
new file mode 100644
index 0000000000000000000000000000000000000000..abad0a4c2af8427e32cf9f56cc7868fe742be0e1
--- /dev/null
+++ b/Tp7/compare.py
@@ -0,0 +1,44 @@
+#!/usr/bin/python3
+# -*- coding: utf-8 -*-
+
+"""
+:mod:`compare` module
+:author: FIL - FST - Univ. Lille <http://portail.fil.univ-lille1.fr>_
+:date: 2016, january
+:dernière révision: février 2018
+
+Fonction de comparaison 
+pour l'analyse des algos de recherche et de tri
+
+"""
+from typing import TypeVar
+
+
+T = TypeVar('T')
+def compare(x: T, y: T) -> int:
+    """
+    renvoie:
+      - -1 si x < y
+      - 0 si x == y
+      - 1 si x > y
+    précondition: x et y doivent être d'un type pour lequel les opérateurs de comparaison <, <=, ==
+         peuvent s'appliquer
+    exemples:
+
+    $$$ compare(1, 3)
+    -1
+    $$$ compare(3, 1)
+    1
+    $$$ compare(3, 3)
+    0
+    """
+    if x == y:
+        return 0
+    elif x > y:
+        return 1
+    else:
+        return -1
+
+if (__name__ == '__main__'):
+    import apl1test
+    apl1test.testmod('compare.py')
diff --git a/Tp7/tris.py b/Tp7/tris.py
new file mode 100644
index 0000000000000000000000000000000000000000..18df74065a465ff7025f8fc807a4bd08958869a5
--- /dev/null
+++ b/Tp7/tris.py
@@ -0,0 +1,193 @@
+#!/usr/bin/python3
+# -*- coding: utf-8 -*-
+
+"""
+:mod:`tris` module
+:author: FIL - Faculté des Sciences et Technologies -
+         Univ. Lille <http://portail.fil.univ-lille1.fr>_
+:date: 2015, january
+:dernière révision: février 2018
+
+
+Tris de listes
+
+- tri par sélection
+- tri par insertion
+
+"""
+
+from types import NoneType
+from typing import Callable, TypeVar
+from compare import compare
+T = TypeVar('T')
+
+def est_trie(liste: list[T], comp: Callable[[T, T], int] = compare) -> bool:
+    """
+    renvoir True si et seulement si liste est triée selon l'ordre défini par comp
+
+    précondition: les éléments de liste doivent être comparables selon comp
+
+    exemples:
+
+    $$$ est_trie([1, 2, 3, 4])
+    True
+    $$$ est_trie([1, 2, 4, 3])
+    False
+    $$$ est_trie([])
+    True
+    """
+    i = 0
+    res = True
+    while res and i < len(liste) - 1:
+        res = comp(liste[i], liste[i+1]) <= 0
+        i += 1
+    return res
+    # ou plus simplement
+    # return all(comp(liste[i], liste[i+1]) <= 0 for i in range(len(liste)-1))
+
+
+################################################
+#  TRI PAR SELECTION                           #
+################################################
+
+def echanger(liste: list[T], i: int, j: int) -> NoneType:
+    """
+    échange les éléments d'indice i et j de liste.
+
+    précondition: 0 <= i,j < len(liste)
+
+    exemples:
+
+    $$$ l1 =  [3, 1, 4, 9, 5, 1, 2]
+    $$$ l2 = l1.copy()
+    $$$ echanger(l2, 3, 5)
+    $$$ (l1[3], l1[5]) == (l2[5], l2[3])
+    True
+    """
+    liste[i], liste[j] = liste[j], liste[i]
+
+
+def select_min(liste: list[T], a: int, b: int, comp: Callable[[T, T], int]=compare) -> int:
+    """
+    renvoie l'indice du minimum dans la tranche liste[a:b]
+    précondition: 0 <= a < b <= long(liste),
+         éléments de liste comparables avec comp
+    exemples:
+
+    $$$ select_min([1, 2, 3, 4, 5, 6, 7, 0], 0, 8)
+    7
+    $$$ select_min([1, 2, 3, 4, 5, 6, 7, 0], 1, 7)
+    1
+    """
+    ind_min = a
+    # l'indice du plus petit élément de la tranche liste[a:a+1] est ind_min
+    for i in range(a + 1, b):
+        # supposons que l'indice du plus petit élément de la
+        # tranche liste[a:i] est ind_min
+        if comp(liste[i], liste[ind_min]) == -1:
+            ind_min = i
+        # alors l'indice du plus petit élément de la tranche liste[a:i+1]
+        # est ind_min
+    # à l'issue de l'itération l'indice du plus petit élément de la tranche
+    # liste[a:b] est ind_min
+    return ind_min
+
+
+def tri_select(liste: list[T], comp: Callable[[T, T], int] = compare) -> NoneType:
+    """
+    modifie la liste liste en triant ses éléments selon l'ordre défini par comp
+          Algorithme du tri par sélection du minimum
+    précondition: liste liste homogène d'éléments comparables selon comp
+    exemples:
+
+    $$$ liste = [3, 1, 4, 1, 5, 9, 2]
+    $$$ tri_select(liste)
+    $$$ liste == [1, 1, 2, 3, 4, 5, 9]
+    True
+    $$$ from random import randrange
+    $$$ l1 = [randrange(1000) for k in range(randrange(100))]
+    $$$ l2 = l1.copy()
+    $$$ tri_select(l2)
+    $$$ est_trie(l2)
+    True
+    $$$ all(l1.count(elt) == l2.count(elt) for elt in l1)
+    True
+    $$$ all(l1.count(elt) == l2.count(elt) for elt in l2)
+    True
+    """
+    n = len(liste)
+    # la tranche liste[0:1] est triée
+    for i in range(n - 1):
+        # supposons la tranche liste[0:i+1] triée
+        ind_min = select_min(liste, i, n, comp=comp)
+        echanger(liste, i, ind_min)
+        # alors la tranche liste[0:i+1] est triée
+    # à l'issue de l'itération la tranche liste[0:n] est triée
+
+
+################################################
+#  TRI PAR INSERTION                           #
+################################################
+
+def inserer(liste: list[T], i: int, comp: Callable[[T, T], int] = compare) -> NoneType:
+    """
+    insère l'élément liste[i] à sa place dans la tranche
+    liste[0:i+1] de sorte que cette tranche soit triée
+    si liste[0:i] l'est auparavant
+
+    précondition: 0 <= i < long(liste)
+         éléments de liste comparables par comp
+    exemples:
+
+    $$$ liste = [1, 2, 4, 5, 3, 7, 6]
+    $$$ inserer(liste, 4)
+    $$$ liste == [1, 2, 3, 4, 5, 7, 6]
+    True
+    $$$ inserer(liste, 5)
+    $$$ liste == [1, 2, 3, 4, 5, 7, 6]
+    True
+    $$$ inserer(liste, 6)
+    $$$ liste == [1, 2, 3, 4, 5, 6, 7]
+    True
+    """
+    aux = liste[i]
+    k = i
+    while k >= 1 and comp(aux, liste[k - 1]) == -1:
+        liste[k] = liste[k - 1]
+        k = k - 1
+    liste[k] = aux
+
+
+def tri_insert(liste: list[T], comp: Callable[[T, T], int] = compare) -> NoneType:
+    """
+    modifie la liste liste en triant ses éléments selon l'ordre défini par comp Algorithme du tri par insertion
+    précondition: liste liste homogène d'éléments comparables selon comp
+    exemples:
+
+    $$$ liste = [3, 1, 4, 1, 5, 9, 2]
+    $$$ tri_insert(liste)
+    $$$ liste == [1, 1, 2, 3, 4, 5, 9]
+    True
+    $$$ from random import randrange
+    $$$ l1 = [randrange(1000) for k in range(randrange(100))]
+    $$$ l2 = l1.copy()
+    $$$ tri_insert(l2)
+    $$$ est_trie(l2)
+    True
+    $$$ all(l1.count(elt) == l2.count(elt) for elt in l1)
+    True
+    $$$ all(l1.count(elt) == l2.count(elt) for elt in l2)
+    True
+    """
+    n = len(liste)
+    # la tranche liste[0:1] est triée
+    for i in range(1, n):
+        # supposons la tranche liste[0:i] triée
+        inserer(liste, i, comp=comp)
+        # alors la tranche liste[0:i+1] est triée
+    # à l'issue de l'itération la tranche liste[0:n] est triée
+
+
+if (__name__ == '__main__'):
+    import apl1test
+    apl1test.testmod('tris.py')