from scipy import stats
import matplotlib.pyplot as mpl


def vb_mean(vb):
    return sum(vb) / len(vb)


def vb_median(vb):
    n = len(vb)
    sorted_vb = sorted(vb)
    if n % 2:
        return sorted_vb[n // 2]
    else:
        return (sorted_vb[n // 2 - 1] + sorted_vb[n // 2]) / 2


def vb_dispersion(vb):
    n = len(vb)
    mu = vb_mean(vb)
    s = 0
    for x in vb:
        s += (x - mu) ** 2
    return s / (n - 1)


def vb_sigma(vb):
    return vb_dispersion(vb) ** 0.5


def stat_criterion(vb1, vb2):

    n1 = len(vb1)
    mean1 = vb_mean(vb1)
    dispersion1 = vb_dispersion(vb1)

    n2 = len(vb2)
    mean2 = vb_mean(vb2)
    dispersion2 = vb_dispersion(vb2)

    return (mean1 - mean2) / (dispersion1 / n1 + dispersion2 / n2) ** 0.5


def is_mean_equal(vb1, vb2, a):
    z = stat_criterion(vb1, vb2)
    p = 2 * (1 - stats.norm.cdf(abs(z)))
    return p > a, p


def vb_histogram(vb, title):
    mpl.hist(vb)
    mpl.title(title)
    mpl.show()


def main():
    # Вхіднні данні
    n1 = 110
    n2 = 148
    mu = 22
    sg = 1.8
    a = 0.05
    # Перша вибірка
    vb1 = [22.6, 20.73, 22.14, 21.84, 23.73, 24.81, 21.95, 22.42, 21.37, 22.04, 22.89, 20.22, 22.62, 20.78, 25.57, 20.21, 21.77, 21.17, 25.71, 23.43, 21.61,
           20.4, 22.89, 22.52, 22.56, 18.72, 23.38, 21.39, 20.79, 23, 22.51, 23.27, 23.26, 21.02, 20.65, 23.34, 21.48, 21, 17.49, 22.18, 21.13, 18.77, 21.16,
           21.08, 24.91, 21.72, 23.47, 22.66, 21.85, 24.85, 22.3, 24.52, 22.08, 18.97, 21.45, 21.45, 20.18, 18.63, 24.37, 20.38, 22.22, 21.9, 23.19, 21.8,
           19.5, 21.42, 23.13, 19.43, 21.04, 19.09, 21.88, 21.43, 24.39, 20.9, 20.24, 21.47, 22.99, 24.78, 19.24, 21.86, 21.87, 25.93, 21.18, 21.06, 21.51,
           21.96, 21.41, 21.7, 22.93, 21.69, 25.63, 22.94, 22.63, 22.85, 21.85, 20.31, 22.41, 21.48, 23.17, 21.8, 20.66, 21.87, 26.22, 18.75, 23.6, 21.44,
           23.45, 24.76, 18.54, 21.68]
    # Друга вибірка
    vb2 = [24.67, 21.64, 21.15, 21.71, 20.41, 23.86, 22.61, 22.14, 21.7, 22.75, 21.5, 23.9, 21.29, 22.38, 21.53, 23.45, 25.89, 19.39, 22.47, 20.74, 24.08,
           24.8, 21.11, 20.75, 20.69, 26.74, 19.37, 24, 19.85, 19.91, 21.62, 23.36, 21.18, 22.13, 20.76, 20.95, 20.9, 21.28, 18.8, 21.87, 23.64, 21.59,
           21.23, 23.99, 24.1, 20.87, 23.08, 22.86, 21.69, 18.43, 21.87, 20.71, 22.82, 20.49, 22.91, 21.44, 25.65, 22.42, 23.01, 21.61, 25.34, 20.57, 23.36,
           22.67, 21.92, 21.02, 21.85, 18.45, 21.96, 25.26, 21.57, 23.21, 24.6, 20.98, 19.64, 20.84, 25.06, 21.96, 23.44, 22.95, 19.2, 22.63, 20.69, 20,
           19.56, 22.97, 24.23, 23.8, 20.04, 22.01, 23.43, 19.96, 20.1, 19.75, 21.03, 24.19, 23.52, 22.17, 22.12, 23.21, 22.25, 23.17, 22.3, 20.47, 21.56,
           20.3, 20.58, 19.18, 25.25, 21.28, 21.16, 21.71, 20.21, 21.27, 22.97, 21.92, 20.8, 18.16, 22.93, 19.31, 19.9, 21.91, 20.19, 18.68, 22.78, 22.98,
           20.82, 20.36, 21.27, 22.95, 22.64, 22.46, 20.68, 21.88, 20.65, 20.21, 19.6, 24.6, 23.19, 21.78, 21.85, 23.9, 22.36, 22.78, 19.94, 23.72, 21.61,
           22.29]

    print("Результати роботи програми:")

    print("Вибіркове середнє першої вибірки", vb_mean(vb1))
    print("Вибіркове середнє другої вибірки", vb_mean(vb2))

    print("Медіана першої вибірки", vb_median(vb1))
    print("Медіана другої вибірки", vb_median(vb2))

    print("Дисперсія першої вибірки:", vb_dispersion(vb1))
    print("Дисперсія другої вибірки:", vb_dispersion(vb2))

    print("середньоквадратичне відхилення першої вибірки:", vb_sigma(vb1))
    print("середньоквадратичне відхилення другої вибірки:", vb_sigma(vb2))

    print("Статистичний критерій гіпотези щодо рівності математичних сподівань двох генеральних сукупностей", stat_criterion(vb1, vb2))

    is_equal, p = is_mean_equal(vb1, vb2, a)

    if is_equal:
        print("Враховуючи те, що  p = {}, то ми приймаємо нульову гіпотезу".format(p))
    else:
        print("Враховуючи те, що  p = {}, то ми відхиляємо нульову гіпотезу".format(p))

    vb_histogram(vb1, "Перша вибірка")
    vb_histogram(vb2, "Друга вибірка")


main()
