From dcdc168b6e5fe59c7b0a189c799b56f1aecd278c Mon Sep 17 00:00:00 2001
From: Louis Chmielewski <louischmielewski@MacBook-Air-de-Louis.local>
Date: Wed, 13 Mar 2024 09:17:37 +0100
Subject: [PATCH] tp_tri liste_alea

---
 .DS_Store             | Bin 10244 -> 10244 bytes
 Projet/.DS_Store      | Bin 6148 -> 6148 bytes
 Projet/README.md      |   2 +-
 Projet/src/bloc.py    |  39 +++++++++
 Tp01/.DS_Store        | Bin 6148 -> 6148 bytes
 Tp05/.DS_Store        | Bin 6148 -> 6148 bytes
 Tp06/mesures.py       |   2 +-
 Tp07/analyse_tris.csv | 102 ++++++++++++++++++++++
 Tp07/analyse_tris.py  |  79 +++++++++++++++++
 Tp07/ap_decorators.py | 135 +++++++++++++++++++++++++++++
 Tp07/apl1test.py      |  89 +++++++++++++++++++
 Tp07/compare.py       |  44 ++++++++++
 Tp07/tp_tri.py        |  32 +++++++
 Tp07/tris.py          | 193 ++++++++++++++++++++++++++++++++++++++++++
 Tp07/tris_nbcomp.png  | Bin 0 -> 28343 bytes
 15 files changed, 715 insertions(+), 2 deletions(-)
 create mode 100644 Tp07/analyse_tris.csv
 create mode 100644 Tp07/analyse_tris.py
 create mode 100644 Tp07/ap_decorators.py
 create mode 100644 Tp07/apl1test.py
 create mode 100644 Tp07/compare.py
 create mode 100755 Tp07/tp_tri.py
 create mode 100644 Tp07/tris.py
 create mode 100644 Tp07/tris_nbcomp.png

diff --git a/.DS_Store b/.DS_Store
index 38ad5b6c7137d54edc2b705a4fac73bf004a534a..2123ae47bd8ef83e1b398d97f7ec8e2ce611ea62 100644
GIT binary patch
delta 1073
zcmZn(XbG6$FKElaz`)4BAi$85ZWx@LpIfl8a2or>2Eonj94s95AXyd$J%)6KOokGe
z3I-71>)XV@zyO!a&3AE0%E?b+U|`@dsCg-J;=)l!RQVLV@&y?X+d)P%C>nq$Him%7
zLIRSkjtmTpT9XX~eloL)m`v6Ylwo6FV9;1~ezKpSoH~RFwu_A+fT4&XpCOAOm7xU1
zJl2HGlLdnr>rp(Q@2v!OU<gA2g8_pfvIiI#8d$0~fDL6~fXgF1fK497Lj4Ai2jF_k
zf{XHU^7A&o6%uERwXZ?4)(F*F2ELuB)*9vJBU_6pk76xDz~)2|ZAK>Zy2*W_5};sm
z5866;ji?lic}7%*F=6vdQ7y*U-6lxRFhO-jgB;^-6yKYmIs;Q4)fpcq7l=np-YHT#
z`GkP`<hw!~le;DOnd<T;&yfJTs_NIF$-5-Lt^zS{Nk}s>7Hs}5q0JbZB!=WHGc;#0
zTb@I4mKmC}Fyv94)iAkUN@jAc2nVD2WElZ@PFVbyPhKa|C~U5yU}RxXtD{hDXkcQg
zqhM-aIr)x&G06G#<|rwLVG|^2LsEu0vLi!NR|uVfC4IO&A_}p|qdM{fa>_A>q@2x@
Tr2a5%W>@&d5-?y1hH*Cl^j-XW

delta 656
zcmZn(XbG6$FRI7Dz`)4BAi%(o%248&lb@WFlb^IPaWVU5b`BN}L69^XLjXe&Lq0<m
zNXg`>((;ox3%pZh00R`c+<X@okah+J29DCQ&9<gzCLa@&V}mkZ3Cc4uFl^=)3TE7V
zO<0aG7Hj|uLkL3wg8_pPvgW?R*;>^bjyf_hFd)gNzzxSHUyxxKoSdIq05+9@VRN9U
zHX{=Q!{j<K2{zXSr=D_dnmk8L3dY<cCd0_E`KFi_nlnt0opCe0vS-Uq6la*^<|CYe
zO&-k|lM^H&CL4+$o?Iiz4{}Yfqy$^4R<3N&zR9a4rC`j{lG31{c_FEd<{UF*=VaXs
pJo)PoigV16or6st-8lu)G8<EJSU0mP{9>8>QM4Q6ra=)xHUOIptxW&`

diff --git a/Projet/.DS_Store b/Projet/.DS_Store
index 3a2ffc2d18ce5b714e3d2e943b2a04fff657c174..012a194f43ef6645fe0c77bd378b13dfb3310c7b 100644
GIT binary patch
delta 81
zcmZoMXffEJ$;!;~O>MFcs|+gxL&Iyk$%U-KlM`5Z;5-E;R)x)zS)&=5Sf@_@z$V7Z
Zz`)>WKbf0d63WtKmu3{$?8?4h003lP6MX;x

delta 81
zcmZoMXffEJ$;!;Yz%W^dRfhFYU)mYl$%U-KlM`5Z;5-E;28PX(S)&=57#JphU=w4_
Z6|&N^o6OBF31w-rOEWTTc4gl$005Ge6$AhP

diff --git a/Projet/README.md b/Projet/README.md
index 0b83392..dd22c9e 100644
--- a/Projet/README.md
+++ b/Projet/README.md
@@ -4,5 +4,5 @@ author : Louis Chmielewski
 - - -
 
 # journal
-- 6/03 :
+- 11/03 : organisation de la résolution du projet
 
diff --git a/Projet/src/bloc.py b/Projet/src/bloc.py
index d58bde5..ae3edca 100755
--- a/Projet/src/bloc.py
+++ b/Projet/src/bloc.py
@@ -10,3 +10,42 @@
 
 """
 
+from PIL import Image, ImageDraw
+
+class Bloc:
+    """Classe d'un bloc d'une image en pixel
+    """
+
+    def __init__(self, image: Image):
+        """
+        $$$ 
+        """
+        self.image = image
+
+    def __repr__(self) -> str:
+        """
+        $$$ repr(DicoTrie([Association('a', 1)]))
+        "DicoTrie([Association('a', 1)])"
+        $$$ repr(DicoTrie([Association('a', 1), Association('b', 2)]))
+        "DicoTrie([Association('a', 1), Association('b', 2)])"
+        $$$ repr(DicoTrie([Association('c', 3), Association('a', 2), Association('b', 1)]))
+        "DicoTrie([Association('a', 2), Association('b', 1), Association('c', 3)])"
+        """
+        return f"DicoTrie({repr(self.liste_assos)})"
+
+    def __eq__(self, autre) -> bool:
+        """
+        $$$ d1 = DicoTrie([Association("a", 1), Association("b", 2)])
+        $$$ d2 = DicoTrie([Association("b", 2), Association("a", 1)])
+        $$$ d3 = DicoTrie([Association("a", 1), Association("b", 2), Association("c", 3)])
+        $$$ d1 == d2
+        True
+        $$$ d1 == d3
+        False
+        $$$ d1 == {"a": 1, "b": 2}
+        False
+        """
+        if isinstance(autre, DicoTrie):
+            return self.liste_assos == autre.liste_assos
+        else:
+            return False
\ No newline at end of file
diff --git a/Tp01/.DS_Store b/Tp01/.DS_Store
index 1ea4f8f77ec5d17550335a7756d70e129b54b52b..d2da421d72d10f2f3c6366735076c36fe4c04cf1 100644
GIT binary patch
delta 302
zcmZoMXfc=|#>B!ku~2NHo+2aH#(>?7iyN4k7`Zm{Fa<Hz=cF43C+FuDFo1w~=X3@J
z26l!VhE#?MhD?S+hEj&q+<X_8q@4UD1_lNW1_p++%xjK1VpEkugsOrJWZM=nFiiGk
zR!HSSwU9xNp@5;%GbcY8YOMeR1EVYh1B2dwFaWuffg3|l2}1=#37W2Mgs#nn%u5+J
hvvcrsFtKoLE@b}BJegm_k%N(efeB>b<_M8B%mBqUN)rG8

delta 71
zcmZoMXfc=|#>B)qu~2NHo+2a5#(>?7j4YdZSb`WQzhmX!EW#noGO?k3Gdl-A2NM(L
cW<iec%#-;=961;m7#J8C7+5w(h^%1-0E+_<f&c&j

diff --git a/Tp05/.DS_Store b/Tp05/.DS_Store
index 3e0563300041a8e1f12e167e8a09a7b9782e4e03..5b10303b2ee0c66a010d9c83b7955f08361dac24 100644
GIT binary patch
delta 169
zcmZoMXfc@J&&ahgU^gQp*JK{1%k``bnGDGc`3!js#X0GQ!O8i#1q@&y)6BrYfFzrn
z@8Xh_lb^)Ez`()4&|n<2@2DfXiWCAW3Nnywc)-BGF!>&nEhGD62__jPru5A`%)Ts}
J**X650|0mpC$|6q

delta 35
rcmZoMXfc@J&&awlU^gQp>tr6L%ah}oZ8o1|wqu#tux>Lu$6tN`&d3Y|

diff --git a/Tp06/mesures.py b/Tp06/mesures.py
index 5ab31e0..6677b6b 100755
--- a/Tp06/mesures.py
+++ b/Tp06/mesures.py
@@ -15,7 +15,7 @@ from association import Association
 from types import NoneType
 from timeit import timeit
 from random import randrange
-#import matplotlib.pyplot as plt
+import matplotlib.pyplot as plt
 
 def generation_dict(tailles: list[int]) -> list[dict[str, NoneType]]:
     """Renvoie une liste de dictionnaires dont les clés sont les
diff --git a/Tp07/analyse_tris.csv b/Tp07/analyse_tris.csv
new file mode 100644
index 0000000..7526113
--- /dev/null
+++ b/Tp07/analyse_tris.csv
@@ -0,0 +1,102 @@
+taille;"tri séléction";"tri insertion"
+  0;    0.00;    0.00
+  1;    0.00;    0.00
+  2;    1.00;    1.00
+  3;    3.00;    2.62
+  4;    6.00;    4.96
+  5;   10.00;    7.72
+  6;   15.00;   11.44
+  7;   21.00;   15.40
+  8;   28.00;   19.02
+  9;   36.00;   24.62
+ 10;   45.00;   28.80
+ 11;   55.00;   35.70
+ 12;   66.00;   40.96
+ 13;   78.00;   50.26
+ 14;   91.00;   56.38
+ 15;  105.00;   66.54
+ 16;  120.00;   73.34
+ 17;  136.00;   81.82
+ 18;  153.00;   94.12
+ 19;  171.00;  103.36
+ 20;  190.00;  109.78
+ 21;  210.00;  121.60
+ 22;  231.00;  131.76
+ 23;  253.00;  143.06
+ 24;  276.00;  156.52
+ 25;  300.00;  175.36
+ 26;  325.00;  182.90
+ 27;  351.00;  192.02
+ 28;  378.00;  212.32
+ 29;  406.00;  227.84
+ 30;  435.00;  243.40
+ 31;  465.00;  262.58
+ 32;  496.00;  278.14
+ 33;  528.00;  293.86
+ 34;  561.00;  312.92
+ 35;  595.00;  332.28
+ 36;  630.00;  344.32
+ 37;  666.00;  354.34
+ 38;  703.00;  397.18
+ 39;  741.00;  410.56
+ 40;  780.00;  429.42
+ 41;  820.00;  453.40
+ 42;  861.00;  461.80
+ 43;  903.00;  485.46
+ 44;  946.00;  517.10
+ 45;  990.00;  540.00
+ 46; 1035.00;  554.30
+ 47; 1081.00;  575.34
+ 48; 1128.00;  607.34
+ 49; 1176.00;  620.18
+ 50; 1225.00;  647.48
+ 51; 1275.00;  693.96
+ 52; 1326.00;  712.04
+ 53; 1378.00;  732.64
+ 54; 1431.00;  768.84
+ 55; 1485.00;  794.12
+ 56; 1540.00;  820.92
+ 57; 1596.00;  822.34
+ 58; 1653.00;  877.84
+ 59; 1711.00;  917.66
+ 60; 1770.00;  948.42
+ 61; 1830.00;  956.04
+ 62; 1891.00; 1005.00
+ 63; 1953.00; 1042.60
+ 64; 2016.00; 1037.82
+ 65; 2080.00; 1087.02
+ 66; 2145.00; 1147.22
+ 67; 2211.00; 1184.68
+ 68; 2278.00; 1215.44
+ 69; 2346.00; 1239.10
+ 70; 2415.00; 1247.28
+ 71; 2485.00; 1310.14
+ 72; 2556.00; 1336.78
+ 73; 2628.00; 1395.50
+ 74; 2701.00; 1417.10
+ 75; 2775.00; 1464.58
+ 76; 2850.00; 1482.62
+ 77; 2926.00; 1545.84
+ 78; 3003.00; 1566.48
+ 79; 3081.00; 1622.52
+ 80; 3160.00; 1637.64
+ 81; 3240.00; 1686.34
+ 82; 3321.00; 1740.88
+ 83; 3403.00; 1789.50
+ 84; 3486.00; 1814.38
+ 85; 3570.00; 1857.88
+ 86; 3655.00; 1929.30
+ 87; 3741.00; 1980.88
+ 88; 3828.00; 1973.52
+ 89; 3916.00; 2066.94
+ 90; 4005.00; 2085.78
+ 91; 4095.00; 2125.72
+ 92; 4186.00; 2220.08
+ 93; 4278.00; 2240.44
+ 94; 4371.00; 2283.70
+ 95; 4465.00; 2359.88
+ 96; 4560.00; 2385.16
+ 97; 4656.00; 2450.00
+ 98; 4753.00; 2473.96
+ 99; 4851.00; 2531.32
+100; 4950.00; 2564.28
diff --git a/Tp07/analyse_tris.py b/Tp07/analyse_tris.py
new file mode 100644
index 0000000..9d12c34
--- /dev/null
+++ b/Tp07/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/Tp07/ap_decorators.py b/Tp07/ap_decorators.py
new file mode 100644
index 0000000..5f4adc9
--- /dev/null
+++ b/Tp07/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/Tp07/apl1test.py b/Tp07/apl1test.py
new file mode 100644
index 0000000..8533cca
--- /dev/null
+++ b/Tp07/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/Tp07/compare.py b/Tp07/compare.py
new file mode 100644
index 0000000..abad0a4
--- /dev/null
+++ b/Tp07/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/Tp07/tp_tri.py b/Tp07/tp_tri.py
new file mode 100755
index 0000000..bd3545d
--- /dev/null
+++ b/Tp07/tp_tri.py
@@ -0,0 +1,32 @@
+#!/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: mars 2024
+
+
+Tris de listes
+
+- tri par sélection
+- tri par insertion
+
+"""
+
+from random import shuffle
+import matplotlib.pyplot as plt
+
+def liste_alea(n:int) -> list[int]:
+    """
+    Renvoie une liste de 0 à n-1 mélangé
+    Précondition : aucune
+    Exemple(s) :
+    $$$ 
+
+    """
+    res = list(range(n))
+    shuffle(res)
+    return res
\ No newline at end of file
diff --git a/Tp07/tris.py b/Tp07/tris.py
new file mode 100644
index 0000000..18df740
--- /dev/null
+++ b/Tp07/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/Tp07/tris_nbcomp.png b/Tp07/tris_nbcomp.png
new file mode 100644
index 0000000000000000000000000000000000000000..a2ce8bdaaad372e005af87d22e90db36c52fb421
GIT binary patch
literal 28343
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
XxwL9&T!SV90|SGntDnm{r-UW|=}iBV

literal 0
HcmV?d00001

-- 
GitLab