#/usr/bin/env python # -*- coding:Utf-8 -*- # # # Ensemble de fonction rendant beaucoup plus pratique la résolution et l'élaboration des exercices de stat au lycée # # from math import sqrt, ceil class Dataset(list): """ 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"): """ Create a numeric data set :param data: values of the data set :param data_name: name of the data set """ list.__init__(self, data) self_name = data_name def add_data(self, data): """Add datas to the data set :param data: datas """ try: self += data except TypeError: self += [data] def effectif_total(self): return len(self) def sum(self): return sum(self) def mean(self): return self.sum()/self.effectif_total() def deviation(self): """ Compute the deviation (not normalized) """ mean = self.mean() return sum([(x - mean)**2 for x in self]) def variance(self): return self.deviation()/self.effectif_total() def sd(self): """ Compute the standard deviation """ return sqrt(self.variance()) def quartiles(self): """ Calcul les quartiles de la série. :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)) def quartile(self, quartile = 1): """ Calcul un quartile de la série. :param quartile: quartile à calculer (par defaut 1 -> Q1) :return: le quartile demandé : Example: >>> 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 """ # -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): """ Calcul la position du quartile :param quartile: le quartile concerné :return : la position du quartile (arondis à l'entier suppérieur, non arrondis) """ 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 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 def quartiles_latex(self): """ Renvoie le code latex pour afficher le calcul des quartiles :return : le code latex pour afficher le calcul des quartiles """ latex = self.quartile_latex() latex += self.quartile_latex(1) latex += self.quartile_latex(3) return latex def quartile_latex(self, quartile = 2): """ Renvoie le code latex pour afficher le calcul du quartile :param quartile: numéro du quartile :return : le code latex pour afficher le calcul du quartile """ if quartile == 2 : # médiane quartile_tpl = """ Position de la médiane: $\\dfrac{{\\mbox{{effectif total}}}}{{2}} = \\dfrac{{{eff_tot}}}{{2}} = {posi_q}$. Donc la médiane se trouve à la position: {posi_q_ceil}. On a ainsi $Me = {val_q}$ """ else: quartile_tpl = """ Position de $Q_{q}$: $\\dfrac{{{q} \\times \\mbox{{effectif total}}}}{{4}} = \\dfrac{{{q} \\times {eff_tot}}}{{4}} = {posi_q}$. Donc $Q_{q}$ se trouve à la position: {posi_q_ceil}. On a ainsi $Q_{q} = {val_q}$ """ posi_q_ceil , posi_q = self.posi_quartile(quartile) val_q = self.quartile(quartile) latex = quartile_tpl.format(eff_tot = self.effectif_total, q = quartile, posi_q = posi_q, posi_q_ceil = posi_q_ceil, val_q = val_q) return latex def tabular_latex(self, nbr_lines = 1): """ Renvoie le code latex pour afficher le tableau :return : le code latex pour afficher le tableau """ 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) # Construction du tableau latex = "\\begin{{center}} \n \t \\begin{{tabular}}{{|c|*{{{nbr_col}}}{{c|}}}} \n".format(nbr_col = d_per_line) latex += "\t\t \hline \n" d_lines = [' & '.join(map(str,l)) for l in splited_data] latex += " \\\\ \n \\hline \n".join(d_lines) latex += " \\\\ \n \\hline \n" latex += "\t \\end{tabular} \n \\end{center}" return latex if __name__ == '__main__': valeurs = [65, 75, 85, 95, 105, 115, 125, 135] valeurs.sort() print(valeurs) effectifs = [ 15, 2, 21, 24, 12, 9, 5, 2] s = Dataset() s.set_values(valeurs, effectifs) print(s.effectif_total) print(s.valeurs) print(s.effectifs) print(s.data) # print(s.tabular_latex()) # print("Moyenne ", s.moyenne()) # print(s.variance()) # print(s.ecart_type()) print("\n-----------------------\n") print(s.moyenne_latex()) print("\n-----------------------\n") print(s.variance_latex()) print("\n-----------------------\n") print(s.ecart_type_latex()) # print(s.quartiles()) print("\n-----------------------\n") print(s.quartile_latex()) print(s.quartile_latex(1)) print(s.quartile_latex(3)) # ----------------------------- # Reglages pour 'vim' # vim:set autoindent expandtab tabstop=4 shiftwidth=4: # cursor: 16 del