import numpy as np
import random as rd
from matplotlib import pyplot as plt


#--- III.1 : UNE SIMULATION
# variables à utiliser
hauteurs = ["7","8","9","10","V","D","R","A"]
couleurs = ["T","K","C","P"]
#--- III.1.1.a produit
def produit(ha,co) :
    tmp = []
    for h in ha :
        for c in co :
            tmp.append((h,c))
    return tmp
print("-"*40+"test III.1.1.a")
print(produit(hauteurs,couleurs))
#END
#--- III.1.1.b complexité
# la réponse est O(l_hxl_c) car l'opération tmp.append((h,c)) est faite en temps constant
# elle est exécutée co l_c fois, mais cette même boucle est effectuée l_h fois ce qui fait 
# l_h x l_c opérations en temps constant. 
#END
#--- III.1.1.c création du jeu
cartes = produit(hauteurs,couleurs) 
print("-"*40, "III.1.1.c")
print("jeu de cartes :", cartes)
#END
#--- III.1.1.d vérification de longueur
print("-"*40+"test III.1.1.d")
print("test longueur : ", len(cartes) == 32)
#END 
#--- III.1.2.a lCartes
def lCartes() :
    '''
    tirages de 5 cartes dans le jeu avec répétition possible
    '''
    tmp = []
    for _ in range(5) : 
       ca = cartes[np.random.randint(31)]
       tmp.append(ca)
    return tmp
print("-"*40 + "test III.1.2.a")
print("test lCartes :", lCartes())
#END
#--- III.1.2.b tirerMain
def tirerMain() :
    return rd.sample(cartes,5)
print("-"*40 + "test III.1.2.b")
print("test tirerMain:", tirerMain())
#END
#--- III.1.3.a estCouleur
def estCouleur(main) :
    a = main[0][1] # couleur de la première carte
    for k in range(1,5) :
        if main[k][1] != a :
            return False
    return True

mainTestCouleur = [('R', 'T'), ('V', 'T'), ('D', 'T'), ('8', 'T'), ('V', 'T')]
print("-"*40 + "test III.1.3.a")
print("test estCouleur :", estCouleur(mainTestCouleur))
#END
#--- III.1.3.b freq
def freq(n) :
    total = 0
    for k in range(n) :
        if estCouleur(tirerMain()) :
            total += 1
    return total/n

print("-"*40 + "test III.1.3.b")
print("test freq :", freq(10000))
#abs = [k for k in range(100,2100,100)]
#END
#--- III.1.3.c approximation
print("-"*40 + "test III.1.3.c")
print("approxmation :", freq(100000))
#END
#--- III.1.3.d. graphique
X = [k for k in range(10000,110000,10000)]
Y = [freq(e) for e in X] 
plt.plot(X,Y)
plt.show()
#END
#END

print()
print("*"*80)
print("*"*80)
print()

#--- III.2 : CODAGE MINIMAL D'UNE CHAINE
#--- III.2.1. coupures
def coupures(S) :
    tmp = []
    l = len(S)
    for i in range(1,l) :
        if S[i-1] != S[i] :
            tmp.append(i)
    tmp.append(l)
    return tmp

L = [1,1,0,0,1,1,1,0,1,1,1]

print("-"*40, "III.2.1")
print(L)
print(coupures(L))
#END
#--- III.2.2 CP
def CP(S)  :
    tmp = []    # liste a renvoyer 
    a = 0       # indice de départ
    cpr = coupures(S)
    for k in range(len(cpr)) : 
        # on ajoute la longueur de séquence
        # et la valeur répétée dans la séquence
        tmp.append([cpr[k]-a,S[a]])
        # on repart du nouvel indice de coupure
        a = cpr[k]
    return tmp 

L = [1,1,0,0,1,1,1,0,1,1,1]
A = 'aaaaggaadaaa'
print("-"*40, "III.2.2")
print(L)
print("tests fonction CP : ", CP(A))
#END
#--- III.2.3 : nbits
def nbits(n) :
    cpt = 0 
    a = 1 # contiendra les puissances de 2
    while a< n :
        cpt += 1 
        a *= 2
    return cpt
print("-"*40, "III.2.3")
print("test fonction nbit : ", nbits(25))
#END
#--- III.2.4 : nbelem
def nbelem(L) :
    # dictionnaire car on va utiliser un test en "in"
    dico = {}
    for e in L :
        if not e in dico :
            dico[e] = True
    return len(dico)
# chaine pour tester :
chaine = 'aaaaggaadaaa'
print("-"*40, "III.2.4")
print("test fonction nbelem : ", nbelem(chaine) )
#END
#--- III.2.5 ntotalbits
def ntotalbits(S) :
    # combien d'éléments  différents
    nbe = nbelem(S)
    # on en déduit le nombre de bits pour les coder :
    N1 = nbits(nbe)
    # on trouve l'écriture sous la forme [[element, nbr de fois]]
    comp = CP(S)
    # on veut coder les nombres de répétitions, il nous faut 
    # le nombre max de ces répétitions
    N2 = nbits(max([ e[0] for e in comp]))
    return (N1+N2)*len(comp)
#chaine pour tester
chaine = 'aaaaggaadaaa'
print("-"*40, "III.2.5")
print("test fonction ntotalbits : ", ntotalbits(chaine))
#END
#END
