import random
from matplotlib import pyplot as plt
from scipy.stats.stats import mode
import NEW2 as _new
import math
import numpy as np


PRODUCT_LIMIT = 2
SIGMA2 = 0.238


def get_random_like_normal(mu, sigma):
    new_a = random.normalvariate(mu=mu, sigma=sigma)
    if (new_a >= (mu + sigma * PRODUCT_LIMIT))  or (new_a <= (mu - sigma * PRODUCT_LIMIT)):
        return get_random_like_normal(mu, sigma)
    else:
        return new_a

def get_list_random_like_normal(mu, sigma, _len):
    list_random = [get_random_like_normal(mu,sigma) for _ in range(_len)]
    return list_random

# x = get_list_random_like_normal(0, 1, 10000000)
# plt.hist(x, bins=100, density=True)
# plt.grid()
# plt.show()

def get_mode(x):
    data = np.histogram(x, bins=(len(x) // 8)) # <- 8 -- magic value
    _mode = data[1][np.argmax(data[0])]
    return _mode

def calc_distance_gamma(x):
    mode_x = get_mode(x)
    diff_x = np.abs(x - mode_x)
    max_diff = max(diff_x)
    relative_dist = diff_x / max_diff # distance, max = 1.0, min = 0
    proc_relative_dist = relative_dist * 100 # distance in procents
    return proc_relative_dist

def calc_distance_like_norm(x_gamma, y_like_norm):
    _diff = np.abs(x_gamma - y_like_norm)
    max_distance = max(_diff)
    relative_dist = _diff / max_distance # distance, max = 1.0, min = 0
    proc_relative_dist = relative_dist * 100 # distance in procents
    return proc_relative_dist

def classify_point(x, y, distance_gamma, distance_like_norm):
    rez_dist = distance_gamma + distance_like_norm
    sort_rez_dist = np.sort(rez_dist)
    len_sort = len(sort_rez_dist)
    index_blue = int(len_sort * 0.66)
    index_yel = int(len_sort * 0.33)
    index_red = 0
    val_blue = sort_rez_dist[index_blue]
    val_yel = sort_rez_dist[index_yel]
    x_red = x[rez_dist<val_yel]
    y_red = y[rez_dist<val_yel]
    x_yel = x[np.all([rez_dist>=val_yel , rez_dist < val_blue], axis=0)]
    y_yel = y[np.all([rez_dist>=val_yel , rez_dist < val_blue], axis=0)]
    x_blue = x[rez_dist >=val_blue]
    y_blue = y[rez_dist >=val_blue]
    return ((x_blue, y_blue),(x_yel, y_yel),(x_red, y_red))


x = _new.x1

get_random_from_u = lambda x: get_random_like_normal(x, sigma=SIGMA2/2)
y = list(map(get_random_from_u, x))
y = np.array(y)
# x = list(map(lambda x: x * math.cos(math.pi/4),x))
plt.show()

distance_gamma = calc_distance_gamma(x)
distance_like_norm = calc_distance_like_norm(x, y)

data_blue, data_yel, data_red = classify_point(x, y, distance_gamma, distance_like_norm)

x_blue, y_blue = data_blue
x_yel, y_yel = data_yel
x_red, y_red = data_red

plt.plot(x_blue, y_blue, '.b')
plt.plot(x_yel, y_yel, '.y')
plt.plot(x_red, y_red, '.r')
plt.xlim([5, 6.3])
plt.ylim([5, 6.3])
plt.plot([5, 6.3],[5, 6.3], 'g')
# plt.plot(y,x, '.b')
plt.grid()
plt.show()