diff --git a/Tp2/ap_decorators.py b/Tp2/ap_decorators.py
new file mode 100644
index 0000000000000000000000000000000000000000..5f4adc9129d3d7ffef9d7dc68b59e4d6643d419d
--- /dev/null
+++ b/Tp2/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/Tp2/recursivite.py b/Tp2/recursivite.py
new file mode 100755
index 0000000000000000000000000000000000000000..75e8d2264eaac0145d72240724ea1c174eea4875
--- /dev/null
+++ b/Tp2/recursivite.py
@@ -0,0 +1,361 @@
+#!/usr/bin/python3
+# -*- coding: utf-8 -*-
+
+# Noms :Dahmane
+# Prenoms :lynda
+# Groupe :MI15
+# Date :24/01/2024
+
+
+
+"""
+
+:mod: module `recursivite`
+:author: FIL - Faculté des Sciences et Technologies - Univ. Lille
+:link: <http://portail.fil.univ-lille1.fr>_
+:date: Mars 2020
+:dernière révision: janvier 2024
+
+"""
+
+from ap_decorators import count, trace
+# l'instruction suivante permet d'annoter des paramètres qui sont des functions.
+from collections.abc import Callable
+
+
+def taille_binaire(naturel: int) -> int:
+    """
+    Renvoie le nombre de chiffres dans l'écriture binaire de l'entier naturel `naturel`
+
+    Précondition :
+       naturel >= 0
+
+    Exemples :
+    $$$ taille_binaire(0)
+    1
+    $$$ taille_binaire(1)
+    1
+    $$$ taille_binaire(2)
+    2
+    $$$ taille_binaire(1023)
+    10
+    $$$ taille_binaire(1024)
+    11
+    $$$ from random import randrange
+    $$$ l = [randrange(1,2**100)  for _ in range(100)]
+    $$$ all(taille_binaire(elt) == len(bin(elt))-2  for elt in l)
+    True
+
+    """
+    res = 1
+    while naturel>=2:
+        res += 1
+        naturel //= 2
+    return res
+# 
+# def taille_binaire_recursive(naturel: int) -> int:
+#     """
+#     Renvoie le nombre de chiffres dans l'écriture binaire de l'entier naturel `naturel`
+# 
+#     Précondition :
+#        naturel >= 0
+# 
+#     Exemples :
+#     $$$ taille_binaire_recursive(0)
+#     1
+#     $$$ taille_binaire_recursive(1)
+#     1
+#     $$$ taille_binaire_recursive(2)
+#     2
+#     $$$ taille_binaire_recursive(1023)
+#     10
+#     $$$ taille_binaire_recursive(1024)
+#     11
+#     $$$ from random import randrange
+#     $$$ l = [randrange(1,2**100)  for _ in range(100)]
+#     $$$ all(taille_binaire_recursive(elt) == len(bin(elt))-2  for elt in l)
+#     True
+#     """
+#     
+#     if naturel==1:
+#         return 1
+#     else:
+#         
+#         res+1
+#     taille_binaire_recursive(naturel//2)
+#     return res
+#     
+
+
+def poids_binaire(naturel: int) -> int:
+    """
+    Renvoie le nombre de chiffre 1 dans l'écriture binaire de l'entier naturel `naturel`
+
+    Précondition :
+       naturel >= 0
+
+    Exxemples :
+
+    $$$ poids_binaire(0)
+    0
+    $$$ poids_binaire(1)
+    1
+    $$$ poids_binaire(2)
+    1
+    $$$ poids_binaire(255)
+    8
+    $$$ from random import randrange
+    $$$ l = [randrange(1,2**100)  for _ in range(100)]
+    $$$ all([poids_binaire(x)==bin(x).count('1') for x in l])
+    True
+    """
+    res = naturel % 2
+    while naturel > 0:
+        naturel //= 2
+        res += naturel % 2
+    return res
+
+# 
+# def poids_binaire_recursif(naturel: int) -> int:
+#     """
+#     Renvoie le nombre de chiffre 1 dans l'écriture binaire de l'entier naturel `naturel`
+# 
+#     Précondition :
+#        naturel >= 0
+# 
+#     Exxemples :
+# 
+#     $$$ poids_binaire_recursif(0)
+#     0
+#     $$$ poids_binaire_recursif(1)
+#     1
+#     $$$ poids_binaire_recursif(2)
+#     1
+#     $$$ poids_binaire_recursif(255)
+#     8
+#     $$$ from random import randrange
+#     $$$ l = [randrange(1, 2**100)  for _ in range(100)]
+#     $$$ all([poids_binaire_recursif(x)==bin(x).count('1') for x in l])
+#     True
+#     """
+#     res= naturel % 2
+#     while naturel>1:
+#         res=res + (poids_binaire_recursif(naturel//2)%2)
+#     return res
+#     
+        
+
+def puissance(x: int|float, n: int) -> int|float:
+    """
+    Calcule x élevé à la puissance n
+
+    Précondition :
+        n>=0
+
+    Exemples :
+
+    $$$ puissance(10, 0)
+    1
+    $$$ puissance(10, 1)
+    10
+    $$$ puissance(2, 10)
+    1024
+    """
+    if n==0:
+        return 1
+    else:
+        return x*puissance(x,n-1)
+    
+
+def puissance_v2(x: int|float, n: int) -> int|float:
+    """
+    calcule  x élevé à la puissance n
+
+    Précondition :   n>=0
+
+    Exemples :
+    $$$ puissance_v2(10,0)
+    1
+    $$$ puissance_v2(10,1)
+    10
+    $$$ puissance_v2(2,10)
+    1024
+    """
+    if n==0:
+        return 1
+    else:
+        return fois(x, puissance_v2(x,n-1))
+
+@count
+def fois(x: int|float, y: int|float) -> int|float:
+    """
+    renvoie le produit de x par y
+
+    Précondition : les mêmes que l'opérateur *
+
+    Exemples :
+    $$$ fois(8, 7)
+    56
+    """
+    if y==0:
+        return 0
+    else:
+    
+        return x * y
+
+def comptage(puissance: Callable[[int|float, int], int|float]) -> list[int]:
+    """
+    Renvoie une liste de longueur 100 contenant le nombre de multiplications
+    effectuées par la fonction ``puissance`` passée en paramètre
+
+    Précondition :
+       la fonction doit être implantée en utilisant la fonction ``fois``
+    """
+    res = []
+    for i in range(100):
+        fois.counter = 0
+        _ = puissance(2, i)
+        res.append(fois.counter)
+    return res
+#Q1:
+# le paramétre c'est puissance
+#Q2:
+# le resultat sera une liste de longueure 100 contenant le nombre de multiplication
+#effectuées par la fonction puissanceà chaque itération de la boucle.
+#Q3:
+#calculons comptage(puissance):
+#[1,2,3,4,5,6,7,8,9,10,.......,100] , on obtient ce calcul pour mesurer
+# la complexité en nombre de multiplication de fonction puissance  et de la fonction 
+#puissance_v2, cela nous permet de comparer les performances de ces deux fonctions  de la valeur d
+#Q4:
+# on utilise le meme calcul comme d'avant : [1,2,3,4,5,6,7,8,9,10,.......,100]
+# on observant  les résultats sz comptage(puissance_v2), on peut remarquer que le nombre d'appels recursifs
+#de la fonction puissance_v2 correspond au nombre  d'éléments dans la liste, qui va de 1 à 100
+
+
+
+
+#@trace
+def puissance_calbuth(x: int|float, n: int) -> int|float:
+    """
+    calcule  x élevé à la puissance n
+
+    Précondition :
+        n>=0
+
+    Exemples :
+
+    $$$ puissance_calbuth(10,0)
+    1
+    $$$ puissance_calbuth(10,1)
+    10
+    $$$ puissance_calbuth(2,10)
+    1024
+
+    """
+    if n == 0:
+        return 1
+    if n == 1:
+        return x
+    else:
+        k = n // 2
+        return puissance_calbuth(x, k) * puissance_calbuth(x, n - k)
+
+def puissance_calbuth_v2(x: int|float, n: int) -> int|float:
+    """
+    calcule  x élevé à la puissance n
+
+    Précondition :
+        n>=0
+
+    Exemples :
+
+    $$$ puissance_calbuth_v2(10,0)
+    1
+    $$$ puissance_calbuth_v2(10,1)
+    10
+    $$$ puissance_calbuth_v2(2,10)
+    1024
+
+    """
+    if n==0:
+        return 1
+    elif n % 2==0:
+        temps=puissance_calbuth_v2(x,n//2)
+        return fois(temps,temps)
+    else:
+        temps=puissance_calbuth_v2(x,(n-1)//2)
+        return fois(fois(temps,temps),x)
+#Q5:
+    # oui l'idée de Raymond Calbuth permet de diminuer la compléxité en nombre de multiplications
+# dans le calcul de la puissance .
+#Q6:
+# le gain dépend du nombre de fois ou la puissance est dévisée par 2.
+#Q7:
+# la fonction de n
+    
+    
+
+
+def puissance_calbuth_v2_amelioree(x: int|float, n: int) -> int|float:
+    """
+    calcule  x élevé à la puissance n
+
+    Précondition :
+        n>=0
+
+    Exemples :
+
+    $$$ puissance_calbuth_v2_amelioree(10,0)
+    1
+    $$$ puissance_calbuth_v2_amelioree(10,1)
+    10
+    $$$ puissance_calbuth_v2_amelioree(2,10)
+    1024
+
+    """
+    ...
+
+def puissance_erronee(x: int|float, n: int) -> int|float:
+    """
+    aurait dû calculer  x élevé à la puissance n
+
+    Précondition :
+       n >= 0
+
+    Exemples :
+
+    $$$ puissance_erronee(10, 0)
+    1
+    $$$ puissance_erronee(10, 1)
+    10
+    $$$ #$$$ puissance_erronee(2, 10)
+    $$$ #1024
+    """
+    if n == 0:
+        return 1
+    elif n == 1:
+        return x
+    else:
+        r = n % 2
+        q = n // 2
+        return puissance_erronee(x, r) * puissance_erronee(puissance_erronee(x, q), 2)
+
+def puissance_reparee(x: int|float, n: int) -> int|float:
+    """
+    calcule  x élevé à la puissance n
+
+    Précondition :
+        n>=0
+
+    Exemples :
+
+    $$$ puissance_reparee(10,0)
+    1
+    $$$ puissance_reparee(10,1)
+    10
+    $$$ puissance_reparee(2,10)
+    1024
+    """
+    ...
+