"""
This code is based on the binary classication section of this tutorial: http://karpathy.github.io/neuralnets/
"""
from svm import *


positive_label = 1
negative_label = -1

def get_pull(outputs, expected_label):
    return [get_pull_for_output(output, expected_label) for output in outputs]

def get_pull_for_output(output, expected_label):

    if (expected_label == positive_label and output < positive_label):
        return positive_label
    elif expected_label == negative_label and output > negative_label:
        return negative_label
    else:
        return 0.0

def get_binary_classification_label(outputs):
    return positive_label if outputs[0] > 0 else negative_label

def binary_clasification_with_a_svm(data_points_to_labels):
    """
    Use a SVM to classify data points into one of two labels.
    """
    svm = SupportVectorMachine([1.0, -2.0], -1.0)
    number_of_iterations = 400
    learn([[svm]], data_points_to_labels, number_of_iterations, get_pull, get_binary_classification_label)

def binary_classication_with_a_neural_network(data_points_to_labels ):
    """
    Use a small hard coded neural net to classify data points into one of two labels.
    """
    nn = [
        [ReLU([0.2, -3.0], 1.0), ReLU([-4.5, 0.9], 0.3), ReLU([-0.7, 2.3], 0)],
        [SupportVectorMachine([0.5, -0.6, 0.4], 0)]
    ]
    number_of_iterations = 400
    learn(nn, data_points_to_labels, number_of_iterations, get_pull, get_binary_classification_label)

if __name__ == "__main__":
    data_points_to_labels = [
        ([1.2, 0.7], 1),
        ([-0.3, -0.5], -1),
        ([3.0, 0.1], 1),
        ([-0.1, -1.0], -1),
        ([-1.0, 1.1], -1),
        ([2.1, -3.0], 1),
    ]
    binary_clasification_with_a_svm(data_points_to_labels )
    binary_classication_with_a_neural_network(data_points_to_labels)

