from ...forall import *
#######################################################################################################################
# Проверка гипотез о значении дисперсии
#######################################################################################################################
def TVH_1(text,mu0,sigma_0,sigma_1,alpha,splitter = ';',locale = 'rus') -> tuple:
    """
    Проверка гипотезы об определенном значении ГЕНЕРАЛЬНОЙ ДИСПЕРСИИ ПРИ ИЗВЕСТНОМ ГЕНЕРАЛЬНОМ СРЕДНЕМ (𝜇) на уровне значимости 𝜶
    
    Пусть X- =(x1,…,x_n) - реализация случайной выборки X =(X1,…,X_n)
    из нормального распределения N(`mu0`;σ2).
    Проверяется на уровне значимости α = `alpha`
    гипотеза H0: σ = `sigma_0` против альтернативной гипотезы
    H1: σ ≠ `sigma_0` с критическим множеством вида
    Kα = (0; A) ∪ (B; +∞). 
    - Найдите значение статистики критерия. 
    - Найдите границы А и В критического множества и проверьте гипотезу H0. 
    - Найдите P-значение критерия. 
    - Найдите вероятность ошибки второго рода β для σ1 = `sigma_1`
    
    
    Исходные данные: X- = `text`


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

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

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



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

    # Вычислить размер выборки
    n = x.size

    # Вычислить наблюдаемое значение критерия chi2
    chi2_obs = sum((x-mu0)**2)/sigma_0**2

    # Вычислить критические значения критерия chi2
    chi2_crit_1 =  chi2.ppf(alpha/2,n)
    chi2_crit_2 =  chi2.isf(alpha/2,n)

    p_value = 2 *min(chi2.cdf((chi2_obs), df=n),chi2.sf((chi2_obs), df=n) )

    # Вычислить вероятность ошибки второго рода
    lambda_ = (sigma_1 / sigma_0)**2
    beta = chi2.cdf(chi2_crit_2 / lambda_, df=n) - chi2.cdf(chi2_crit_1 / lambda_, df=n)


    # Вывод результатов
    print("Значение статистики критерия = " + (one_rrstr(chi2_obs,3)) )
    print('\nГраницы критического множества:')
    print("Граница A = "+ (one_rrstr(chi2_crit_1,3)))
    print("Граница B = "+ (one_rrstr(chi2_crit_2,3)))
    print("\nP-значение для двустороннего теста: "+ (one_rrstr(p_value,3)))
    print("\nВероятность ошибки второго рода = " + one_rrstr(beta,3))

    # Проверка гипотезы
    if alpha > p_value:
        print("\nОтвергаем нулевую гипотезу H0 в пользу альтернативной H_1.")
    else:
        print("\nНе хватает оснований отвергнуть нулевую гипотезу H_0.   ")

    return (chi2_obs, chi2_crit_1, chi2_crit_2,p_value,beta )
#######################################################################################################################
def TVH_2(text,sigma_0,sigma_1,alpha,splitter = ';',locale = 'rus') -> tuple:
    """
    Проверка гипотезы об определенном значении ГЕНЕРАЛЬНОЙ ДИСПЕРСИИ ПРИ НЕИЗВЕСТНОМ ГЕНЕРАЛЬНОМ СРЕДНЕМ (𝜇) на уровне значимости 𝜶
    
    Пусть X- =(x1,…,x_n) - реализация случайной выборки X =(X1,…,X_n)
    из нормального распределения N(μ;σ2).
    Проверяется на уровне значимости α = `alpha`
    гипотеза H0: σ = `sigma_0` против альтернативной гипотезы
    H1: σ ≠ `sigma_0` с критическим множеством вида
    Kα = (0; A) ∪ (B; +∞). 
    - Найдите значение статистики критерия. 
    - Найдите границы А и В критического множества и проверьте гипотезу H0. 
    - Найдите P-значение критерия. 
    - Найдите вероятность ошибки второго рода β для σ1 = `sigma_1`
    
    
    Исходные данные: X- = `text`


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

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

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



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

    # Вычислить размер выборки
    n = x.size

    # Вычислить наблюдаемое значение критерия chi2
    chi2_obs = sum((x-x.mean())**2)/sigma_0**2

    # Вычислить критические значения критерия chi2
    chi2_crit_1 =  chi2.ppf(alpha/2,n-1)
    chi2_crit_2 =  chi2.isf(alpha/2,n-1)

    p_value = 2 *min(chi2.cdf((chi2_obs), df=n-1),chi2.sf((chi2_obs), df=n-1) )

    # Вычислить вероятность ошибки второго рода
    lambda_ = (sigma_1 / sigma_0)**2
    beta = chi2.cdf(chi2_crit_2 / lambda_, df=n-1) - chi2.cdf(chi2_crit_1 / lambda_, df=n-1)


    # Вывод результатов
    print("Значение статистики критерия = " + (one_rrstr(chi2_obs,3)) )
    print('\nГраницы критического множества:')
    print("Граница A = "+ (one_rrstr(chi2_crit_1,3)))
    print("Граница B = "+ (one_rrstr(chi2_crit_2,3)))
    print("\nP-значение для двустороннего теста: "+ (one_rrstr(p_value,3)))
    print("\nВероятность ошибки второго рода = " + one_rrstr(beta,3))

    # Проверка гипотезы
    if alpha > p_value:
        print("\nОтвергаем нулевую гипотезу H0 в пользу альтернативной H_1.")
    else:
        print("\nНе хватает оснований отвергнуть нулевую гипотезу H_0.   ")

    return (chi2_obs, chi2_crit_1, chi2_crit_2,p_value,beta )
#######################################################################################################################
TVH = [TVH_1,TVH_2]