#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Wed Nov 24 15:59:20 2021

@author: ojacques
"""


import sys
from scipy.spatial import distance
import math
import random
import numpy as np
import statistics
######################### FUNÇÕES #########################

# Imprime informações sobre os dados de iris.data
def info_dataset(amostras, verbose=True):
	if verbose:
		print('Total de amostras: %d' % len(amostras))
	rotulo1, rotulo2, rotulo3 = 0, 0, 0
	for amostra in amostras:
		if amostra[-1] == 'Iris-setosa':
			rotulo1 += 1
		elif amostra[-1] == 'Iris-versicolor':
			rotulo2 += 1
		elif amostra[-1] == 'Iris-virginica':
			rotulo3 += 1
		else:
			print("nenhuma classificação!")
	if verbose:
		print('Total rotulo 1: %d' % rotulo1)
		print('Total rotulo 2: %d' % rotulo2)
		print('Total rotulo 3: %d' % rotulo3)
	return [len(amostras), rotulo1, rotulo2, rotulo3]


# KNN propriamente dito
# =============================================================================
# def knn(treinamento, teste, K):
# 	dists, tam_treino = {}, len(treinamento)
# 	# calcula as distâncias euclidianas da nova_amostra a todas amostras de treinamento
# 	dist=[distance.euclidean(treinamento[i][:-1], teste[:-1]) for i in range(tam_treino)]
# 	k_vizinhos=np.argsort(dist)[:K] #índice das k menores distâncias
# 	# votação majoritária
# 	lst = [treinamento[l][-1] for l in k_vizinhos]
# 
# 	return statistics.mode(lst) #retorna a moda
# =============================================================================

def EM():
    tamTreino=len(treinamento)
    #calcular a gaussiana para cada 


######################### PROGRAMA #########################

# Inicialização da lista de amostras
amostras = []

# Carregar dados de arquivo CSV com amostras
with open('iris.data', 'r') as f:
	#ler arquivo linha por linha
	for linha in f.readlines():
		# obter os atributos da amostra
		atrib = linha.replace('\n','').split(',') #separa os dados conforme a vírgula
		amostras.append([float(atrib[0]), float(atrib[1]), float(atrib[2]), float(atrib[3]), atrib[4]])
	#random.shuffle(amostras) # mistura a ordem dos dados
# Guardar totais de cada rótulo/classe
tamAmostra, rotulo1, rotulo2, rotulo3 = info_dataset(amostras, verbose=False)

acertos = 0
K = 3
matConf=np.zeros((4,4))
# =============================================================================
# Matriz de confusão:
#     | set | ver  | vir  | tot |
# set | 20  |  0   |  0   | 20  |
# ver |  0  | 19   |  1   | 20  |
# vir |  0  |  1   | 19   | 20  |
# tot | 20  | 20   | 20   | 60  |
# =============================================================================

#P(x[i]|G[j]), i=1,...,n    j=1,..,k

#calcular as covariâncias
#s[j]: desvio padrão
#u[j]: media 
#P(x[i]|G[j])=(1/(s[j]*sqrt(2*pi)))*exp(-0.5*((x[i]-u[j])/s[j])**2)


# =============================================================================
# for amostraTeste in teste:
#     	classe = knn(treinamento, amostraTeste, K)
#     	#print('%s X %s' % (amostra[-1], classe))
#     	#sys.exit("fim de teste")
#     
#         #knn acertou
#     	if amostraTeste[-1] == classe: 
#     		acertos += 1
#     		if classe == 'Iris-setosa': #0
#     			matConf[0][0]+=1        #era setosa e o resultou setosa
#     			matConf[3][0]+=1        #atualiza total de acertos para setosa
#     			matConf[0][3]+=1        #soma total de (setosa,versicolor, virginica)
#     		elif classe == 'Iris-versicolor': #1
#     			matConf[1][1]+=1
#     			matConf[3][1]+=1
#     			matConf[1][3]+=1  #total de versicolor
#     		elif classe == 'Iris-virginica': #2
#     			matConf[2][2]+=1
#     			matConf[3][2]+=1
#     			matConf[2][3]+=1  #total de virginica
#             
#         #knn errou, era setosa        
#     	elif amostraTeste[-1] == 'Iris-setosa': #0
#             matConf[0][3]+=1    #total de setosa 
#             if classe == 'Iris-versicolor': #1      
#                 matConf[0][1]+=1
#                 matConf[3][1]+=1
#     			
#             elif classe == 'Iris-virginica': #2
#                 matConf[0][2]+=1
#                 matConf[3][2]+=1
#     			
#             
#         #knn errou, era versicolor        
#     	elif amostraTeste[-1] == 'Iris-versicolor': #1
#             matConf[1][3]+=1     #total de versicolor 
#             if classe == 'Iris-setosa': #0
#                 matConf[1][0]+=1
#                 matConf[3][0]+=1
#                 
#             elif classe == 'Iris-virginica': #2
#                 matConf[1][2]+=1
#                 matConf[3][2]+=1
#                 
#             
#         #knn errou, era virginica        
#     	elif amostraTeste[-1] == 'Iris-virginica': #2
#             matConf[2][3]+=1  #total de virginica
#             if classe == 'Iris-setosa': #0
#                 matConf[2][0]+=1
#                 matConf[3][0]+=1
#                 
#             elif classe == 'Iris-versicolor': #1
#                 matConf[2][1]+=1
#                 matConf[3][1]+=1
#                
#                 
#     	matConf[3][3]=np.sum(matConf[3][:-1])   
# =============================================================================

print('Total de treinamento: %d' % len(treinamento))
print('Total de testes: %d' % len(teste))
print('Total de acertos: %d' % acertos)
print('Porcentagem de acertos: %.2f%%' % (100 * acertos / len(teste)))
print('Matriz de confusão:')

print("    | set | ver  | vir  | tot |")
print('set | %2d  | %2d   | %2d   | %2d  |' %(matConf[0][0],matConf[0][1],matConf[0][2],matConf[0][3]))
print('ver | %2d  | %2d   | %2d   | %2d  |' %(matConf[1][0],matConf[1][1],matConf[1][2],matConf[1][3]))
print('vir | %2d  | %2d   | %2d   | %2d  |' %(matConf[2][0],matConf[2][1],matConf[2][2],matConf[2][3]))
print('tot | %2d  | %2d   | %2d   | %2d  |' %(matConf[3][0],matConf[3][1],matConf[3][2],matConf[3][3]))