# -*- coding: utf-8 -*-
"""
Partie statistiques et probobilité du module lycee.
"""
"""
Créé à partir d' Edupython: http://edupython.tuxfamily.org/
Licence CECILL http://www.cecill.info/
"""
# Loi Binomial
import math
import builtins
import random
from .arithmetique import quotient
from .listes import transposer
[docs]def binomial(n, p):
"""
Renvoie un entier (int) représentant le coefficient binomial ``p`` parmi ``n``.
C'est à dire le nombre de chemins de l’arbre réalisant ``p`` succès pour ``n`` répétitions.
Arguments:
n (int): Un nombre entier
p (int): Un nombre entier
"""
if p <= n:
return quotient(
math.factorial(n),
math.factorial(n - p) * math.factorial(p)
)
else:
return 0
[docs]def tirage_binomial(n, p):
"""
Renvoie un nombre entier (int) choisi de manière aléatoire selon une loi binomiale B(n,p) : ``p`` parmi ``ǹ``.
Arguments:
n (int): Premier paramètre de la loi binomiale à simuler.
p (int): Second paramètre de la loi binomiale à simuler.
"""
s = 0
for i in range(n):
if alea() < p:
s = s + 1
return s
# Loi uniforme
[docs]def alea_entier(min, max):
"""
Renvoie un entier (int) choisi de manière (pseudo)aléatoire et équiprobable
dans l'intervalle [``min`` ; ``max``].
Arguments:
min (int): Un nombre entier
max (int): Un nombre entier
"""
return random.randint(min, max)
[docs]def choix(liste):
"""
Renvoie un élément de la liste ``liste`` choisi (pseudo)aléatoirement et de manière équipropable
Arguments:
liste (int): La liste dans laquelle on choisit un élément.
"""
return random.choice(liste)
[docs]def alea():
"""
Renvoie au hasard un décimal de l'intervalle [0 ; 1[
"""
return random.random()
# Loi exponentielle
[docs]def tirage_expo(x):
"""
Renvoie un nombre décimal (float) choisi de manière aléatoire selon
une loi exponentielle de paramètre ``x``.
Arguments:
x (float) : est un réel strictement positif.
"""
return random.expovariate(x)
# Loi normale
[docs]def repartition_normale(x, mu=0, sigma=1):
"""
Renvoie la probabilité P(y < x) pour P loi normale de moyenne mu et
d'écart type sigma.
Arguments:
x (float)
mu (float): Un nombre décimal. L'éspérance de la loi normale
sigma (float): Un nombre décimal. L'écart type de la loi normale
"""
if sigma <= 0:
raise ValueError("Veuillez entrer un écart type strictement positif")
ferx = math.erf((x - mu)/(sigma * 2 ** 0.5))
return (1 + ferx) / 2
[docs]def tirage_normale(mu, sigma, precision=15):
"""
Renvoie un nombre décimal (float) choisi de manière aléatoire
selon une loi nomale d'espérance ``mu`` et d'écart type ``sigma``.
Arguments:
mu (float): Un nombre décimal. L'éspérance de la loi normale
sigma (float): Un nombre décimal. L'écart type de la loi normale
"""
cible = random.random()
a = mu
#On symétrise le problème de recherche d'inverse, car si on procède par
#dichotomie, les valeurs très inférieures à la moyenne s'envoient sur des
#point très proches et on a un souci de précision.
sym = False
if cible < 0.5:
cible = 1 - cible
sym = True
#On commence par chercher un intervalle qui contient l'inverse de 'cible'
#pour la fonction de répartition. On prends des intervalles de longueur
# l'écart-type pour être sûr de trouver en très peu d'itérations
b = sigma
while repartition_normale(b, mu, sigma) < cible:
a, b = b, b + sigma
#On calcule la précision ici
epsilon = 1/2**precision
#On applique l'algorithme de dichotomie
while repartition_normale(b,mu,sigma) - cible > epsilon:
milieu = (a+b)/2
if repartition_normale(milieu, mu, sigma) > cible:
b = milieu
else:
a = milieu
#Au besoin, on symétrise autour de la moyenne
if sym:
return - b + 2 * mu
else:
return b
[docs]def tirage_gauss(mu, sigma):
"""
Renvoie un nombre décimal (float) choisi de manière aléatoire
selon une loi nomale d'espérance ``mu`` et d'écart type ``sigma``.
Arguments:
mu (float): Un nombre décimal. L'éspérance de la loi normale
sigma (float): Un nombre décimal. L'écart type de la loi normale
"""
return random.gauss(mu, sigma)
[docs]def compte(liste_critere, liste_effectif=[]):
"""
Retourne la liste non triée, sans les doublons, les effectifs, les fréquences correspondantes et l'effectifs totales.
La fonctionne NE TRIE PAS par ordre des critères : les critères n'ont pas nécessairement un ordre.
Pour trier le résultat, utililser la fonctions trier()
Arguments:
liste_critere (list): une liste de critère d'une population
liste_effectif (list, optionnel) : liste des frequences ou des effectifs des critères
"""
n = len(liste_critere)
eff_tot = 0
leff = []
if liste_effectif == []: # On crée la liste des effectifs si elle n'existe pas, 1 par critère
leff = [1] * n
elif liste_effectif != [] and len(liste_effectif) != n:
print("Erreur : les 2 listes n'ont pas le même nombre déléments !")
else:
leff = liste_effectif
critere_groupe = []
eff_groupe = []
for i in range(n): # où l'on compte
if liste_critere[i] not in critere_groupe:
# Si le critere n'est pas dans la liste on le rajoute
critere_groupe.append(liste_critere[i])
# Et on ajoute l'effectif/frequence correspondante
eff_groupe.append(leff[i])
eff_tot += leff[i]
else:
# Si le critere est déjà présent on ajoute l'effectif/frequence à
# celle déjà existante
eff_groupe[critere_groupe.index(liste_critere[i])] += leff[i]
eff_tot += leff[i]
return [critere_groupe, eff_groupe, [
float(i) / eff_tot for i in eff_groupe], eff_tot]
# Les classes
[docs]def centres(L): # Pourquoi?
"""
Renvoie une liste de longueur n-1 contenant les valeurs (L[i]+L[i+1])/2.
Arguments:
L (list): Une liste de taille n
"""
R = []
for i in range(len(L) - 1):
R.append((L[i] + L[i + 1]) / 2)
return R
[docs]def moyenne(xi, ni=[]):
"""
Renvoie la moyenne de la liste ``xi``.
Arguments:
xi (list): liste de valeurs
ni (liste, optionnel): série des effectifs ou des fréquences associés
"""
L = compte(xi, ni)
# Manipulation technique pour ne prendre que critere et freq de la serie
# statistiques
L1 = transposer(L[::2])
# Et prendre la transposee
m = 0
for i, j in L1:
m += i * j
return m
[docs]def variance(xi, ni=[]):
"""
Retourne la variance de la liste.
Arguments:
xi (list): Liste de valeurs
ni (list, optionnel): Liste des effectifs associés
"""
L = compte(xi, ni)
m = moyenne(xi, ni)
# Manipulation technique pour ne prendre que critere et freq de la serie
# statistiques
L1 = transposer(L[::2])
# Et prendre la transposee
v = 0
for i, j in L1:
v += (i - m)**2 * j
return v
[docs]def ecartype(xi, ni=[]):
"""
Retourne l'écart-type de la liste.
Arguments:
xi (list): Liste de valeurs
ni (list, optionnel): Liste des effectifs associés
"""
return math.sqrt(variance(xi, ni))