From 8d4214dc33206989bdebe27dba2a6fbc200997ef Mon Sep 17 00:00:00 2001
From: david <david@lipn.fr>
Date: Mon, 9 Sep 2019 09:37:25 +0200
Subject: [PATCH] Ajout des fichiers Python du TP1

---
 TP1/Python/analyzer.py  | 66 +++++++++++++++++++++++++++++++++++++++++
 TP1/Python/arraylist.py | 28 +++++++++++++++++
 TP1/Python/main.py      | 26 ++++++++++++++++
 3 files changed, 120 insertions(+)
 create mode 100644 TP1/Python/analyzer.py
 create mode 100644 TP1/Python/arraylist.py
 create mode 100644 TP1/Python/main.py

diff --git a/TP1/Python/analyzer.py b/TP1/Python/analyzer.py
new file mode 100644
index 0000000..ca4d581
--- /dev/null
+++ b/TP1/Python/analyzer.py
@@ -0,0 +1,66 @@
+import math
+
+#  Classe utilisée pour faire des statistiques élémentaires
+#  sur une séquence d'opérations.
+class Analyzer:
+    # Constructeur de la classe analyse
+    # Complexité en temps/espace, pire et meilleur cas : O(1)  
+    def __init__(self):
+        self.cost = [];
+        self.cumulative_cost = [];
+        self.cumulative_square = 0.;
+
+    # Ajoute un coût, une valeur à l'analyse.
+    # Complexité en temps/espace, pire cas : O(size)
+    # Complexité en temps/espace, meilleur cas : O(1)
+    # Complexité amortie : O(1)
+    # @param x est la valeur que l'on souhaite ajouter à l'analyse.
+    def append(self, x):
+        self.cost.append(x)
+        
+        self.cumulative_cost.append( self.cumulative_cost[len(self.cumulative_cost)-1]+x if len(self.cumulative_cost)>0 else x)
+        self.cumulative_square = self.cumulative_square+x*x
+
+    # Renvoie la somme des coûts enregistrés dans cette analyse.
+    # Complexité en temps/espace, meilleur cas : O(1)
+    # @returns la somme des coûts enregistrés dans cette analyse.
+    def get_total_cost(self):
+        return self.cumulative_cost[len(self.cumulative_cost)-1]
+
+    # Renvoie le coût amorti d'une opération.
+    # Complexité en temps/espace, meilleur cas : O(1)
+    # @param pos est l'indice de l'opération pour laquelle on veut connaître le coût amorti.
+    # @returns le coût amorti d'une opération.    
+    def get_amortized_cost(self, pos):
+        return self.cumulative_cost[pos]/pos if pos>0 else self.cumulative_cost[pos] 
+
+    # Renvoie la moyenne des coûts de toutes les opérations enregistrées dans l'analyse.
+    # Complexité en temps/espace, meilleur cas : O(1)
+    # @returns la moyenne des coûts de toutes les opérations enregistrées dans l'analyse.
+    def get_average_cost(self):
+        if len(self.cumulative_cost) == 0:
+            raise Exception('List is empty')
+        return self.cumulative_cost[len(self.cumulative_cost)-1]/len(self.cumulative_cost);
+
+    # Renvoie la variance des coûts de toutes les opérations enregistrées dans l'analyse.
+    # Complexité en temps/espace, meilleur cas : O(1)
+    # @returns la variance des coûts de toutes les opérations enregistrées dans l'analyse.
+    def get_variance(self):
+        mean = self.get_average_cost()
+        mean_square = mean*mean
+        return self.cumulative_square - mean_square
+
+    # Renvoie l'écart-type des coûts de toutes les opérations enregistrées dans l'analyse.
+    # Complexité en temps/espace, meilleur cas : O(1)
+    # @returns l'écart-type des coûts de toutes les opérations enregistrées dans l'analyse.
+    def get_standard_deviation(self):
+        return math.sqrt(self.get_variance())
+
+    # Sauvegarde la liste des coûts et des coûts amortis dans un fichier.
+    # Complexité en temps, meilleur/pire cas : O(size)
+    # @param path est le chemin du fichier dans lequel la sauvegarde est faite.
+    def save_values(self, path):
+        f = open(path, 'w')
+        for i in range(len(self.cost)):
+            f.write(str(i)+" "+str(self.cost[i])+"  "+str(self.get_amortized_cost(i))+"\n")
+        f.close()
diff --git a/TP1/Python/arraylist.py b/TP1/Python/arraylist.py
new file mode 100644
index 0000000..a4ab582
--- /dev/null
+++ b/TP1/Python/arraylist.py
@@ -0,0 +1,28 @@
+# Cette classe est un simple proxy vers le type "list" de python
+# Le langage ne permettant pas de manipuler l'espace mémoire d'une "list",
+# on se contente ici d'observer son comportement.
+class ArrayListProxy:
+    # Constructeur de la classe ArraylistProxy
+    def __init__(self):
+        self.data = []
+
+    # Ajoute l'élément x au tableau
+    #   Complexité en temps/espace, pire cas : O(data.size)
+    #   Complexité en temps/espace, meilleur cas : O(1)
+    #   Complexité amortie : O(1)
+    def append(self, x):
+        self.data.append(x)
+
+    # Supprime le dernier élément du tableau
+    def pop_back(self):
+        self.data.pop()
+
+    # Renvoie l'élément situé à la position 'pos' dans le tableau
+    def get(self, pos):
+        return self.data[pos]
+
+    # Renvoie le nombre d'éléments dans le tableau
+    def get_size(self):
+        return len(data)
+
+        
diff --git a/TP1/Python/main.py b/TP1/Python/main.py
new file mode 100644
index 0000000..3d5e522
--- /dev/null
+++ b/TP1/Python/main.py
@@ -0,0 +1,26 @@
+import time
+import sys
+
+from arraylist import ArrayListProxy
+from analyzer import Analyzer
+
+# Tableau dynamique.
+a = ArrayListProxy()
+# Analyse du temps pris par les opérations.
+time_analysis = Analyzer();
+
+for i in range(1000000):
+    before = time.time()
+    a.append(i)
+    after = time.time()
+    # Enregistrement du temps pris par l'opération
+    time_analysis.append((after - before)*10**9)
+
+# Affichage de quelques statistiques sur l'expérience.
+sys.stderr.write("Total cost : " + str(time_analysis.get_total_cost())+"\n")
+sys.stderr.write("Average cost : " + str(time_analysis.get_average_cost())+"\n")
+sys.stderr.write("Variance :" + str(time_analysis.get_variance())+"\n")
+sys.stderr.write("Standard deviation :" + str(time_analysis.get_standard_deviation())+"\n")
+
+// Sauvegarde les données de l'expérience: temps et temps amorti par opération.
+time_analysis.save_values("../dynamic_array_time_python.plot")
-- 
GitLab