from sklearn.datasets import load_iris
import numpy as np
import matplotlib.pyplot as plt
import sys,random

class bin_classification:
    def __init__(self, learning_rate = 0.01, epoch = 100):
        self.lr = learning_rate
        self.ep = epoch

    def sigmoid(self,D,W):
        def sigma(D,W):
            return np.dot(D,W)
        return 1/(1+np.exp(-sigma(D,W)))
    
    def binary_predict(self,D,W):#input sample data vactor (include features)
        return self.sigmoid(D,W)

    #coss function
    def mse(self,predict,real_value):
        return abs(predict-real_value)

    def binary_train(self,D,W): #data "D" is vector , "W" is vector
        loss = 0
        for d in range(len(D)):
            pre = float(self.binary_predict(D[d],W))
            loss += self.mse(pre,float(D[d][-1]))
            #print('LOSS = ',loss)
            for i in range(len(W)): #update weight scalar
                real = float(D[d][-1])
                Xi = float(D[d][i])
                print("PRE-REAL = ",pre-real)
                W[i] -= (self.lr * ((pre-real) / abs(pre-real)) * (pre * (1-pre)) * Xi)

        return W, loss

    def data_preprocessing(self,Datasets,Dtype):

        #devide validation set, train set, target vector...
        if str(type(Datasets)) != "<class 'sklearn.utils.Bunch'>":
            print("-------ONLY USE THE DATASET FORMAT OF SKLEARN------- ")
            return 0
        Datasize = len(Datasets.data)
        ClassSize = Datasets.target[-1] + 1
        print('Dataset Size = ',Datasize,',The Number of Classes = ',ClassSize)

        trainSet = Datasets.data
        trainSet_realValue = Datasets.target

        validation_size = int(Datasize/10)
        validationSet = []
        validationSet_realValue = []
        
        if Dtype == "normal":

            for i in range(validation_size):
                domdom = random.randint(1,len(trainSet)-1)
                validationSet.append(trainSet[domdom])
                validationSet_realValue.append(trainSet_realValue[domdom])
                trainSet = np.delete(trainSet,(domdom),axis=0)
                trainSet_realValue = np.delete(trainSet_realValue,(domdom),axis=0)
            print('TrainSet Length',len(trainSet),trainSet,trainSet_realValue)        
            print('ValidationSet Length', len(validationSet),validationSet,validationSet_realValue) 
            return trainSet,trainSet_realValue, validationSet, validationSet_realValue 

        elif Dtype == "ovo":
            pass
        elif Dtype == "ovr":
            pass



def main():


    test = bin_classification(learning_rate = 0.01,epoch = 100)
    iris = load_iris()
    t,tr,v,vr = test.data_preprocessing(iris,"normal")
    weight = np.zeros(len(t[0])-1)+0.3
    

    ann = bin_classification(learning_rate = 0.01, epoch = 100)
    W, Loss = ann.binary_train(weight,t)


    print(test.binary_predict([2,3],[11,2]))
#    print(test.sigmoid([3,2],[1,2]))


if __name__ == "__main__":
    main()
