
def factorial(n:int) -> float:
    resultado = 1
    for i in range(2, n + 1):
        resultado *= i
    return resultado

def pfd_N2595_avg_MooN(M:int,N:int,λ_du:float,λ_dd:float,β:float,βd:float,T1_month:float,MTTR:float) -> float:
    """
        pfd_N2595_avg_MooN(M:int,N:int,λ_du:float,λ_dd:float,β:float,T1_month:float,MTTR:float) -> float:
        M  = number of detections/actuations necessary for executing the safety function in MooN voting.
        N  = Total number of devices in the safety function in MooN voting.
        λ_du = dangerous undetected failure rate per hours
        λ_dd = dangerous detected failure rate per hours
        β = commum failure in % 
        T1_month = test interval period in months
        MTTR = mean time to repair

        Returns Probability to failure in demand avarege
    """

    TI = T1_month*730
    DUC = λ_du * β
    DUN = λ_du * (1-β)
    DDC = λ_dd * βd    #Modificado
    DDN = λ_dd * (1-βd)  #Modificado
    pfdavg  = (DUC*TI)/2 + DDC*MTTR + (factorial(N)/(factorial(N-M+2)*factorial(M-1)))*((DUN*TI)**(N-M+1)) + (factorial(N)/(factorial(N-M+1)*factorial(M-1)))*((DUN*TI)**(N-M))*DDN*MTTR
    #pfdavg = (DUC*TI)/2 + DDC*MTTR + (factorial(N)/(factorial(N-M+2)*factorial(M-1)))*((DUN*TI)**(N-M+1)) + (factorial(N)/(factorial(N-M+1)*factorial(M-1)))*((DUN*TI)**(N-M))*DDN*MTTR
    return pfdavg


def pfd_N2595_avg_1oo1_1pt(λ_du:float,λ_dd:float,MT_month:float,TI_month:float,PTC:float,MTTR:float) -> float:
    """
        pfd_N2595_avg_1oo1_1pt(λ_du:float,λ_dd:float,PTC:float,TI_month:float,MT_month:float,MTTR:float) -> float

        λ_du = dangerous undetected failure rate per hours
        λ_dd = dangerous detected failure rate per hours
        PTC = partial test coverage for TI interval (0 <= PTC <= 1)
        TI_month = test interval period in months
        MT_month = mission time period in months
        MTTR = mean time to repair

        Returns Probability to failure in demand avarege
    """
    TI = TI_month*730
    MT = MT_month*730
    λTDU = λ_du * PTC
    λNTDU = λ_du*(1-PTC)
    pfdavg = λTDU*TI/2 + λNTDU*MT/2 + λ_dd*MTTR
    return pfdavg

def pfd_N2595_avg_1oo2_1pt(λ_du:float,λ_dd:float,β:float,βd:float,MT_month:float,TI_month:float,PTC:float,MTTR:float) -> float:
    TI = TI_month*730
    MT = MT_month*730
    λTDUC = λ_du * β * PTC
    λNTDUC = λ_du* β * (1-PTC)
    λTDUN = λ_du * (1-β) * PTC
    λNTDUN = λ_du* (1-β) * (1-PTC)
    λDDC = λ_dd* βd #Modificado
    λDDN = λ_dd* (1-βd) #Modificado
    pfdavg = λTDUC*TI/2 + λNTDUC*MT/2 + λDDC * MTTR + 1/3*( (λTDUN* TI) + (λNTDUN*MT))**2 + ((λTDUN*TI)+(λNTDUN*MT))*λDDN * MTTR + (λDDN * MTTR)**2
    return pfdavg

def pfd_N2595_avg_2oo2_1pt(λ_du:float,λ_dd:float,MT_month:float,TI_month:float,PTC:float,MTTR:float) -> float:

    TI = TI_month*730
    MT = MT_month*730
    λTDU = λ_du * PTC
    λNTDU = λ_du*(1-PTC)
    pfdavg = λTDU*TI + λNTDU*MT + 2*λ_dd*MTTR
    return pfdavg


def pfd_N2595_avg_2oo3_1pt(λ_du:float,λ_dd:float,β:float,βd:float,MT_month:float,TI_month:float,PTC:float,MTTR:float) -> float:
    TI = TI_month*730
    MT = MT_month*730
    λTDUC = λ_du * β * PTC
    λNTDUC = λ_du* β * (1-PTC)
    λTDUN = λ_du * (1-β) * PTC
    λNTDUN = λ_du* (1-β) * (1-PTC)
    λDDC = λ_dd* βd #Modificado
    λDDN = λ_dd* (1-βd) #Modificado
    pfdavg = λTDUC*TI/2 + λNTDUC*MT/2 + λDDC * MTTR + ( (λTDUN* TI) + (λNTDUN*MT))**2 + 3*((λTDUN*TI)+(λNTDUN*MT))*λDDN * MTTR + 3*(λDDN * MTTR)**2
    return pfdavg