from ...forall import *
#######################################################################################################################
# Проверка гипотезы о состоянии двух средних
#######################################################################################################################
def TSTwoM_1(text_x,text_y,sigma_x,sigma_y,alpha,delta,splitter = ';',locale = 'rus'):
    """Сравнение ДВУХ ГЕНЕРАЛЬНЫХ СРЕДНИХ при ИЗВЕСТНОЙ ДИСПЕРСИИ
    Пусть X- =(x1,…,x_m) - реализация случайной выборки X =(X1,…,X_m) из нормального распределения N(μ_x; `sigma_x`),
    а Y- =(y1,…,y_n) - реализация случайной выборки Y =(Y1,…,Y_n) из нормального распределения N(μ_y; `sigma_y`).
    Известно, что X и Y независимы. Проверяется гипотеза H0: μ_x = μ_y против альтернативной гипотезы H1: μ_x > μ_y.
    При уровне значимости α применяется критерий с критической областью {Z>A}, где статистика критерия
    Z = Z(X, Y) - это нормированная разность X- - Y-,
    A = A_α -  зависящее от α критическое значение. Соответствующее критическое множество имеет вид K_α =(A_α; ∞).
    
    - Найдите значение статистики критерия Z_набл.= Z(X-, Y-).
    - Найдите P-значение критерия.
    - Найдите критическое значение A, критическое множество K_α и проверьте гипотезу H0 при α = `alpha`.
    - Найдите мощность критерия W в случае μx - μy = `delta` и α = `alpha`.
    
    Исходные данные:
    
    X- = `text_x`
    Y- = `text_y`

    Args:
        text_x (str): Строка перечисления всех чисел, данных как X-
        text_y (str): Строка перечисления всех чисел, данных как Y-
        sigma_x (numerical): Значение стандартного отклонения X
        sigma_y (numerical): Значение стандартного отклонения Y
        alpha (numerical): Уровень значимости
        delta (numerical): Разность между математическими ожиданиями для подсчета W
        splitter (str, optional): Разделитель между каждым значением в `text_x` и `text_y`. Стандартно равно =  ';'.
        locale (str, optional): Локализция данных - если целая и дробная часть каждого числа из `text разделена не запятой, то нужно изменить значение этого параметра на любое другое. Стандартно равно =  'rus'.

    ## Prints
        `answer` каждое значение последовательно.<br>C запятой вместо точки и сокращенное до соответствующего количества десятичных знаков.

    ## Returns:
        `answer` (tuple): Соответствующие значения
    """
    from scipy.stats import norm

    # Взять данные из строки
    if locale== 'rus':
        x = np.array(text_x.replace(',','.').split(splitter)).astype(float)
        y = np.array(text_y.replace(',','.').split(splitter)).astype(float)
    else:
        x = np.array(text_x.split(splitter)).astype(float)
        y = np.array(text_y.split(splitter)).astype(float)


    x_sr = x.mean()
    y_sr = y.mean()
    m = x.size
    n = y.size

    # Значение статистики Z
    z_obs = (x_sr - y_sr)/(sigma_x**2/m + sigma_y**2/n)**0.5

    # P-значение
    p_value = 1 - norm.cdf(z_obs)

    # Критическое значение A
    z_crit = norm.ppf(1 - alpha)

    # Мощность критерия W
    z_alt = (delta) / np.sqrt((sigma_x**2 / m) + (sigma_y**2 / n))
    w = 1 - norm.cdf(z_crit - z_alt)



    print('Значение статистики критерия = ' + one_rrstr(z_obs,3))
    print('P-значение критерия = ' + one_rrstr(p_value,3))
    print('Критическое значение А = ' + one_rrstr(z_crit,3))
    print('Мощность критерия = ' + one_rrstr(w,3))

    # Проверка гипотезы
    if z_obs > z_crit:
        print("Гипотеза H0 отвергается в пользу H1.")
    else:
        print("Нет оснований отвергнуть гипотезу H0.")
        
    return (z_obs, p_value, z_crit, w)
#######################################################################################################################
def TSThreeM_1(A,B,C,alpha,splitter = ';',locale = 'rus'):
    """Проверка гипотезы о совпадении нескольких генеральных средних методом дисперсионного анализа
    Для трех групп финансовых показателей 
    - A = (X1;...;X_a), 
    - B = (Y1;...;Y_b), 
    - C = (Z1;...;Z_c),
    которые по предположению независимы и распределены, соответственно, по трем нормальным законам
    N(μ_x,σ2), N(μ_y,σ2), N(μ_z,σ2) (с одинаковой неизвестной дисперсией σ2)
    на уровне значимости α = `alpha` с помощью F-критерия (Фишера) проверяется гипотеза H0: μ_x = μ_y = μ_z
    о совпадении ожидаемых значений показателей.
    
    Конкретные значения всех показателей указаны ниже.
    - По данным значениям показателей найдите межгрупповую дисперсию. 
    - По этим же данным найдите среднюю групповую дисперсию. 
    - Найдите значение статистики F-критерия, критическое множество K_α и проверьте гипотезу H0. 
    - Найдите P-значение критерия и сделайте выводы.
    
    
    Значения показателей группы A = `A`.
    Значения показателей группы B = `B`.
    Значения показателей группы C = `C`.

    ## Args:
        A (str): Строка перечисления всех чисел, данных как `A`
        B (str): Строка перечисления всех чисел, данных как `B`
        C (str): Строка перечисления всех чисел, данных как `C`
        alpha (numerical): Уровень значимости
        splitter (str, optional): Разделитель между каждым значением в `text_x` и `text_y`. Стандартно равно =  ';'.
        locale (str, optional): Локализция данных - если целая и дробная часть каждого числа из `text разделена не запятой, то нужно изменить значение этого параметра на любое другое. Стандартно равно =  'rus'.

    ## Prints
        `answer` каждое значение последовательно.<br>C запятой вместо точки и сокращенное до соответствующего количества десятичных знаков.

    ## Returns:
        `answer` (tuple): Соответствующие значения
    """
    from scipy.stats import f

    # Взять данные из строки
    if locale== 'rus':
        A = np.array(A.replace(',','.').split(splitter)).astype(float)
        B = np.array(B.replace(',','.').split(splitter)).astype(float)
        C = np.array(C.replace(',','.').split(splitter)).astype(float)
    else:
        A = np.array(A.split(splitter)).astype(float)
        B = np.array(B.split(splitter)).astype(float)
        C = np.array(C.split(splitter)).astype(float)


    n1,n2,n3 = A.size,B.size,C.size

    ni = np.array((n1,n2,n3))
    n = ni.sum()
    k = 3

    Gr_sr = np.array((A.mean(),B.mean(),C.mean()))
    Gr_var = np.array((A.var(),B.var(),C.var()))
    all_sr = np.dot(Gr_sr,ni)/n


    delta2 = np.dot((Gr_sr - all_sr)**2,ni)/n #SSA / n
    print('Межгрупповая дисперсия = ' + one_rrstr(delta2,3)  )

    sigma2_sr = np.dot(Gr_var,ni)/n #SSW/n
    print('Средняя групповая дисперсия = ' + one_rrstr(sigma2_sr,3)  )

    sigma2 =sigma2_sr + delta2
    
    MSA = n * delta2 /(k-1)
    MSW = n *sigma2_sr/(n - k)
    MST = n * sigma2 / (n-1)

    F_obs =  MSA/MSW
    print('Значение статистики критерия = ' + one_rrstr(F_obs,3)  )

    F_cr = f.ppf(1 - alpha, k-1, n-k)
    p_val = f.sf(F_obs,k-1,n-k)
    print('P-значение критерия = ' + one_rrstr(p_val,3))

    return (delta2,sigma2_sr,F_obs,p_val)
#######################################################################################################################
TSM = [TSTwoM_1, TSThreeM_1]