diff --git a/pymath/stat/dataset.py b/pymath/stat/dataset.py index 81db07c..dd5b9fc 100644 --- a/pymath/stat/dataset.py +++ b/pymath/stat/dataset.py @@ -10,7 +10,20 @@ from math import sqrt, ceil class Dataset(list): - """ Classe réprésentant un série statistique avec rendu latex """ + """ A dataset (a list) with statistics and latex rendering methods + + >>> s = Dataset(range(100)) + >>> s.sum() + 4950 + >>> s.mean() + 49.5 + >>> s.deviation() + 83325.0 + >>> s.variance() + 833.25 + >>> s.sd() + 28.86607004772212 + """ def __init__(self, data = [], data_name = "Valeurs"): """ @@ -33,15 +46,14 @@ class Dataset(list): except TypeError: self += [data] - def sort(self, *args, **kwrds): - """ Apply sort to data """ - self.sort(*args, **kwrds) + def effectif_total(self): + return len(self) def sum(self): return sum(self) def mean(self): - return self.sum()/len(self) + return self.sum()/self.effectif_total() def deviation(self): """ Compute the deviation (not normalized) """ @@ -49,7 +61,7 @@ class Dataset(list): return sum([(x - mean)**2 for x in self]) def variance(self): - return self.deviation()/len(self) + return self.deviation()/self.effectif_total() def sd(self): """ Compute the standard deviation """ @@ -57,9 +69,13 @@ class Dataset(list): def quartiles(self): """ - Compute quartiles + Calcul les quartiles de la série. - :return: (min, Q1, Me, Q3, Max) + :return: un tuple avec (min, Q1, Me, Q3, Max) + + >>> w = Dataset(range(12)) + >>> w.quartiles() + (0, 2.5, 5.5, 8.5, 11) """ return (min(self) , self.quartile(1) , self.quartile(2) , self.quartile(3), max(self)) @@ -73,14 +89,28 @@ class Dataset(list): : Example: - >>> s = Dataset([2, 3, 4, 5, 6, 6, 6, 7]) - >>> + >>> w = Dataset(range(12)) + >>> w.quartile(1) + 2.5 + >>> w.quartile(2) + 5.5 + >>> w.quartile(3) + 8.5 + >>> w = Dataset(range(14)) + >>> w.quartile(1) + 3 + >>> w.quartile(2) + 6.5 + >>> w.quartile(3) + 10 """ - position = self.posi_quartile(quartile)[0] - # À vérifier... - return self[position] - + # -1 to match with list indexing + position = self.posi_quartile(quartile) - 1 + if position.is_integer(): + return (self[int(position)] + self[int(position)+1])/2 + else: + return self[ceil(position)] def posi_quartile(self, quartile = 1): """ @@ -90,9 +120,89 @@ class Dataset(list): :return : la position du quartile (arondis à l'entier suppérieur, non arrondis) """ - return (ceil(quartile * self.effectif_total / 4), (quartile * self.effectif_total / 4)) + return quartile * self.effectif_total() / 4 + # -------------------------- + # Rendu latex + + def moyenne_latex(self, val_cara = "x", eff_cara = "n", end_cara = "p", moy_cara= "\\bar{x}"): + """ + Renvoie le code latex pour afficher le calcul de la moyenne + + :param val_cara: caractère représentant les valeurs (x par défaut) + :param eff_cara: caractère représentant les effectifs (n par défaut) + :param end_cara: caractère représentant le nombre de valeurs (p par défaut) + :param moy_cara: nom de la moyenne (\\bar{x} par défaut) + + :return: le code latex pour afficher le calcul de la moyenne + """ + moy = self.moyenne() + latex = moy_cara + " &=& " + latex += "\\frac{{{x}_1 \\times {n}_1 + {x}_2 \\times {n}_2 + ... + {x}_{p} \\times {n}_{p}}}{{{n}_1 + {n}_2 + ... + {n}_p}} \\\\ \n".format(x = val_cara, n=eff_cara, p = end_cara) + latex += "\t &=& \\frac{" + for (i,v) in enumerate(self.valeurs): + latex += "{x:.2f} \\times {p:.2f} + ".format(x = v, p = self.effectifs[i]) + latex = latex[:-2] # on enlève le + et l'espace de fin de calcul + latex += "}}{{{eff_tot}}}\\\\ \n".format(eff_tot = self.effectif_total) + latex += "\t &=& {moy:.2f}".format(moy=moy) + + return latex + + def variance_latex(self, val_cara = "x", eff_cara = "n", end_cara = "p", moy_cara= "\\bar{x}", var_cara = "V"): + """ + Renvoie le code latex pour afficher le calcul de la moyenne + + :param val_cara: caractère représentant les valeurs (x par défaut) + :param eff_cara: caractère représentant les effectifs (n par défaut) + :param end_cara: caractère représentant le nombre de valeurs (p par défaut) + :param moy_cara: nom de la moyenne (\\bar{x} par défaut) + :param var_var: nom de la variance (V par défaut) + + :return: le code latex pour afficher le calcul de la moyenne + """ + moy = self.moyenne() + var = self.variance() + + latex = var_cara + " &=& " + latex += "\\frac{{ {n}_1 ({x}_1 - {moy})^2 + {n}_2 ({x}_2 - {moy})^2 + ... + {n}_{p} ({x}_{p} - {moy})^2}}{{{n}_1 + {n}_2 + ... + {n}_p}}\\\\ \n".format(x = val_cara, n=eff_cara, p = end_cara, moy = moy_cara) + latex += "\t &=& \\frac{ " + for (i,v) in enumerate(self.valeurs): + latex += "{p:.2f} ({x:.2f} - {moy:.2f})**2 + ".format(p = self.effectifs[i], x = v, moy = moy) + latex = latex[:-2] # on enlève le + et l'espace de fin de calcul + latex += "}}{{{eff_tot}}}\\\\ \n".format(eff_tot = self.effectif_total) + latex += "\t &=& {var:.2f}".format(var = var) + + return latex + + def ecart_type_latex(self, val_cara = "x", eff_cara = "n", end_cara = "p", moy_cara= "\\bar{x}", var_cara = "V", ecar_cara = "\\sigma"): + """ + Renvoie le code latex pour afficher le calcul de la moyenne + + :param val_cara: caractère représentant les valeurs (x par défaut) + :param eff_cara: caractère représentant les effectifs (n par défaut) + :param end_cara: caractère représentant le nombre de valeurs (p par défaut) + :param moy_cara: nom de la moyenne (\\bar{x} par défaut) + :param var_var: nom de la variance (V par défaut) + :param ecar_var: nom de la variance (V par défaut) + + :return: le code latex pour afficher le calcul de la moyenne + """ + ecart = self.ecart_type() + + # On récupère le calcul de la variance + latex = self.variance_latex(val_cara, eff_cara, end_cara, moy_cara, var_cara) + latex += "\n\n" + + # On y ajoute celui de l'écart-type (ya un soucis ici à cause du conflit entre format et { + latex += "{ecar_cara} &=& \\sqrt{{{var_cara}}} \\\\ \n".format(ecar_cara = ecar_cara, var_cara = var_cara) + latex += "\t &=& {ecart:.2f}".format(ecart = ecart) + + return latex + + + + # -------------------------- # Rendu latex @@ -210,9 +320,9 @@ On a ainsi $Q_{q} = {val_q}$ :return : le code latex pour afficher le tableau """ - d_per_line = len(self) // nbr_lines - d_last_line = len(self) % d_per_line - splited_data = [self[x:x+d_per_line] for x in range(0, len(self), d_per_line)] + d_per_line = self.effectif_total() // nbr_lines + d_last_line = self.effectif_total() % d_per_line + splited_data = [self[x:x+d_per_line] for x in range(0, self.effectif_total(), d_per_line)] # On ajoute les éléments manquant pour la dernière line if d_last_line: splited_data[-1] += [' ']*(d_per_line - d_last_line)