def perceptron(X, Y):
    """
    Function to 
 a perceptron to the kernelized input data.

    Parameters
    ----------
    X: Numpy array with the input 2D data points [n_samples, 2]
    Y: Numpy array with the binary classes (either 0 or 1) [n_samples,]

    Returns
    -------
    is_linearly_separable: Boolean value indicating whether the data is
                           linearly separable or not

    """

    is_linearly_separable = False
    kernelX = kernelize(
        X, Y)  # Y is passed to plot the kernelized data with labels
    """
    Create a Perceptron instance and fit it to the kernelized data.
    For details on how to do this in scikit-learn, refer:
        http://scikit-learn.org/stable/modules/generated/sklearn.linear_model.Perceptron.html
    ==========================================================================
    """

    # YOUR CODE GOES HERE
    m = Perceptron()
    m.fit(kernelX, Y)
    train_predictions = m.predict(kernelX)
    train_labels = Y
    clf = m.densify()
    """
    ==========================================================================
    """
    """
    Calculates training accuracy. Replace predictions and labels with your
    respective variable names.
    """
    train_accuracy = calculate_accuracy(train_predictions, train_labels)
    print "Training Accuracy: %.4f" % (train_accuracy)

    if train_accuracy == 1:
        is_linearly_separable = True
    """
    Code to plot the 3D decision surface that separates the points. Visualization
    will help in understanding how the kernel has performed.
    """
    fig = plt.figure()
    ax = fig.add_subplot(111, projection='3d')
    color = lambda x: 'r' if x else 'b'
    mark = lambda x: 'o' if x else '^'
    for i in range(kernelX.shape[0]):
        x, y, z = kernelX[i]
        ax.scatter(x, y, z, c=color(Y[i]), marker=mark(Y[i]))

    W = clf.coef_[0]  # 3D normal
    intercept = clf.intercept_[0]  # Distance from origin

    xx, yy = np.meshgrid(kernelX[:, 0], kernelX[:, 1])
    """
    Derived from a*x + b*y + c*z + d = 0. (a, b, c) is the normal and we know
    x and y values. d is the distance from origin, or the intercept. Hence, value
    of z => (-a*x - b*y - d) / c.
    Source: https://stackoverflow.com/questions/3461869/plot-a-plane-based-on-a-normal-vector-and-a-point-in-matlab-or-matplotlib
    """
    zz = ((-W[0] * xx) + (-W[1] * yy) + (-intercept)) * 1. / W[2]

    ax.plot_surface(xx,
                    yy,
                    zz,
                    rstride=10,
                    cstride=10,
                    color='g',
                    antialiased=False,
                    linewidth=0,
                    shade=False)
    plt.show()

    return is_linearly_separable