import numpy as np
from math import sqrt



######################

## script 1
def dist(x1,x2):
    S=0
    for i in range(len(x1)):
        S=S+(x1[i]-x2[i])**2
    return sqrt(S)

#test
print(dist([1,2,3],[0,0,0]))  #racine de 14 ok


## on execute le fichier donnees.py

print(joueuses)

print(performances)


########################
#### Note de performance

## script 2

def distances_au_point(joueuses,x):
    result=[]
    for i in range(len(joueuses)):
        result.append(dist(joueuses[i],x))

    return result



#test
nouvelle=[25,39,70] #;-)
print(distances_au_point(joueuses,nouvelle))



## question 3

def trier(distances):
    n=len(distances)
    def f(i):
        return distances[i]
    return sorted(range(n),key=f)


print(trier([1,50,60,43,22]))#rep :[0, 4, 3, 1, 2]


## script 4 (facultatif)

def mini(L,liste_indices):
    '''renvoie l indice du minimum de L , minimum pris sur les indices listés dans liste_indices'''
    k=liste_indices[0]
    min=L[k]

    for i in liste_indices:
        if L[i]<min:
            k=i
            min=L[i]

    return k


print(mini([1,2,3,4,5,7,-1,0],[2,3,4,6,7]))#rep : 6 ok



def trier2(distances):
    N=len(distances)
    listes_indices=[i for i in range(N)]

    result=[]

    while listes_indices!=[]:
        k=mini(distances,listes_indices)
        listes_indices.remove(k)
        result.append(k)

    return result

print(trier2([1,20,30,2,5]))
print(trier([1,20,30,2,5]))  #ok


## script 5

def moyenne_des_k_voisins(indices_tries,performances,k):
    S=0
    for i in range(k):
        S=S+performances[indices_tries[i]]
        print(performances[indices_tries[i]])
    return S/k





## script 6

def k_plus_proches_voisins(joueuses,performances,x,k):
    L=distances_au_point(joueuses,x)
    # print(L)
    indices=trier(L)
    # print(indices)
    return moyenne_des_k_voisins(indices,performances,k)


nouvelle=[50,60,65]
print(k_plus_proches_voisins(joueuses,performances,nouvelle,3))#rep:5.933



#############################
### Groupes de performances


## script 7

import random as rd


def initialisation(saison2, k):
    q=saison2.shape[1]
    poles=np.zeros((k,q))
    for j in range(q):
        m=np.min(saison2[:,j])
        M=np.max(saison2[:,j])
        for i in range(k):
            poles[i,j] = rd.uniform(m,M)
    return poles



#test
poles=initialisation(saison2,3)
print(poles)




## script 8

def pole_le_plus_proche(poles,x):
    result=0
    temp=dist(poles[0],x)
    for i in range(1,len(poles)):
        if dist(poles[i],x)<temp:
            temp=dist(poles[i],x)
            result=i
    return result



#test
print(pole_le_plus_proche(poles,[30,61,75]))


## script 9

def poles_les_plus_proches(poles,saison2):
    return [pole_le_plus_proche(poles,saison2[i]) for i in range(len(saison2))]




#test
repartition=poles_les_plus_proches(poles,saison2)
print(repartition)


## script 10

def nouveaux_poles(saison2,repartition,k):
    q=saison2.shape[1]
    poles=np.zeros((k,q))
    for i in range(k):
        result=np.zeros((1,q))
        nombre=0
        for k in range(len(repartition)):
            if repartition[k]==i:
                nombre=nombre+1
                result=result+saison2[k]

        if nombre!=0:
            poles[i]=result/nombre


    return poles






#test
newpoles=nouveaux_poles(saison2,repartition,3)
print(newpoles)

## script 11

def k_moyennes(saison2,k):
    poles=initialisation(saison2,k)

    test=False

    while not test:
        repartition=poles_les_plus_proches(poles,saison2)
        newpoles=nouveaux_poles(saison2,repartition,k)
        test= (poles==newpoles).all() #les elts de poles sont ils tous egaux à ceux de des nouv poles
        poles=newpoles

    return poles




#test
k=3
polesdefinitifs=k_moyennes(joueuses,k)
print(polesdefinitifs)

## question 12
# illustration avec la fct affiche présnte dans le fichier donnees.py

'''la nouvelle categorie de chaque joueuse  X est donnée par pole_le_plus_proche(polesdefinitifs,X)
essayons de représenter les nouvelles catégories'''

affiche(saison2,polesdefinitifs,3)


'''c es t normal de ne pas avoir un résultat différent, puisque le point de départ de l'algorithme est aléatoire.
De plus on sait d'après le cours que l'algorithme s'arrête lorsqu'on a trouvé un minimum local pour une certaine fonction (liée à un calcul de distance catégorisées.
Le caoch est-il content?
Sur les illustrations, on voit bien le cloissonnement des joueuses , c'est  ce qu'il demandait. Cependant, une demande implicite du coach pourrait être de créer des catégories homogènes en nombre de joueuses et dans ce cas notre résulta est critiquable'''


## bonus

'''en moyenne, l'algo des k moyennes se termine en 3 étapes (rapide!)
On s'en aperçoit en plaçant un compteur au sein de la fct k_moyennes'''


















