Skip to content
Snippets Groups Projects
Commit a131833c authored by Koffi Gantchou's avatar Koffi Gantchou
Browse files

depot assosciation

parent 1304e84d
No related branches found
No related tags found
No related merge requests found
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.58
4; 6.00; 4.84
5; 10.00; 7.82
6; 15.00; 10.74
7; 21.00; 14.76
8; 28.00; 18.62
9; 36.00; 23.88
10; 45.00; 29.48
11; 55.00; 35.44
12; 66.00; 39.98
13; 78.00; 48.62
14; 91.00; 56.32
15; 105.00; 64.10
16; 120.00; 75.32
17; 136.00; 81.48
18; 153.00; 88.88
19; 171.00; 104.48
20; 190.00; 111.56
21; 210.00; 119.32
22; 231.00; 136.48
23; 253.00; 146.52
24; 276.00; 160.48
25; 300.00; 172.12
26; 325.00; 187.32
27; 351.00; 198.28
28; 378.00; 208.10
29; 406.00; 226.10
30; 435.00; 242.86
31; 465.00; 259.78
32; 496.00; 272.96
33; 528.00; 299.78
34; 561.00; 311.58
35; 595.00; 327.34
36; 630.00; 343.84
37; 666.00; 359.14
38; 703.00; 375.68
39; 741.00; 405.78
40; 780.00; 428.62
41; 820.00; 451.92
42; 861.00; 463.04
43; 903.00; 476.76
44; 946.00; 523.76
45; 990.00; 532.12
46; 1035.00; 559.54
47; 1081.00; 590.20
48; 1128.00; 603.06
49; 1176.00; 622.30
50; 1225.00; 650.64
51; 1275.00; 691.52
52; 1326.00; 711.02
53; 1378.00; 747.72
54; 1431.00; 761.70
55; 1485.00; 799.58
56; 1540.00; 811.42
57; 1596.00; 836.24
58; 1653.00; 875.78
59; 1711.00; 901.02
60; 1770.00; 943.02
61; 1830.00; 980.46
62; 1891.00; 1013.62
63; 1953.00; 1011.48
64; 2016.00; 1060.82
65; 2080.00; 1096.54
66; 2145.00; 1106.42
67; 2211.00; 1157.74
68; 2278.00; 1210.80
69; 2346.00; 1204.30
70; 2415.00; 1287.48
71; 2485.00; 1320.34
72; 2556.00; 1363.24
73; 2628.00; 1359.50
74; 2701.00; 1442.94
75; 2775.00; 1465.80
76; 2850.00; 1508.88
77; 2926.00; 1539.72
78; 3003.00; 1579.54
79; 3081.00; 1621.52
80; 3160.00; 1654.10
81; 3240.00; 1699.60
82; 3321.00; 1722.82
83; 3403.00; 1784.30
84; 3486.00; 1846.20
85; 3570.00; 1833.66
86; 3655.00; 1903.94
87; 3741.00; 1976.24
88; 3828.00; 2020.98
89; 3916.00; 2025.96
90; 4005.00; 2064.60
91; 4095.00; 2149.46
92; 4186.00; 2201.64
93; 4278.00; 2235.34
94; 4371.00; 2250.64
95; 4465.00; 2323.24
96; 4560.00; 2389.64
97; 4656.00; 2409.42
98; 4753.00; 2475.90
99; 4851.00; 2497.80
100; 4950.00; 2612.10
#!/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()
#!/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 *
import timeit
from fonction import liste_alea
################################################
# 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)
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_sort[t] = analyser_tri(tri_sort, 1, 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],c_sort[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_sort, 'g.', 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()
print(timeit.timeit(stmt='liste_alea(100)', setup='from fonction import liste_alea', number=5000));
\ No newline at end of file
#!/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)
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))
#!/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')
# gantchou koffi
#mi13
#20/03/2025
from random import shuffle
def liste_alea(n:int)->list[int]:
""" à_remplacer_par_ce_que_fait_la_fonction
Précondition :
Exemple(s) :
$$$ liste_alea(3)
[2, 0, 1]
"""
liste = [i for i in range(n)]
shuffle(liste)
return liste
import matplotlib.pyplot as plt
abscisses = [1,2,4]
ordonnees = [2,5,0]
plt.plot(abscisses, ordonnees, color = 'blue')
plt.show
from ap_decorators import count
from compare import compare
C'est range qui permet de construire une liste d'entiers de 0 a n-1
Au vu es courbes obtenues on deduit que avec la methode sort est plus optimise que le tri par insertion qui a son tour plus optimiser que par selection
18.105114018002496
#!/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 random import shuffle
from types import NoneType
from typing import Callable, TypeVar
from compare import compare
from functools import cmp_to_key
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
def tri_sort(liste: list[T], compare: int)->list[T]:
""" à_remplacer_par_ce_que_fait_la_fonction
Précondition :
Exemple(s) :
$$$
"""
liste.sort(key=cmp_to_key(compare))
return liste
if (__name__ == '__main__'):
import apl1test
apl1test.testmod('tris.py')
analyse-tris/tris_nbcomp.png

29.1 KiB

#!/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)
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))
#!/usr/bin/python3
# -*- coding: utf-8 -*-
"""
:mod:`association` module : un module pour les associations clé-valeur
:author: `FIL - Faculté des Sciences et Technologies -
Univ. Lille <http://portail.fil.univ-lille1.fr>`_
:date: 2024 février
"""
from ap_decorators import count
from typing import TypeVar
# On définit deux types génériques :
# - C pour le type des clés
# - V pour le type des valeurs
C = TypeVar('C')
V = TypeVar('V')
class Association:
"""Classe d'une association clé-valeur
"""
def __init__(self, cle: C, valeur: V):
"""
$$$ asso1 = Association('a', 1)
$$$ asso1.cle
'a'
$$$ asso1.valeur
1
"""
self.cle = cle
self.valeur = valeur
def __repr__(self) -> str:
"""
$$$ repr(Association(2, 3))
'Association(2, 3)'
$$$ repr(Association('a', 1))
"Association('a', 1)"
$$$ repr(Association((1, True), [1, 2, 3]))
'Association((1, True), [1, 2, 3])'
$$$ repr(Association(1+1 == 2, "Vrai"))
"Association(True, 'Vrai')"
"""
return f"Association({repr(self.cle)}, {repr(self.valeur)})"
def __eq__(self, autre) -> bool:
"""
$$$ Association('a', 1) == Association('a', 1)
True
$$$ Association('a', 1) == Association('a', 2)
False
$$$ Association('a', 1) == Association(1, 'a')
False
$$$ Association('a', 1) == ('a', 1)
False
"""
if not isinstance(autre,Association):
return False
a = (self.cle == autre.cle)
b = (self.valeur == autre.valeur)
return a and b
@count
def comp_asso(a1: Association, a2: Association) -> int:
"""Renvoie 0 si les clés de a1 et a2 sont identiques
-1 si la clé de a1 < la clé de a2
1 si la clé de a1 > la clé de a2
Precondition : les clés de a1 et a2 sont comparables
$$$ comp_asso(Association(1, 'a'), Association(1, 'c'))
0
$$$ comp_asso(Association(1, 'a'), Association(2, 'a'))
-1
$$$ comp_asso(Association(1, 'd'), Association(0, 'c'))
1
"""
if a1.cle ==a2.cle:
res = 0
elif a1.cle< a2.cle:
res = -1
else:
res = 1
return res
if __name__ == '__main__':
import apl1test
apl1test.testmod('association.py')
#!/usr/bin/python3
# -*- coding: utf-8 -*-
"""
:mod:`dicotrie` module : un module pour les ensembles d'associations
:author: `FIL - Faculté des Sciences et Technologies -
Univ. Lille <http://portail.fil.univ-lille1.fr>`_
:date: 2024 février
"""
from association import Association, C, V, comp_asso
from recherches import indice_dicho, inserer
from types import NoneType
class DicoTrie:
"""Classe d'une association clé-valeur
"""
def __init__(self, liste_assos: list[Association]):
"""
"""
self.liste_assos = []
for asso in liste_assos:
self.__setitem__(asso.cle,asso.valeur)
def __str__(self)->str:
""" à_remplacer_par_ce_que_fait_la_fonction
Précondition :
Exemple(s) :
$$$
"""
return f"DicoTrie({self.liste_assos})"
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({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 not (isinstance(autre,DicoTrie) and len(self.liste_assos) == len(autre.liste_assos)):
return False
for asso in self.liste_assos:
if asso not in autre.liste_assos:
return False
return True
def __setitem__(self, cle: C, valeur: V) -> NoneType:
"""
$$$ d1 = DicoTrie([Association("a", 1), Association("b", 2)])
$$$ d1["c"] = 3
$$$ d1
DicoTrie([Association("a", 1), Association("b", 2), Association("c", 3)])
"""
for i in range(len(self.liste_assos)):
if cle < self.liste_assos[i].cle:
self.liste_assos.insert(i,Association(cle,valeur))
return
self.liste_assos.append(Association(cle,valeur))
def __getitem__(self, cle: C) -> V:
"""
$$$ d1 = DicoTrie([Association("a", 1), Association("b", 2)])
$$$ d1['a']
1
$$$ d1['b']
2
$$e d1['c']
KeyError
"""
for asso in self.liste_assos:
if asso.cle == cle:
return asso.valeur
raise KeyError("la clé n'a pas été trouvée")
def __delitem__(self, cle: C) -> NoneType:
"""
$$$ d1 = DicoTrie([Association("a", 1), Association("b", 2)])
$$$ del d1['a']
$$$ d1
DicoTrie([Association("b", 2)])
$$e del d1['c']
KeyError
"""
for asso in self.liste_assos:
if asso.cle == cle:
self.liste_assos.remove(asso)
return
raise KeyError("la clé n'a pas été trouvée")
def __contains__(self, cle: C) -> bool:
"""
$$$ d1 = DicoTrie([Association("a", 1), Association("b", 2)])
$$$ 'a' in d1
True
$$$ 'c' in d1
False
"""
for asso in self.liste_assos:
if cle == asso.cle:
return True
return False
if __name__ == '__main__':
import apl1test
apl1test.testmod('dicotrie.py')
#!/usr/bin/python3
# -*- coding: utf-8 -*-
"""
:mod:`mesures` module : un module pour les mesures de temps
:author: `FIL - Faculté des Sciences et Technologies -
Univ. Lille <http://portail.fil.univ-lille1.fr>`_
:date: 2024 février
"""
from dicotrie import DicoTrie
from association import Association
from types import NoneType
from timeit import timeit
from random import randrange
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
représentations des n entiers compris entre 0 et n-1 et les valeurs
associées None pour chaque entier n dans la liste tailles.
Précondition : tous les entiers de tailles sont positifs ou nuls
$$$ generation_dict([0, 2, 4])
[{}, {'0': None, '1':None}, {'0': None, '1': None, '2': None, '3': None}]
"""
liste = []
for taille in tailles:
dico = {}
for i in range(taille):
dico[str(i)] = None
liste.append(dico)
return liste
def generation_dicotrie(tailles: list[int]) -> list[DicoTrie]:
"""Renvoie une liste de DicoTrie dont les clés sont les représentations
des n entiers compris entre 0 et n-1 et les valeurs associées None pour
chaque entier n dans la liste tailles.
Précondition : tous les entiers de tailles sont positifs ou nuls
$$$ generation_dicotrie([0, 2])
[DicoTrie([]), DicoTrie([Association('0', None), Association('1', None)])]
"""
result = []
for n in tailles:
associations = [Association(str(i), None) for i in range(n)]
result.append(DicoTrie(associations))
return result
def mesure_temps_acces(taille : int, d: dict[str, NoneType] | DicoTrie) -> float:
"""Renvoie le temps moyen mis pour accéder à 1000 éléments quelconques
du dictionnaire d.
Précondition : les clés de d sont les représentations des entiers
compris entre 0 et taille - 1.
"""
cles_a_tester = [str(randrange(taille)) for _ in range(1000)]
stmt = "all(d[cle] == None for cle in cles_a_tester)"
return timeit(stmt = stmt, globals = locals(), number = 1) / 1000
def mesures_temps_acces_dict(tailles: list[int]) -> list[float]:
"""Renvoie les listes des temps moyens pour accéder à 1000 éléments quelconques
de chacun des dictionnaires dont les clés sont les remprésentations des
n entiers compris entre 1 et n-1 pour chaque entier n dans la liste
tailles.
Précondition : tous les entiers de tailles sont positifs ou nuls
"""
res = []
d = generation_dict(tailles)
def mesures_temps_acces_dicotrie(tailles: list[int]) -> list[float]:
"""Renvoie les listes des temps moyens pour accéder à 1000 éléments quelconques
de chacun des DicoTrie dont les clés sont les remprésentations des
n entiers compris entre 1 et n-1 pour chaque entier n dans la liste
tailles.
Précondition : tous les entiers de tailles sont positifs ou nuls
"""
...
if __name__ == '__main__':
import apl1test
apl1test.testmod('mesures.py')
# Écrivez ici le code permettant de faire des hypothèses sur la
# vitesse d'accès aux dictionnaires.
# linéaire
# tailles = list(range(1, 100000, 1000)
# temps_dict = mesures_temps_acces_dict(tailles)
# temps_dicotrie = mesures_temps_acces_dicotrie(tailles)
# plt.plot(tailles, temps_dict, '+')
# plt.plot(tailles, temps_dicotrie, '.')
# plt.show()
# log
# tailles = [2**n for n in range(16)]
# temps_dict = mesures_temps_acces_dict(tailles)
# temps_dicotrie = mesures_temps_acces_dicotrie(tailles)
# plt.plot(range(16), temps_dict, '+')
# plt.plot(range(16), temps_dicotrie, '.')
# plt.show()
#!/usr/bin/python3
# -*- coding: utf-8 -*-
"""
:mod:`recherches` module : un module pour les recherches
:author: `FIL - Faculté des Sciences et Technologies -
Univ. Lille <http://portail.fil.univ-lille1.fr>`_
:date: 2024 février
"""
from typing import TypeVar, Callable
from types import NoneType
# On définit un type générique :
C = TypeVar('C')
def indice_seq(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
* i = len(liste)
Précondition : comp est une fonction de comparaison sur C
$$$ def compare(x, y): return 0 if x == y else 1 if x > y else -1
$$$ indice_seq(0, [1, 3, 5], compare)
(False, 3)
$$$ indice_seq(3, [1, 3, 5], compare)
(True, 1)
$$$ indice_seq(4, [1, 3, 5], compare)
(False, 3)
$$$ indice_seq(5, [1, 3, 5], compare)
(True, 2)
$$$ indice_seq(6, [1, 3, 5], compare)
(False, 3)
$$$ indice_seq(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)
"""
if len(liste) == 0:
return (False, 0)
trouve = False
i = 0
res = len(liste)-1
while i < len(liste) and not trouve:
cmp = comp(elem , liste[i])
if cmp == 0:
trouve = True
res = i
elif cmp==-1:
trouve = False
res = elem
else:
trouve = False
res = len(liste)
i+=1
return (trouve,res)
def inserer(indice: int, elem: C, liste: list[C]) -> NoneType:
"""Insère l'élément elem à l'indice indice de la liste liste.
Précondition : 0 ≤ indice ≤ len(liste)
$$$ l = [1, 3, 5]
$$$ inserer(0, 0, l)
$$$ l
[0, 1, 3, 5]
$$$ inserer(4, 6, l)
$$$ l
[0, 1, 3, 5, 6]
$$$ inserer(3, 4, l)
$$$ l
[0, 1, 3, 4, 5, 6]
$$$ vide = []
$$$ inserer(0, 42, vide)
$$$ vide
[42]
"""
licopier = liste.copy()
for i in range(len(licopier)):
licopier[indice] = elem
licopier[i] = licopier[i+1]
licopier.append(liste[-1])
return licopier
if __name__ == '__main__':
import apl1test
apl1test.testmod('recherches.py')
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment