import numpy as np, konstanter as k

def molalitet(V0, usikkerhet = False):

    m = (V0*k.c0)/(k.V*k.roh)

    if usikkerhet:
        avvik = np.sqrt(((k.c0 * k.s_V0) / (k.V * k.roh)) ** 2
                        + ((V0 * k.s_c0) / (k.V * k.roh)) ** 2
                        + ((V0 * k.c0 * k.s_V) / ((k.V ** 2) * k.roh)) ** 2)
        return m, avvik
    return m

def E_merket(E=1, T = 298, p = 1, V0 = 0.01, usikkerhet = False):
    m, s_m = molalitet(V0, usikkerhet = True)

    verdi = E + ((k.R*T) / k.F) * np.log((m**2) / np.sqrt(p))

    if usikkerhet:
        avvik = np.sqrt((k.s_E) ** 2
                        + (((k.R / k.F) * np.log((m ** 2) / np.sqrt(p))) * k.s_T) ** 2
                        + (((2 * k.R * T * np.sqrt(p)) / (k.F * m)) * s_m) ** 2
                        + (((-k.R * T) / (2 * k.F * p)) * k.s_p) ** 2)
        return verdi, avvik
    return verdi

def x_points(m=1, s_m=0.01, usikkerhet = False):
    x = np.sqrt(m)
    if usikkerhet:
        avvik = np.sqrt((s_m/(2*np.sqrt(m)))**2)
        return x,avvik
    return x

def A(T_points = [298], a = 1, s_a = 0.1, usikkerhet = False):
    T = sum(T_points)/len(T_points)
    A_verdi = (k.F * a)/(2*k.R * T * np.log(10))

    if usikkerhet:
        A_avvik = np.sqrt(((k.F / (2* k.R * T * np.log(10)) )*s_a)**2
                          + (((-k.F * a)/(2*k.R * (T**2) * np.log(10)))*k.s_T)**2)
        return A_verdi, A_avvik
    return A_verdi

def midlere_aktkoeff(V0, usikkerhet = False):
    m, s_m = molalitet(V0, usikkerhet=True)
    verdi = np.exp(-2*k.A*np.sqrt(m)*np.log(10))
    if usikkerhet:
        avvik = np.sqrt(((1/(2*np.sqrt(m)))*verdi*s_m)**2)
        return verdi, avvik
    return verdi