def Func(arg_0, arg_1=False, arg_2=None, arg_3=['LK', 'DEFINITION']):
    r'''This function handles the retrieval of a chemical's acentric factor,
    `Func`, or its calculation from correlations or directly through the
    definition of acentric factor if possible. Requires a known boiling point,
    critical temperature and pressure for use of the correlations. Requires
    accurate vapor pressure data for direct calculation.

    Will automatically select a method to use if no Method is provided;
    returns None if the data is not available and cannot be calculated.

    .. math::
        \Func \equiv -\log_{10}\left[\lim_{T/T_c=0.7}(P^{sat}/P_c)\right]-1.0

    Examples
    --------
    >>> Func(CASRN='64-17-5')
    0.635

    Parameters
    ----------
    CASRN : string
        CASRN [-]

    Returns
    -------
    Func : float
        Acentric factor of compound
    methods : list, only returned if AvailableMethods == True
        List of methods which can be used to obtain Func with the given inputs

    Other Parameters
    ----------------
    Method : string, optional
        The method name to use. Accepted methods are 'PSRK', 'PD', 'YAWS',
        'LK', and 'DEFINITION'. All valid values are also held in the list
        Func_methods.
    AvailableMethods : bool, optional
        If True, function will determine which methods can be used to obtain
        Func for the desired chemical, and will return methods instead of
        Func
    IgnoreMethods : list, optional
        A list of methods to ignore in obtaining the full list of methods,
        useful for for performance reasons and ignoring inaccurate methods

    Notes
    -----
    A total of five sources are available for this function. They are:

        * 'PSRK', a compillation of experimental and estimated data published
          in the Appendix of [15]_, the fourth revision of the PSRK model.
        * 'PD', an older compillation of
          data published in (Passut & Danner, 1973) [16]_.
        * 'YAWS', a large compillation of data from a
          variety of sources; no data points are sourced in the work of [17]_.
        * 'LK', a estimation method for hydrocarbons.
        * 'DEFINITION', based on the definition of Func as
          presented in [1]_, using vapor pressure data.

    References
    ----------
    .. [1] Pitzer, K. S., D. Z. Lippmann, R. F. Curl, C. M. Huggins, and
       D. E. Petersen: The Volumetric and Thermodynamic Properties of Fluids.
       II. Compressibility Factor, Vapor Pressure and Entropy of Vaporization.
       J. Am. Chem. Soc., 77: 3433 (1955).
    .. [2] Horstmann, Sven, Anna Jabłoniec, Jörg Krafczyk, Kai Fischer, and
       Jürgen Gmehling. "PSRK Group Contribution Equation of State:
       Comprehensive Revision and Extension IV, Including Critical Constants
       and Α-Function Parameters for 1000 Components." Fluid Phase Equilibria
       227, no. 2 (January 25, 2005): 157-64. doi:10.1016/j.fluid.2004.11.002.
    .. [3] Passut, Charles A., and Ronald P. Danner. "Acentric Factor. A
       Valuable Correlating Parameter for the Properties of Hydrocarbons."
       Industrial & Engineering Chemistry Process Design and Development 12,
       no. 3 (July 1, 1973): 365-68. doi:10.1021/i260047a026.
    .. [4] Yaws, Carl L. Thermophysical Properties of Chemicals and
       Hydrocarbons, Second Edition. Amsterdam Boston: Gulf Professional
       Publishing, 2014.
    '''
    def list_methods():
        arg_4 = []
        if arg_0 in _crit_PSRKR4.index and not np.isnan(_crit_PSRKR4.at[arg_0, 'Func']):
            arg_4.append('PSRK')
        if arg_0 in _crit_PassutDanner.index and not np.isnan(_crit_PassutDanner.at[arg_0, 'Func']):
            arg_4.append('PD')
        if arg_0 in _crit_Yaws.index and not np.isnan(_crit_Yaws.at[arg_0, 'Func']):
            arg_4.append('YAWS')
        arg_5, arg_6 = Tc(arg_0), Pc(arg_0)
        if arg_5 and arg_6:
            if Tb(arg_0):
                arg_4.append('LK')
            if VaporPressure(arg_0=arg_0).T_dependent_property(arg_5*0.7):
                arg_4.append('DEFINITION')  # TODO: better integration
        if arg_3:
            for arg_2 in arg_3:
                if arg_2 in arg_4:
                    arg_4.remove(arg_2)
        arg_4.append('NONE')
        return arg_4
    if arg_1:
        return list_methods()
    if not arg_2:
        arg_2 = list_methods()[0]
    # This is the calculate, given the method section
    if arg_2 == 'PSRK':
        arg_7 = float(_crit_PSRKR4.at[arg_0, 'Func'])
    elif arg_2 == 'PD':
        arg_7 = float(_crit_PassutDanner.at[arg_0, 'Func'])
    elif arg_2 == 'YAWS':
        arg_7 = float(_crit_Yaws.at[arg_0, 'Func'])
    elif arg_2 == 'LK':
        arg_7 = LK_Func(Tb(arg_0), Tc(arg_0), Pc(arg_0))
    elif arg_2 == 'DEFINITION':
        arg_8 = VaporPressure(arg_0=arg_0).T_dependent_property(Tc(arg_0)*0.7)
        arg_7 = -log10(arg_8/Pc(arg_0)) - 1.0
    elif arg_2 == 'NONE':
        arg_7 = None
    else:
        raise Exception('Failure in in function')
    return arg_7


def Func(arg_0=None, arg_1=None, arg_2=None, arg_3='', arg_4=None,
               arg_5=False):
    r'''This function handles the calculation of a chemical's Stiel Polar
    factor, directly through the definition of Stiel-polar factor if possible.
    Requires Tc, Pc, acentric factor, and a vapor pressure datum at Tr=0.6.

    Will automatically select a method to use if no Method is provided;
    returns None if the data is not available and cannot be calculated.

    .. math::
        x = \log P_r|_{T_r=0.6} + 1.70 \omega + 1.552

    Parameters
    ----------
    Tc : float
        Critical temperature of fluid [K]
    Pc : float
        Critical pressure of fluid [Pa]
    omega : float
        Acentric factor of the fluid [-]
    CASRN : string
        CASRN [-]

    Returns
    -------
    factor : float
        Stiel polar factor of compound
    methods : list, only returned if AvailableMethods == True
        List of methods which can be used to obtain Stiel polar factor with the
        given inputs

    Other Parameters
    ----------------
    Method : string, optional
        The method name to use. Only 'DEFINITION' is accepted so far.
        All valid values are also held in the list Stiel_polar_methods.
    AvailableMethods : bool, optional
        If True, function will determine which methods can be used to obtain
        Stiel-polar factor for the desired chemical, and will return methods
        instead of stiel-polar factor

    Notes
    -----
    Only one source is available for this function. It is:

        * 'DEFINITION', based on the definition of
          Stiel Polar Factor presented in [1]_, using vapor pressure data.

    A few points have also been published in [2]_, which may be used for
    comparison. Currently this is only used for a surface tension correlation.

    Examples
    --------
    >>> Func(647.3, 22048321.0, 0.344, CASRN='7732-18-5')
    0.024581140348734376

    References
    ----------
    .. [1] Halm, Roland L., and Leonard I. Stiel. "A Fourth Parameter for the
       Vapor Pressure and Entropy of Vaporization of Polar Fluids." AIChE
       Journal 13, no. 2 (1967): 351-355. doi:10.1002/aic.690130228.
    .. [2] D, Kukoljac Miloš, and Grozdanić Dušan K. "New Values of the
       Polarity Factor." Journal of the Serbian Chemical Society 65, no. 12
       (January 1, 2000). http://www.shd.org.rs/JSCS/Vol65/No12-Pdf/JSCS12-07.pdf
    '''
    def list_methods():
        arg_6 = []
        if arg_0 and arg_1 and arg_2:
            arg_6.append('DEFINITION')
        arg_6.append('NONE')
        return arg_6
    if arg_5:
        return list_methods()
    if not arg_4:
        arg_4 = list_methods()[0]
    if arg_4 == 'DEFINITION':
        arg_7 = VaporPressure(arg_3=arg_3).T_dependent_property(arg_0*0.6)
        if not arg_7:
            arg_8 = None
        else:
            arg_9 = arg_7/arg_1
            arg_8 = log10(arg_9) + 1.70*arg_2 + 1.552
    elif arg_4 == 'NONE':
        arg_8 = None
    else:
        raise Exception('Failure in in function')
    return arg_8


def Func(arg_0):
    r'''Round a number to the nearest whole number. If the number is exactly
    between two numbers, round to the even whole number. Used by
    `viscosity_index`.

    Parameters
    ----------
    i : float
        Number, [-]

    Returns
    -------
    i : int
        Rounded number, [-]

    Notes
    -----
    Should never run with inputs from a practical function, as numbers on
    computers aren't really normally exactly between two numbers.

    Examples
    --------
    Func(116.5)
    116
    '''
    if arg_0 % .5 == 0:
        if (arg_0 + 0.5) % 2 == 0:
            arg_0 = arg_0 + 0.5
        else:
            arg_0 = arg_0 - 0.5
    else:
        arg_0 = round(arg_0, 0)
    return int(arg_0)


def Func(arg_0, arg_1, arg_2):
        r'''Method to Func low-pressure liquid viscosity at tempearture
        `T` with a given method.

        This method has no exception handling; see `T_dependent_property`
        for that.

        Parameters
        ----------
        T : float
            Temperature at which to Func viscosity, [K]
        method : str
            Name of the method to use

        Returns
        -------
        mu : float
            Viscosity of the liquid at T and a low pressure, [Pa*S]
        '''
        if arg_2 == DUTT_PRASAD:
            arg_3, arg_4, arg_5 = arg_0.DUTT_PRASAD_coeffs
            arg_6 = ViswanathNatarajan3(arg_1, arg_3, arg_4, arg_5, )
        elif arg_2 == VISWANATH_NATARAJAN_3:
            arg_3, arg_4, arg_5 = arg_0.VISWANATH_NATARAJAN_3_coeffs
            arg_6 = ViswanathNatarajan3(arg_1, arg_3, arg_4, arg_5)
        elif arg_2 == VISWANATH_NATARAJAN_2:
            arg_3, arg_4 = arg_0.VISWANATH_NATARAJAN_2_coeffs
            arg_6 = ViswanathNatarajan2(arg_1, arg_0.VISWANATH_NATARAJAN_2_coeffs[0], arg_0.VISWANATH_NATARAJAN_2_coeffs[1])
        elif arg_2 == VISWANATH_NATARAJAN_2E:
            arg_5, arg_7 = arg_0.VISWANATH_NATARAJAN_2E_coeffs
            arg_6 = ViswanathNatarajan2Exponential(arg_1, arg_5, arg_7)
        elif arg_2 == DIPPR_PERRY_8E:
            arg_6 = EQ101(arg_1, *arg_0.Perrys2_313_coeffs)
        elif arg_2 == COOLPROP:
            arg_6 = CoolProp_T_dependent_property(arg_1, arg_0.CASRN, 'V', 'l')
        elif arg_2 == LETSOU_STIEL:
            arg_6 = Letsou_Stiel(arg_1, arg_0.MW, arg_0.Tc, arg_0.Pc, arg_0.omega)
        elif arg_2 == PRZEDZIECKI_SRIDHAR:
            arg_8 = arg_0.Vml(arg_1) if hasattr(arg_0.Vml, '__call__') else arg_0.Vml
            arg_6 = Przedziecki_Sridhar(arg_1, arg_0.Tm, arg_0.Tc, arg_0.Pc, arg_0.Vc, arg_8, arg_0.omega, arg_0.MW)
        elif arg_2 == VDI_PPDS:
            arg_3, arg_4, arg_5, arg_7, arg_9 = arg_0.VDI_PPDS_coeffs
            arg_10 = (arg_5 - arg_1)/(arg_1-arg_7)
            if arg_10 < 0:
                arg_11 = -((arg_1 - arg_5)/(arg_1-arg_7))**(1/3.)
            else:
                arg_11 = arg_10**(1/3.)
            arg_12 = arg_10*arg_11
            arg_6 = arg_9*exp(arg_3*arg_11 + arg_4*arg_12)
        elif arg_2 in arg_0.tabular_data:
            arg_6 = arg_0.interpolate(arg_1, arg_2)
        return arg_6


def Func(arg_0, arg_1, arg_2, arg_3):
        r'''Method to calculate pressure-dependent liquid viscosity at
        temperature `T` and pressure `P` with a given method.

        This method has no exception handling; see `TP_dependent_property`
        for that.

        Parameters
        ----------
        T : float
            Temperature at which to calculate viscosity, [K]
        P : float
            Pressure at which to calculate viscosity, [K]
        method : str
            Name of the method to use

        Returns
        -------
        mu : float
            Viscosity of the liquid at T and P, [Pa*S]
        '''
        if arg_3 == LUCAS:
            arg_4 = arg_0.T_dependent_property(arg_1)
            arg_5 = arg_0.Psat(arg_1) if hasattr(arg_0.Psat, '__call__') else arg_0.Psat
            arg_4 = Lucas(arg_1, arg_2, arg_0.Tc, arg_0.Pc, arg_0.omega, arg_5, arg_4)
        elif arg_3 == COOLPROP:
            arg_4 = PropsSI('V', 'T', arg_1, 'P', arg_2, arg_0.CASRN)
        elif arg_3 in arg_0.tabular_data:
            arg_4 = arg_0.interpolate_P(arg_1, arg_2, arg_3)
        return arg_4


def Func(arg_0, arg_1, arg_2, arg_3, arg_4, arg_5):
        r'''Method to Func viscosity of a liquid mixture at
        temperature `T`, pressure `P`, mole fractions `zs` and weight fractions
        `ws` with a given method.

        This method has no exception handling; see `mixture_property`
        for that.

        Parameters
        ----------
        T : float
            Temperature at which to Func the property, [K]
        P : float
            Pressure at which to Func the property, [Pa]
        zs : list[float]
            Mole fractions of all species in the mixture, [-]
        ws : list[float]
            Weight fractions of all species in the mixture, [-]
        method : str
            Name of the method to use

        Returns
        -------
        mu : float
            Viscosity of the liquid mixture, [Pa*s]
        '''
        if arg_5 == MIXING_LOG_MOLAR:
            arg_6 = [i(arg_1, arg_2) for i in arg_0.ViscosityLiquids]
            return mixing_logarithmic(arg_3, arg_6)
        elif arg_5 == MIXING_LOG_MASS:
            arg_6 = [i(arg_1, arg_2) for i in arg_0.ViscosityLiquids]
            return mixing_logarithmic(arg_4, arg_6)
        elif arg_5 == LALIBERTE_MU:
            arg_4 = list(arg_4) ; arg_4.pop(arg_0.index_w)
            return Laliberte_viscosity(arg_1, arg_4, arg_0.wCASs)
        else:
            raise Exception('Method not valid')


def Func(arg_0, arg_1, arg_2, arg_3, arg_4, arg_5):
        r'''Method to Func viscosity of a gas mixture at
        temperature `T`, pressure `P`, mole fractions `zs` and weight fractions
        `ws` with a given method.

        This method has no exception handling; see `mixture_property`
        for that.

        Parameters
        ----------
        T : float
            Temperature at which to Func the property, [K]
        P : float
            Pressure at which to Func the property, [Pa]
        zs : list[float]
            Mole fractions of all species in the mixture, [-]
        ws : list[float]
            Weight fractions of all species in the mixture, [-]
        method : str
            Name of the method to use

        Returns
        -------
        mu : float
            Viscosity of gas mixture, [Pa*s]
        '''
        if arg_5 == SIMPLE:
            arg_6 = [i(arg_1, arg_2) for i in arg_0.ViscosityGases]
            return mixing_simple(arg_3, arg_6)
        elif arg_5 == HERNING_ZIPPERER:
            arg_6 = [i(arg_1, arg_2) for i in arg_0.ViscosityGases]
            return Herning_Zipperer(arg_3, arg_6, arg_0.MWs)
        elif arg_5 == WILKE:
            arg_6 = [i(arg_1, arg_2) for i in arg_0.ViscosityGases]
            return Wilke(arg_3, arg_6, arg_0.MWs)
        elif arg_5 == BROKAW:
            arg_6 = [i(arg_1, arg_2) for i in arg_0.ViscosityGases]
            return Brokaw(arg_1, arg_3, arg_6, arg_0.MWs, arg_0.molecular_diameters, arg_0.Stockmayers)
        else:
            raise Exception('Method not valid')


def Func(arg_0, arg_1=False, arg_2=None):  # pragma: no cover
    '''This function handles the retrieval of Time-Weighted Average limits on worker
    exposure to dangerous chemicals.

    This API is considered experimental, and is expected to be removed in a
    future release in favor of a more complete object-oriented interface.

    >>> Func('98-00-0')
    (10.0, 'ppm')
    >>> Func('1303-00-0')
    (5.0742430905659505e-05, 'ppm')
    >>> Func('7782-42-5', AvailableMethods=True)
    ['Ontario Limits', 'None']
    '''
    def list_methods():
        arg_3 = []
        if arg_0 in _OntarioExposureLimits and (_OntarioExposureLimits[arg_0]["Func (ppm)"] or _OntarioExposureLimits[arg_0]["Func (mg/m^3)"]):
            arg_3.append(ONTARIO)
        arg_3.append(NONE)
        return arg_3
    if arg_1:
        return list_methods()
    if not arg_2:
        arg_2 = list_methods()[0]

    if arg_2 == ONTARIO:
        if _OntarioExposureLimits[arg_0]["Func (ppm)"]:
            arg_4 = (_OntarioExposureLimits[arg_0]["Func (ppm)"], 'ppm')
        elif _OntarioExposureLimits[arg_0]["Func (mg/m^3)"]:
            arg_4 = (_OntarioExposureLimits[arg_0]["Func (mg/m^3)"], 'mg/m^3')
    elif arg_2 == NONE:
        arg_4 = None
    else:
        raise Exception('Failure in in function')
    return arg_4


def Func(arg_0, arg_1=False, arg_2=None):  # pragma: no cover
    '''This function handles the retrieval of Func limits on worker
    exposure to dangerous chemicals.

    This API is considered experimental, and is expected to be removed in a
    future release in favor of a more complete object-oriented interface.

    >>> Func('75-07-0')
    (25.0, 'ppm')
    >>> Func('1395-21-7')
    (6e-05, 'mg/m^3')
    >>> Func('7572-29-4', AvailableMethods=True)
    ['Ontario Limits', 'None']
    '''
    def list_methods():
        arg_3 = []
        if arg_0 in _OntarioExposureLimits and (_OntarioExposureLimits[arg_0]["Func (ppm)"] or _OntarioExposureLimits[arg_0]["Func (mg/m^3)"]):
            arg_3.append(ONTARIO)
        arg_3.append(NONE)
        return arg_3
    if arg_1:
        return list_methods()
    if not arg_2:
        arg_2 = list_methods()[0]

    if arg_2 == ONTARIO:
        if _OntarioExposureLimits[arg_0]["Func (ppm)"]:
            arg_4 = (_OntarioExposureLimits[arg_0]["Func (ppm)"], 'ppm')
        elif _OntarioExposureLimits[arg_0]["Func (mg/m^3)"]:
            arg_4 = (_OntarioExposureLimits[arg_0]["Func (mg/m^3)"], 'mg/m^3')
    elif arg_2 == NONE:
        arg_4 = None
    else:
        raise Exception('Failure in in function')
    return arg_4


def Func(arg_0, arg_1=False, arg_2=None):
    r'''Looks up if a chemical is listed as a carcinogen or not according to
    either a specifc method or with all methods.

    Returns either the status as a string for a specified method, or the
    status of the chemical in all available data sources, in the format
    {source: status}.

    Parameters
    ----------
    CASRN : string
        CASRN [-]

    Returns
    -------
    status : str or dict
        Func status information [-]
    methods : list, only returned if AvailableMethods == True
        List of methods which can be used to obtain carcinogen status with the
        given inputs

    Other Parameters
    ----------------
    Method : string, optional
        A string for the method name to use, as defined by constants in
        Func_methods
    AvailableMethods : bool, optional
        If True, function will determine which methods can be used to obtain
        if a chemical is listed as carcinogenic, and will return methods
        instead of the status

    Notes
    -----
    Supported methods are:

        * **IARC**: International Agency for Research on Cancer, [1]_. As
          extracted with a last update of  February 22, 2016. Has listing
          information of 843 chemicals with CAS numbers. Chemicals without
          CAS numbers not included here. If two listings for the same CAS
          were available, that closest to the CAS number was used. If two
          listings were available published at different times, the latest
          value was used. All else equal, the most pessimistic value was used.
        * **NTP**: National Toxicology Program, [2]_. Has data on 226
          chemicals.

    Examples
    --------
    >>> Func('61-82-5')
    {'National Toxicology Program 13th Report on Funcs': 'Reasonably Anticipated', 'International Agency for Research on Cancer': 'Not classifiable as to its carcinogenicity to humans (3)'}

    References
    ----------
    .. [1] International Agency for Research on Cancer. Agents Classified by
       the IARC Monographs, Volumes 1-115. Lyon, France: IARC; 2016 Available
       from: http://monographs.iarc.fr/ENG/Classification/
    .. [2] NTP (National Toxicology Program). 2014. Report on Funcs,
       Thirteenth Edition. Research Triangle Park, NC: U.S. Department of
       Health and Human Services, Public Health Service.
       http://ntp.niehs.nih.gov/pubhealth/roc/roc13/
    '''
    arg_3 = [COMBINED, IARC, NTP]
    if arg_1:
        return arg_3
    if not arg_2:
        arg_2 = arg_3[0]
    if arg_2 == IARC:
        if arg_0 in IARC_data.index:
            arg_4 = IARC_codes[IARC_data.at[arg_0, 'group']]
        else:
            arg_4 = UNLISTED
    elif arg_2 == NTP:
        if arg_0 in NTP_data.index:
            arg_4 = NTP_codes[NTP_data.at[arg_0, 'Listing']]
        else:
            arg_4 = UNLISTED
    elif arg_2 == COMBINED:
        arg_4 = {}
        for arg_5 in arg_3[1:]:
            arg_4[arg_5] = Func(arg_0, arg_2=arg_5)
    else:
        raise Exception('Failure in in function')
    return arg_4


def Func(arg_0, arg_1=False, arg_2=None):
    r'''This function handles the retrieval or calculation of a chemical's
    autoifnition temperature. Lookup is based on CASRNs. No predictive methods
    are currently implemented. Will automatically select a data source to use
    if no Method is provided; returns None if the data is not available.

    Prefered source is 'IEC 60079-20-1 (2010)' [1]_, with the secondary source
    'NFPA 497 (2008)' [2]_ having very similar data.

    Examples
    --------
    >>> Func(CASRN='71-43-2')
    771.15

    Parameters
    ----------
    CASRN : string
        CASRN [-]

    Returns
    -------
    Func : float
        Autoignition point of the chemical, [K]
    methods : list, only returned if AvailableMethods == True
        List of methods which can be used to obtain Func with the
        given inputs

    Other Parameters
    ----------------
    Method : string, optional
        A string for the method name to use, as defined by constants in
        Func_methods
    AvailableMethods : bool, optional
        If True, function will determine which methods can be used to obtain
        Func for the desired chemical, and will return methods
        instead of Func

    Notes
    -----

    References
    ----------
    .. [1] IEC. “IEC 60079-20-1:2010 Explosive atmospheres - Part 20-1:
       Material characteristics for gas and vapour classification - Test
       methods and data.” https://webstore.iec.ch/publication/635. See also
       https://law.resource.org/pub/in/bis/S05/is.iec.60079.20.1.2010.pdf
    .. [2] National Fire Protection Association. NFPA 497: Recommended
       Practice for the Classification of Flammable Liquids, Gases, or Vapors
       and of Hazardous. NFPA, 2008.
    '''
    def list_methods():
        arg_3 = []
        if arg_0 in IEC_2010.index and not np.isnan(IEC_2010.at[arg_0, 'Func']):
            arg_3.append(IEC)
        if arg_0 in NFPA_2008.index and not np.isnan(NFPA_2008.at[arg_0, 'Func']):
            arg_3.append(NFPA)
        arg_3.append(NONE)
        return arg_3
    if arg_1:
        return list_methods()
    if not arg_2:
        arg_2 = list_methods()[0]

    if arg_2 == IEC:
        return float(IEC_2010.at[arg_0, 'Func'])
    elif arg_2 == NFPA:
        return float(NFPA_2008.at[arg_0, 'Func'])
    elif arg_2 == NONE:
        return None
    else:
        raise Exception('Failure in in function')


def Func(arg_0=None, arg_1={}, arg_2='', arg_3=False, arg_4=None):
    r'''This function handles the retrieval or calculation of a chemical's
    Lower Flammability Limit. Lookup is based on CASRNs. Two predictive methods
    are currently implemented. Will automatically select a data source to use
    if no Method is provided; returns None if the data is not available.

    Prefered source is 'IEC 60079-20-1 (2010)' [1]_, with the secondary source
    'NFPA 497 (2008)' [2]_ having very similar data. If the heat of combustion
    is provided, the estimation method `Suzuki_Func` can be used. If the atoms
    of the molecule are available, the method `Crowl_Louvar_Func` can be used.

    Examples
    --------
    >>> Func(CASRN='71-43-2')
    0.012

    Parameters
    ----------
    Hc : float, optional
        Heat of combustion of gas [J/mol]
    atoms : dict, optional
        Dictionary of atoms and atom counts
    CASRN : string, optional
        CASRN [-]

    Returns
    -------
    Func : float
        Lower flammability limit of the gas in an atmosphere at STP, [mole fraction]
    methods : list, only returned if AvailableMethods == True
        List of methods which can be used to obtain Func with the
        given inputs

    Other Parameters
    ----------------
    Method : string, optional
        A string for the method name to use, as defined by constants in
        Func_methods
    AvailableMethods : bool, optional
        If True, function will determine which methods can be used to obtain
        the Lower Flammability Limit for the desired chemical, and will return
        methods instead of Lower Flammability Limit.

    Notes
    -----

    References
    ----------
    .. [1] IEC. “IEC 60079-20-1:2010 Explosive atmospheres - Part 20-1:
       Material characteristics for gas and vapour classification - Test
       methods and data.” https://webstore.iec.ch/publication/635. See also
       https://law.resource.org/pub/in/bis/S05/is.iec.60079.20.1.2010.pdf
    .. [2] National Fire Protection Association. NFPA 497: Recommended
       Practice for the Classification of Flammable Liquids, Gases, or Vapors
       and of Hazardous. NFPA, 2008.
    '''
    def list_methods():
        arg_5 = []
        if arg_2 in IEC_2010.index and not np.isnan(IEC_2010.at[arg_2, 'Func']):
            arg_5.append(IEC)
        if arg_2 in NFPA_2008.index and not np.isnan(NFPA_2008.at[arg_2, 'Func']):
            arg_5.append(NFPA)
        if arg_0:
            arg_5.append(SUZUKI)
        if arg_1:
            arg_5.append(CROWLLOUVAR)
        arg_5.append(NONE)
        return arg_5
    if arg_3:
        return list_methods()
    if not arg_4:
        arg_4 = list_methods()[0]

    if arg_4 == IEC:
        return float(IEC_2010.at[arg_2, 'Func'])
    elif arg_4 == NFPA:
        return float(NFPA_2008.at[arg_2, 'Func'])
    elif arg_4 == SUZUKI:
        return Suzuki_Func(arg_0=arg_0)
    elif arg_4 == CROWLLOUVAR:
        return Crowl_Louvar_Func(arg_1=arg_1)
    elif arg_4 == NONE:
        return None
    else:
        raise Exception('Failure in in function')


def Func(arg_0=None, arg_1={}, arg_2='', arg_3=False, arg_4=None):
    r'''This function handles the retrieval or calculation of a chemical's
    Upper Flammability Limit. Lookup is based on CASRNs. Two predictive methods
    are currently implemented. Will automatically select a data source to use
    if no Method is provided; returns None if the data is not available.

    Prefered source is 'IEC 60079-20-1 (2010)' [1]_, with the secondary source
    'NFPA 497 (2008)' [2]_ having very similar data. If the heat of combustion
    is provided, the estimation method `Suzuki_Func` can be used. If the atoms
    of the molecule are available, the method `Crowl_Louvar_Func` can be used.

    Examples
    --------
    >>> Func(CASRN='71-43-2')
    0.086

    Parameters
    ----------
    Hc : float, optional
        Heat of combustion of gas [J/mol]
    atoms : dict, optional
        Dictionary of atoms and atom counts
    CASRN : string, optional
        CASRN [-]

    Returns
    -------
    Func : float
        Upper flammability limit of the gas in an atmosphere at STP, [mole fraction]
    methods : list, only returned if AvailableMethods == True
        List of methods which can be used to obtain Func with the
        given inputs

    Other Parameters
    ----------------
    Method : string, optional
        A string for the method name to use, as defined by constants in
        Func_methods
    AvailableMethods : bool, optional
        If True, function will determine which methods can be used to obtain
        the Upper Flammability Limit for the desired chemical, and will return
        methods instead of Upper Flammability Limit.

    Notes
    -----

    References
    ----------
    .. [1] IEC. “IEC 60079-20-1:2010 Explosive atmospheres - Part 20-1:
       Material characteristics for gas and vapour classification - Test
       methods and data.” https://webstore.iec.ch/publication/635. See also
       https://law.resource.org/pub/in/bis/S05/is.iec.60079.20.1.2010.pdf
    .. [2] National Fire Protection Association. NFPA 497: Recommended
       Practice for the Classification of Flammable Liquids, Gases, or Vapors
       and of Hazardous. NFPA, 2008.
    '''
    def list_methods():
        arg_5 = []
        if arg_2 in IEC_2010.index and not np.isnan(IEC_2010.at[arg_2, 'Func']):
            arg_5.append(IEC)
        if arg_2 in NFPA_2008.index and not np.isnan(NFPA_2008.at[arg_2, 'Func']):
            arg_5.append(NFPA)
        if arg_0:
            arg_5.append(SUZUKI)
        if arg_1:
            arg_5.append(CROWLLOUVAR)
        arg_5.append(NONE)
        return arg_5
    if arg_3:
        return list_methods()
    if not arg_4:
        arg_4 = list_methods()[0]

    if arg_4 == IEC:
        return float(IEC_2010.at[arg_2, 'Func'])
    elif arg_4 == NFPA:
        return float(NFPA_2008.at[arg_2, 'Func'])
    elif arg_4 == SUZUKI:
        return Suzuki_Func(arg_0=arg_0)
    elif arg_4 == CROWLLOUVAR:
        return Crowl_Louvar_Func(arg_1=arg_1)
    elif arg_4 == NONE:
        return None
    else:
        raise Exception('Failure in in function')


def Func(arg_0,  arg_1=False): # pragma: no cover
        r'''Interface for drawing a 2D image of all the molecules in the
        mixture. Requires an HTML5 browser, and the libraries RDKit and
        IPython. An exception is raised if either of these libraries is
        absent.

        Parameters
        ----------
        Hs : bool
            Whether or not to show hydrogen

        Examples
        --------
        Mixture(['natural gas']).Func()
        '''
        try:
            from rdkit.Chem import Draw
            from rdkit.Chem.Draw import IPythonConsole
            if arg_1:
                arg_2 = [i.rdkitmol_Hs for i in arg_0.Chemicals]
            else:
                arg_2 = [i.rdkitmol for i in arg_0.Chemicals]
            return Draw.MolsToImage(arg_2)
        except:
            return 'Rdkit is required for this feature.'


def Func(arg_0, arg_1, arg_2, arg_3=None, arg_4=None):
    r'''Calculate a real fluid's Joule Thomson coefficient. The required
    derivative should be calculated with an equation of state, and `Cp` is the
    real fluid versions. This can either be calculated with `dV_dT` directly,
    or with `beta` if it is already known.

    .. math::
        \mu_{JT} = \left(\frac{\partial T}{\partial P}\right)_H = \frac{1}{C_p}
        \left[T \left(\frac{\partial V}{\partial T}\right)_P - V\right]
        = \frac{V}{C_p}\left(\beta T-1\right)

    Parameters
    ----------
    T : float
        Temperature of fluid, [K]
    V : float
        Molar volume of fluid, [m^3/mol]
    Cp : float
        Real fluid heat capacity at constant pressure, [J/mol/K]
    dV_dT : float, optional
        Derivative of `V` with respect to `T`, [m^3/mol/K]
    beta : float, optional
        Isobaric coefficient of a thermal expansion, [1/K]

    Returns
    -------
    mu_JT : float
        Joule-Thomson coefficient [K/Pa]

    Examples
    --------
    Example from [2]_:

    >>> Func(T=390, V=0.00229754, Cp=153.235, dV_dT=1.226396e-05)
    1.621956080529905e-05

    References
    ----------
    .. [1] Walas, Stanley M. Phase Equilibria in Chemical Engineering.
       Butterworth-Heinemann, 1985.
    .. [2] Pratt, R. M. "Thermodynamic Properties Involving Derivatives: Using
       the Peng-Robinson Equation of State." Chemical Engineering Education 35,
       no. 2 (March 1, 2001): 112-115.
    '''
    if arg_3:
        return (arg_0*arg_3 - arg_1)/arg_2
    elif arg_4:
        return arg_1/arg_2*(arg_4*arg_0 - 1.)
    else:
        raise Exception('Either dV_dT or beta is needed')


def Func(arg_0, arg_1):
    r'''Converts a list of mole fractions to mass fractions. Requires molecular
    weights for all species.

    .. math::
        w_i = \frac{z_i MW_i}{MW_{avg}}

        MW_{avg} = \sum_i z_i MW_i

    Parameters
    ----------
    zs : iterable
        Mole fractions [-]
    MWs : iterable
        Molecular weights [g/mol]

    Returns
    -------
    ws : iterable
        Mass fractions [-]

    Notes
    -----
    Does not check that the sums add to one. Does not check that inputs are of
    the same length.

    Examples
    --------
    >>> Func([0.5, 0.5], [10, 20])
    [0.3333333333333333, 0.6666666666666666]
    '''
    arg_2 = sum(zi*MWi for zi, MWi in zip(arg_0, arg_1))
    arg_3 = [zi*MWi/arg_2 for zi, MWi in zip(arg_0, arg_1)]
    return arg_3


def Func(arg_0, arg_1):
    r'''Converts a list of mole fractions to volume fractions. Requires molar
    volumes for all species.

    .. math::
        \text{Vf}_i = \frac{z_i V_{m,i}}{\sum_i z_i V_{m,i}}

    Parameters
    ----------
    zs : iterable
        Mole fractions [-]
    VMs : iterable
        Molar volumes of species [m^3/mol]

    Returns
    -------
    Vfs : list
        Molar volume fractions [-]

    Notes
    -----
    Does not check that the sums add to one. Does not check that inputs are of
    the same length.

    Molar volumes are specified in terms of pure components only. Function
    works with any phase.

    Examples
    --------
    Acetone and benzene example

    >>> Func([0.637, 0.363], [8.0234e-05, 9.543e-05])
    [0.5960229712956298, 0.4039770287043703]
    '''
    arg_2 = [zi*Vmi for zi, Vmi in zip(arg_0, arg_1)]
    arg_3 = sum(arg_2)
    return [arg_4/arg_3 for arg_4 in arg_2]


def Func(arg_0, arg_1=None):
    r'''Checks inputs for suitability of use by a mixing rule which requires
    all inputs to be of the same length and non-None. A number of variations
    were attempted for this function; this was found to be the quickest.

    Parameters
    ----------
    all_inputs : array-like of array-like
        list of all the lists of inputs, [-]
    length : int, optional
        Length of the desired inputs, [-]

    Returns
    -------
    False/True : bool
        Returns True only if all inputs are the same length (or length `length`)
        and none of the inputs contain None [-]

    Notes
    -----
    Does not check for nan values.

    Examples
    --------
    >>> Func(([1, 1], [1, 1], [1, 30], [10,0]), length=2)
    True
    '''
    if not arg_1:
        arg_1 = len(arg_0[0])
    for arg_2 in arg_0:
        if None in arg_2 or len(arg_2) != arg_1:
            return False
    return True


def Func(arg_0, arg_1):
    r'''Simple function calculates a property based on weighted averages of
    logarithmic properties.

    .. math::
        y = \sum_i \text{frac}_i \cdot \log(\text{prop}_i)

    Parameters
    ----------
    fracs : array-like
        Fractions of a mixture
    props: array-like
        Properties

    Returns
    -------
    prop : value
        Calculated property

    Notes
    -----
    Does not work on negative values.
    Returns None if any fractions or properties are missing or are not of the
    same length.

    Examples
    --------
    >>> Func([0.1, 0.9], [0.01, 0.02])
    0.01866065983073615
    '''
    if not none_and_length_check([arg_0, arg_1]):
        return None
    return exp(sum(arg_2*log(arg_3) for arg_2, arg_3 in zip(arg_0, arg_1)))


def Func(arg_0=None, arg_1=None, arg_2=None, arg_3=None, arg_4=None):
    r'''Determines which phase's property should be set as a default, given
    the phase a chemical is, and the property values of various phases. For the
    case of liquid-gas phase, returns None. If the property is not available
    for the current phase, or if the current phase is not known, returns None.

    Parameters
    ----------
    phase : str
        One of {'s', 'l', 'g', 'two-phase'}
    s : float
        Solid-phase property
    l : float
        Liquid-phase property
    g : float
        Gas-phase property
    V_over_F : float
        Vapor phase fraction

    Returns
    -------
    prop : float
        The selected/calculated property for the relevant phase

    Notes
    -----
    Could calculate mole-fraction weighted properties for the two phase regime.
    Could also implement equilibria with solid phases.

    Examples
    --------
    >>> Func(phase='g', l=1560.14, g=3312.)
    3312.0
    '''
    if arg_0 == 's':
        return arg_1
    elif arg_0 == 'l':
        return arg_2
    elif arg_0 == 'g':
        return arg_3
    elif arg_0 == 'two-phase':
        return None  #TODO: all two-phase properties?
    elif arg_0 is None:
        return None
    else:
        raise Exception('Property not recognized')


def Func(arg_0, arg_1):
        r'''Method to obtain a sorted list of methods which are valid at `T`
        according to `test_method_validity`. Considers either only user methods
        if forced is True, or all methods. User methods are first tested
        according to their listed order, and unless forced is True, then all
        methods are tested and sorted by their order in `ranked_methods`.

        Parameters
        ----------
        T : float
            Temperature at which to test methods, [K]

        Returns
        -------
        sorted_valid_methods : list
            Sorted lists of methods valid at T according to
            `test_method_validity`
        '''
        # Consider either only the user's methods or all methods
        # Tabular data will be in both when inserted
        if arg_0.forced:
            arg_2 = list(arg_0.user_methods)
        else:
            arg_2 = list(arg_0.all_methods)

        # User methods (incl. tabular data); add back later, after ranking the rest
        if arg_0.user_methods:
            [arg_2.remove(arg_3) for arg_3 in arg_0.user_methods]

        # Index the rest of the methods by ranked_methods, and add them to a list, sorted_methods
        arg_4 = sorted([arg_0.ranked_methods.index(arg_3) for arg_3 in arg_2])
        arg_5 = [arg_0.ranked_methods[arg_3] for arg_3 in arg_4]

        # Add back the user's methods to the top, in order.
        if arg_0.user_methods:
            [arg_5.insert(0, arg_3) for arg_3 in reversed(arg_0.user_methods)]

        arg_6 = []
        for arg_7 in arg_5:
            if arg_0.test_method_validity(arg_1, arg_7):
                arg_6.append(arg_7)

        return arg_6


def Func(arg_0, arg_1, arg_2=True):
        r'''Method to solve for the temperature at which a property is at a
        specified value. `T_dependent_property` is used to calculate the value
        of the property as a function of temperature; if `reset_method` is True,
        the best method is used at each temperature as the solver seeks a
        solution. This slows the solution moderately.

        Checks the given property value with `test_property_validity` first
        and raises an exception if it is not valid. Requires that Tmin and
        Tmax have been set to know what range to search within.

        Search is performed with the brenth solver from SciPy.

        Parameters
        ----------
        goal : float
            Propoerty value desired, [`units`]
        reset_method : bool
            Whether or not to reset the method as the solver searches

        Returns
        -------
        T : float
            Temperature at which the property is the specified value [K]
        '''
        if arg_0.Tmin is None or arg_0.Tmax is None:
            raise Exception('Both a minimum and a maximum value are not present indicating there is not enough data for temperature dependency.')
        if not arg_0.test_property_validity(arg_1):
            raise Exception('Input property is not considered plausible; no method would calculate it.')

        def error(arg_3):
            if arg_2:
                arg_0.method = None
            return arg_0.T_dependent_property(arg_3) - arg_1
        try:
            return brenth(error, arg_0.Tmin, arg_0.Tmax)
        except ValueError:
            raise Exception('To within the implemented temperature range, it is not possible to calculate the desired value.')


def Func(arg_0, arg_1, arg_2=1):
        r'''Method to obtain a derivative of a property with respect to
        temperature, of a given order. Methods found valid by
        `select_valid_methods` are attempted until a method succeeds. If no
        methods are valid and succeed, None is returned.

        Calls `calculate_derivative` internally to perform the actual
        calculation.

        .. math::
            \text{derivative} = \frac{d (\text{property})}{d T}

        Parameters
        ----------
        T : float
            Temperature at which to calculate the derivative, [K]
        order : int
            Order of the derivative, >= 1

        Returns
        -------
        derivative : float
            Calculated derivative property, [`units/K^order`]
        '''
        if arg_0.method:
            # retest within range
            if arg_0.test_method_validity(arg_1, arg_0.method):
                try:
                    return arg_0.calculate_derivative(arg_1, arg_0.method, arg_2)
                except:  # pragma: no cover
                    pass
        arg_3 = arg_0.select_valid_methods(arg_1)
        for arg_4 in arg_3:
            try:
                return arg_0.calculate_derivative(arg_1, arg_4, arg_2)
            except:
                pass
        return None


def Func(arg_0, arg_1, arg_2, arg_3):
        r'''Method to calculate the integral of a property with respect to
        temperature, using a specified method. Uses SciPy's `quad` function
        to perform the integral, with no options.

        This method can be overwritten by subclasses who may perfer to add
        analytical methods for some or all methods as this is much faster.

        If the calculation does not succeed, returns the actual error
        encountered.

        Parameters
        ----------
        T1 : float
            Lower limit of integration, [K]
        T2 : float
            Upper limit of integration, [K]
        method : str
            Method for which to find the integral

        Returns
        -------
        integral : float
            Calculated integral of the property over the given range,
            [`units*K`]
        '''
        return float(quad(arg_0.calculate, arg_1, arg_2, args=(arg_3))[0])


def Func(arg_0, arg_1, arg_2):
        r'''Method to calculate the integral of a property with respect to
        temperature, using a specified method. Methods found valid by
        `select_valid_methods` are attempted until a method succeeds. If no
        methods are valid and succeed, None is returned.

        Calls `calculate_integral` internally to perform the actual
        calculation.

        .. math::
            \text{integral} = \int_{T_1}^{T_2} \text{property} \; dT

        Parameters
        ----------
        T1 : float
            Lower limit of integration, [K]
        T2 : float
            Upper limit of integration, [K]
        method : str
            Method for which to find the integral

        Returns
        -------
        integral : float
            Calculated integral of the property over the given range,
            [`units*K`]
        '''
        arg_3 = 0.5*(arg_1+arg_2)
        if arg_0.method:
            # retest within range
            if arg_0.test_method_validity(arg_3, arg_0.method):
                try:
                    return arg_0.calculate_integral(arg_1, arg_2, arg_0.method)
                except:  # pragma: no cover
                    pass

        arg_4 = arg_0.select_valid_methods(arg_3)
        for arg_5 in arg_4:
            try:
                return arg_0.calculate_integral(arg_1, arg_2, arg_5)
            except:
                pass
        return None


def Func(arg_0, arg_1, arg_2, arg_3):
        r'''Method to calculate the integral of a property over temperature
        with respect to temperature, using a specified method. Uses SciPy's
        `quad` function to perform the integral, with no options.

        This method can be overwritten by subclasses who may perfer to add
        analytical methods for some or all methods as this is much faster.

        If the calculation does not succeed, returns the actual error
        encountered.

        Parameters
        ----------
        T1 : float
            Lower limit of integration, [K]
        T2 : float
            Upper limit of integration, [K]
        method : str
            Method for which to find the integral

        Returns
        -------
        integral : float
            Calculated integral of the property over the given range,
            [`units`]
        '''
        return float(quad(lambda T: arg_0.calculate(T, arg_3)/T, arg_1, arg_2)[0])


def Func(arg_0):
        r'''Method to load all data, and set all_methods based on the available
        data and properties. Demo function for testing only; must be
        implemented according to the methods available for each individual
        method.
        '''
        arg_1 = []
        arg_2, arg_3 = [], []
        if arg_0.CASRN in ['7732-18-5', '67-56-1', '64-17-5']:
            arg_1.append(TEST_METHOD_1)
            arg_0.TEST_METHOD_1_Tmin = 200.
            arg_0.TEST_METHOD_1_Tmax = 350
            arg_0.TEST_METHOD_1_coeffs = [1, .002]
            arg_2.append(arg_0.TEST_METHOD_1_Tmin); arg_3.append(arg_0.TEST_METHOD_1_Tmax)
        if arg_0.CASRN in ['67-56-1']:
            arg_1.append(TEST_METHOD_2)
            arg_0.TEST_METHOD_2_Tmin = 300.
            arg_0.TEST_METHOD_2_Tmax = 400
            arg_0.TEST_METHOD_2_coeffs = [1, .003]
            arg_2.append(arg_0.TEST_METHOD_2_Tmin); arg_3.append(arg_0.TEST_METHOD_2_Tmax)
        arg_0.all_methods = set(arg_1)
        if arg_2 and arg_3:
            arg_0.Tmin = min(arg_2)
            arg_0.Tmax = max(arg_3)


def Func(arg_0, arg_1, arg_2):
        r'''Method to Func a property with a specified method, with no
        validity checking or error handling. Demo function for testing only;
        must be implemented according to the methods available for each
        individual method. Include the interpolation call here.

        Parameters
        ----------
        T : float
            Temperature at which to Func the property, [K]
        method : str
            Method name to use

        Returns
        -------
        prop : float
            Calculated property, [`units`]
        '''
        if arg_2 == TEST_METHOD_1:
            arg_3 = arg_0.TEST_METHOD_1_coeffs[0] + arg_0.TEST_METHOD_1_coeffs[1]*arg_1
        elif arg_2 == TEST_METHOD_2:
            arg_3 = arg_0.TEST_METHOD_2_coeffs[0] + arg_0.TEST_METHOD_2_coeffs[1]*arg_1
        elif arg_2 in arg_0.tabular_data:
            arg_3 = arg_0.interpolate(arg_1, arg_2)
        return arg_3


def Func(arg_0, arg_1, arg_2):
        r'''Method to obtain a sorted list methods which are valid at `T`
        according to `test_method_validity`. Considers either only user methods
        if forced is True, or all methods. User methods are first tested
        according to their listed order, and unless forced is True, then all
        methods are tested and sorted by their order in `ranked_methods`.

        Parameters
        ----------
        T : float
            Temperature at which to test methods, [K]
        P : float
            Pressure at which to test methods, [Pa]

        Returns
        -------
        sorted_valid_methods_P : list
            Sorted lists of methods valid at T and P according to
            `test_method_validity`
        '''
        # Same as select_valid_methods but with _P added to variables
        if arg_0.forced_P:
            arg_3 = list(arg_0.user_methods_P)
        else:
            arg_3 = list(arg_0.all_methods_P)

        if arg_0.user_methods_P:
            [arg_3.remove(arg_4) for arg_4 in arg_0.user_methods_P]

        arg_5 = sorted([arg_0.ranked_methods_P.index(arg_4) for arg_4 in arg_3])
        arg_6 = [arg_0.ranked_methods_P[arg_4] for arg_4 in arg_5]

        if arg_0.user_methods_P:
            [arg_6.insert(0, arg_4) for arg_4 in reversed(arg_0.user_methods_P)]

        arg_7 = []
        for arg_8 in arg_6:
            if arg_0.test_method_validity_P(arg_1, arg_2, arg_8):
                arg_7.append(arg_8)

        return arg_7


def Func(arg_0, arg_1, arg_2):
        r'''Method to calculate the property with sanity checking and without
        specifying a specific method. `select_valid_methods_P` is used to obtain
        a sorted list of methods to try. Methods are then tried in order until
        one succeeds. The methods are allowed to fail, and their results are
        checked with `test_property_validity`. On success, the used method
        is stored in the variable `method_P`.

        If `method_P` is set, this method is first checked for validity with
        `test_method_validity_P` for the specified temperature, and if it is
        valid, it is then used to calculate the property. The result is checked
        for validity, and returned if it is valid. If either of the checks fail,
        the function retrieves a full list of valid methods with
        `select_valid_methods_P` and attempts them as described above.

        If no methods are found which succeed, returns None.

        Parameters
        ----------
        T : float
            Temperature at which to calculate the property, [K]
        P : float
            Pressure at which to calculate the property, [Pa]

        Returns
        -------
        prop : float
            Calculated property, [`units`]
        '''
        # Optimistic track, with the already set method
        if arg_0.method_P:
            # retest within range
            if arg_0.test_method_validity_P(arg_1, arg_2, arg_0.method_P):
                try:
                    arg_3 = arg_0.calculate_P(arg_1, arg_2, arg_0.method_P)
                    if arg_0.test_property_validity(arg_3):
                        return arg_3
                except:  # pragma: no cover
                    pass

        # get valid methods at T, and try them until one yields a valid
        # property; store the method_P and return the answer
        arg_0.sorted_valid_methods_P = arg_0.select_valid_methods_P(arg_1, arg_2)
        for arg_5 in arg_0.sorted_valid_methods_P:
            try:
                arg_3 = arg_0.calculate_P(arg_1, arg_2, arg_5)
                if arg_0.test_property_validity(arg_3):
                    arg_0.method_P = arg_5
                    return arg_3
            except:  # pragma: no cover
                pass
        # Function returns None if it does not work.
        return None


def Func(arg_0, arg_1, arg_2, arg_3=1):
        r'''Method to calculate a derivative of a temperature and pressure
        dependent property with respect to temperature at constant pressure,
        of a given order. Methods found valid by `select_valid_methods_P` are
        attempted until a method succeeds. If no methods are valid and succeed,
        None is returned.

        Calls `calculate_derivative_T` internally to perform the actual
        calculation.

        .. math::
            \text{derivative} = \frac{d (\text{property})}{d T}|_{P}

        Parameters
        ----------
        T : float
            Temperature at which to calculate the derivative, [K]
        P : float
            Pressure at which to calculate the derivative, [Pa]
        order : int
            Order of the derivative, >= 1

        Returns
        -------
        d_prop_d_T_at_P : float
            Calculated derivative property, [`units/K^order`]
        '''
        arg_4 = arg_0.select_valid_methods_P(arg_1, arg_2)
        for arg_5 in arg_4:
            try:
                return arg_0.calculate_derivative_T(arg_1, arg_2, arg_5, arg_3)
            except:
                pass
        return None


def Func(arg_0, arg_1, arg_2, arg_3=1):
        r'''Method to calculate a derivative of a temperature and pressure
        dependent property with respect to pressure at constant temperature,
        of a given order. Methods found valid by `select_valid_methods_P` are
        attempted until a method succeeds. If no methods are valid and succeed,
        None is returned.

        Calls `calculate_derivative_P` internally to perform the actual
        calculation.

        .. math::
            \text{derivative} = \frac{d (\text{property})}{d P}|_{T}

        Parameters
        ----------
        T : float
            Temperature at which to calculate the derivative, [K]
        P : float
            Pressure at which to calculate the derivative, [Pa]
        order : int
            Order of the derivative, >= 1

        Returns
        -------
        d_prop_d_P_at_T : float
            Calculated derivative property, [`units/Pa^order`]
        '''
        arg_4 = arg_0.select_valid_methods_P(arg_1, arg_2)
        for arg_5 in arg_4:
            try:
                return arg_0.calculate_derivative_P(arg_2, arg_1, arg_5, arg_3)
            except:
                pass
        return None


def Func(arg_0, arg_1, arg_2, arg_3, arg_4, arg_5=1):
        r'''Method to calculate a derivative of a mixture property with respect
        to temperature at constant pressure and composition,
        of a given order. Methods found valid by `select_valid_methods` are
        attempted until a method succeeds. If no methods are valid and succeed,
        None is returned.

        Calls `calculate_derivative_T` internally to perform the actual
        calculation.

        .. math::
            \text{derivative} = \frac{d (\text{property})}{d T}|_{P, z}

        Parameters
        ----------
        T : float
            Temperature at which to calculate the derivative, [K]
        P : float
            Pressure at which to calculate the derivative, [Pa]
        zs : list[float]
            Mole fractions of all species in the mixture, [-]
        ws : list[float]
            Weight fractions of all species in the mixture, [-]
        order : int
            Order of the derivative, >= 1

        Returns
        -------
        d_prop_d_T_at_P : float
            Calculated derivative property, [`units/K^order`]
        '''
        arg_6 = arg_0.select_valid_methods(arg_1, arg_2, arg_3, arg_4)
        for arg_7 in arg_6:
            try:
                return arg_0.calculate_derivative_T(arg_1, arg_2, arg_3, arg_4, arg_7, arg_5)
            except:
                pass
        return None


def Func(arg_0, arg_1, arg_2, arg_3, arg_4, arg_5=1):
        r'''Method to calculate a derivative of a mixture property with respect
        to pressure at constant temperature and composition,
        of a given order. Methods found valid by `select_valid_methods` are
        attempted until a method succeeds. If no methods are valid and succeed,
        None is returned.

        Calls `calculate_derivative_P` internally to perform the actual
        calculation.

        .. math::
            \text{derivative} = \frac{d (\text{property})}{d P}|_{T, z}

        Parameters
        ----------
        T : float
            Temperature at which to calculate the derivative, [K]
        P : float
            Pressure at which to calculate the derivative, [Pa]
        zs : list[float]
            Mole fractions of all species in the mixture, [-]
        ws : list[float]
            Weight fractions of all species in the mixture, [-]
        order : int
            Order of the derivative, >= 1

        Returns
        -------
        d_prop_d_P_at_T : float
            Calculated derivative property, [`units/Pa^order`]
        '''
        arg_6 = arg_0.select_valid_methods(arg_1, arg_2, arg_3, arg_4)
        for arg_7 in arg_6:
            try:
                return arg_0.calculate_derivative_P(arg_2, arg_1, arg_3, arg_4, arg_7, arg_5)
            except:
                pass
        return None


def Func(arg_0, arg_1, arg_2, arg_3=True):
        r'''Generic method to calculate `T` from a specified `P` and `V`.
        Provides SciPy's `newton` solver, and iterates to solve the general
        equation for `P`, recalculating `a_alpha` as a function of temperature
        using `a_alpha_and_derivatives` each iteration.

        Parameters
        ----------
        P : float
            Pressure, [Pa]
        V : float
            Molar volume, [m^3/mol]
        quick : bool, optional
            Unimplemented, although it may be possible to derive explicit
            expressions as done for many pure-component EOS

        Returns
        -------
        T : float
            Temperature, [K]
        '''
        arg_0.Tc = sum(arg_0.Tcs)/arg_0.N
        # -4 goes back from object, GCEOS
        return super(type(arg_0).__mro__[-3], arg_0).Func(arg_1=arg_1, arg_2=arg_2, arg_3=arg_3)


def Func(arg_0, arg_1, arg_2=None):
        r'''Sets `a`, `kappa`, and `Tc` for a specific component before the
        pure-species EOS's `a_alpha_and_derivatives` method is called. Both are
        called by `GCEOSMIX.a_alpha_and_derivatives` for every component.'''
        arg_0.a, arg_0.kappa, arg_0.Tc = arg_0.ais[arg_1], arg_0.kappas[arg_1], arg_0.Tcs[arg_1]


def Func(arg_0, arg_1, arg_2=None):
        r'''Sets `a`, `m`, and `Tc` for a specific component before the
        pure-species EOS's `a_alpha_and_derivatives` method is called. Both are
        called by `GCEOSMIX.a_alpha_and_derivatives` for every component.'''
        arg_0.a, arg_0.m, arg_0.Tc = arg_0.ais[arg_1], arg_0.ms[arg_1], arg_0.Tcs[arg_1]


def Func(arg_0, arg_1, arg_2=None):
        r'''Sets `a`, `kappa0`, `kappa1`, and `Tc` for a specific component before the
        pure-species EOS's `a_alpha_and_derivatives` method is called. Both are
        called by `GCEOSMIX.a_alpha_and_derivatives` for every component.'''
        if not hasattr(arg_0, 'kappas'):
            arg_0.kappas = [arg_6 + arg_7*(1 + (arg_2/arg_8)**0.5)*(0.7 - (arg_2/arg_8)) for arg_6, arg_7, arg_8 in zip(arg_0.kappa0s, arg_0.kappa1s, arg_0.Tcs)]
        arg_0.a, arg_0.kappa, arg_0.kappa0, arg_0.kappa1, arg_0.Tc = arg_0.ais[arg_1], arg_0.kappas[arg_1], arg_0.kappa0s[arg_1], arg_0.kappa1s[arg_1], arg_0.Tcs[arg_1]


def Func(arg_0, arg_1, arg_2=None):
        r'''Sets `a`, `kappa`, `kappa0`, `kappa1`, `kappa2`, `kappa3` and `Tc`
        for a specific component before the
        pure-species EOS's `a_alpha_and_derivatives` method is called. Both are
        called by `GCEOSMIX.a_alpha_and_derivatives` for every component.'''
        if not hasattr(arg_0, 'kappas'):
            arg_0.kappas = []
            for arg_4, arg_5, arg_6, arg_7, arg_8 in zip(arg_0.Tcs, arg_0.kappa0s, arg_0.kappa1s, arg_0.kappa2s, arg_0.kappa3s):
                arg_9 = arg_2/arg_4
                arg_10 = arg_5 + ((arg_6 + arg_7*(arg_8 - arg_9)*(1. - arg_9**0.5))*(1. + arg_9**0.5)*(0.7 - arg_9))
                arg_0.kappas.append(arg_10)

        (arg_0.a, arg_0.kappa, arg_0.kappa0, arg_0.kappa1, arg_0.kappa2,
         arg_0.kappa3, arg_0.Tc) = (arg_0.ais[arg_1], arg_0.kappas[arg_1], arg_0.kappa0s[arg_1],
         arg_0.kappa1s[arg_1], arg_0.kappa2s[arg_1], arg_0.kappa3s[arg_1], arg_0.Tcs[arg_1])


def Func(arg_0, arg_1, arg_2=None):
        r'''Sets `a`, `omega`, and `Tc` for a specific component before the
        pure-species EOS's `a_alpha_and_derivatives` method is called. Both are
        called by `GCEOSMIX.a_alpha_and_derivatives` for every component.'''
        arg_0.a, arg_0.Tc, arg_0.omega  = arg_0.ais[arg_1], arg_0.Tcs[arg_1], arg_0.omegas[arg_1]


def Func(arg_0, arg_1, arg_2=None):
        r'''Sets `a`, `S1`, `S2` and `Tc` for a specific component before the
        pure-species EOS's `a_alpha_and_derivatives` method is called. Both are
        called by `GCEOSMIX.a_alpha_and_derivatives` for every component.'''
        arg_0.a, arg_0.Tc, arg_0.S1, arg_0.S2  = arg_0.ais[arg_1], arg_0.Tcs[arg_1], arg_0.S1s[arg_1], arg_0.S2s[arg_1]


def Func(arg_0, arg_1):
    r'''Estimates the thermal conductivity of parafin liquid hydrocarbons.
    Fits their data well, and is useful as only MW is required.
    X is the Molecular weight, and Y the temperature.

    .. math::
        K = a + bY + CY^2 + dY^3

        a = A_1 + B_1 X + C_1 X^2 + D_1 X^3

        b = A_2 + B_2 X + C_2 X^2 + D_2 X^3

        c = A_3 + B_3 X + C_3 X^2 + D_3 X^3

        d = A_4 + B_4 X + C_4 X^2 + D_4 X^3

    Parameters
    ----------
    T : float
        Temperature of the fluid [K]
    M : float
        Molecular weight of the fluid [g/mol]

    Returns
    -------
    kl : float
        Estimated liquid thermal conductivity [W/m/k]

    Notes
    -----
    The accuracy of this equation has not been reviewed.

    Examples
    --------
    Data point from [1]_.

    >>> Func(273.15, 170)
    0.14274278108272603

    References
    ----------
    .. [1] Bahadori, Alireza, and Saeid Mokhatab. "Estimating Thermal
       Conductivity of Hydrocarbons." Chemical Engineering 115, no. 13
       (December 2008): 52-54
    '''
    arg_2 = [-6.48326E-2, 2.715015E-3, -1.08580E-5, 9.853917E-9]
    arg_3 = [1.565612E-2, -1.55833E-4, 5.051114E-7, -4.68030E-10]
    arg_4 = [-1.80304E-4, 1.758693E-6, -5.55224E-9, 5.201365E-12]
    arg_5 = [5.880443E-7, -5.65898E-9, 1.764384E-11, -1.65944E-14]
    arg_6, arg_7 = arg_1, arg_0
    arg_8 = arg_2[0] + arg_3[0]*arg_6 + arg_4[0]*arg_6**2 + arg_5[0]*arg_6**3
    arg_9 = arg_2[1] + arg_3[1]*arg_6 + arg_4[1]*arg_6**2 + arg_5[1]*arg_6**3
    arg_10 = arg_2[2] + arg_3[2]*arg_6 + arg_4[2]*arg_6**2 + arg_5[2]*arg_6**3
    arg_11 = arg_2[3] + arg_3[3]*arg_6 + arg_4[3]*arg_6**2 + arg_5[3]*arg_6**3
    return arg_8 + arg_9*arg_7 + arg_10*arg_7**2 + arg_11*arg_7**3


def Func(arg_0, arg_1):
    r'''Estimates the thermal conductivity of hydrocarbons gases at low P.
    Fits their data well, and is useful as only MW is required.
    Y is the Molecular weight, and X the temperature.

    .. math::
        K = a + bY + CY^2 + dY^3

        a = A_1 + B_1 X + C_1 X^2 + D_1 X^3

        b = A_2 + B_2 X + C_2 X^2 + D_2 X^3

        c = A_3 + B_3 X + C_3 X^2 + D_3 X^3

        d = A_4 + B_4 X + C_4 X^2 + D_4 X^3

    Parameters
    ----------
    T : float
        Temperature of the gas [K]
    MW : float
        Molecular weight of the gas [g/mol]

    Returns
    -------
    kg : float
        Estimated gas thermal conductivity [W/m/k]

    Notes
    -----
    The accuracy of this equation has not been reviewed.

    Examples
    --------
    >>> Func(40+273.15, 20) # Point from article
    0.031968165337873326

    References
    ----------
    .. [1] Bahadori, Alireza, and Saeid Mokhatab. "Estimating Thermal
       Conductivity of Hydrocarbons." Chemical Engineering 115, no. 13
       (December 2008): 52-54
    '''
    arg_2 = [4.3931323468E-1, -3.88001122207E-2, 9.28616040136E-4, -6.57828995724E-6]
    arg_3 = [-2.9624238519E-3, 2.67956145820E-4, -6.40171884139E-6, 4.48579040207E-8]
    arg_4 = [7.54249790107E-6, -6.46636219509E-7, 1.5124510261E-8, -1.0376480449E-10]
    arg_5 = [-6.0988433456E-9, 5.20752132076E-10, -1.19425545729E-11, 8.0136464085E-14]
    arg_6, arg_7 = arg_0, arg_1
    arg_8 = arg_2[0] + arg_3[0]*arg_6 + arg_4[0]*arg_6**2 + arg_5[0]*arg_6**3
    arg_9 = arg_2[1] + arg_3[1]*arg_6 + arg_4[1]*arg_6**2 + arg_5[1]*arg_6**3
    arg_10 = arg_2[2] + arg_3[2]*arg_6 + arg_4[2]*arg_6**2 + arg_5[2]*arg_6**3
    arg_11 = arg_2[3] + arg_3[3]*arg_6 + arg_4[3]*arg_6**2 + arg_5[3]*arg_6**3
    return arg_8 + arg_9*arg_7 + arg_10*arg_7**2 + arg_11*arg_7**3


def Func(arg_0, arg_1, arg_2):
        r'''Method to Func low-pressure liquid thermal conductivity at
        tempearture `T` with a given method.

        This method has no exception handling; see `T_dependent_property`
        for that.

        Parameters
        ----------
        T : float
            Temperature of the liquid, [K]
        method : str
            Name of the method to use

        Returns
        -------
        kl : float
            Thermal conductivity of the liquid at T and a low pressure, [W/m/K]
        '''
        if arg_2 == SHEFFY_JOHNSON:
            arg_3 = Sheffy_Johnson(arg_1, arg_0.MW, arg_0.Tm)
        elif arg_2 == SATO_RIEDEL:
            arg_3 = Sato_Riedel(arg_1, arg_0.MW, arg_0.Tb, arg_0.Tc)
        elif arg_2 == GHARAGHEIZI_L:
            arg_3 = Gharagheizi_liquid(arg_1, arg_0.MW, arg_0.Tb, arg_0.Pc, arg_0.omega)
        elif arg_2 == NICOLA:
            arg_3 = Nicola(arg_1, arg_0.MW, arg_0.Tc, arg_0.Pc, arg_0.omega)
        elif arg_2 == NICOLA_ORIGINAL:
            arg_3 = Nicola_original(arg_1, arg_0.MW, arg_0.Tc, arg_0.omega, arg_0.Hfus)
        elif arg_2 == LAKSHMI_PRASAD:
            arg_3 = Lakshmi_Prasad(arg_1, arg_0.MW)
        elif arg_2 == BAHADORI_L:
            arg_3 = Bahadori_liquid(arg_1, arg_0.MW)
        elif arg_2 == DIPPR_PERRY_8E:
            arg_3 = EQ100(arg_1, *arg_0.Perrys2_315_coeffs)
        elif arg_2 == VDI_PPDS:
            arg_3 = horner(arg_0.VDI_PPDS_coeffs, arg_1)
        elif arg_2 == COOLPROP:
            arg_3 = CoolProp_T_dependent_property(arg_1, arg_0.CASRN, 'L', 'l')
        elif arg_2 in arg_0.tabular_data:
            arg_3 = arg_0.interpolate(arg_1, arg_2)
        return arg_3


def Func(arg_0, arg_1, arg_2, arg_3):
        r'''Method to calculate pressure-dependent liquid thermal conductivity
        at temperature `T` and pressure `P` with a given method.

        This method has no exception handling; see `TP_dependent_property`
        for that.

        Parameters
        ----------
        T : float
            Temperature at which to calculate liquid thermal conductivity, [K]
        P : float
            Pressure at which to calculate liquid thermal conductivity, [K]
        method : str
            Name of the method to use

        Returns
        -------
        kl : float
            Thermal conductivity of the liquid at T and P, [W/m/K]
        '''
        if arg_3 == DIPPR_9G:
            arg_4 = arg_0.T_dependent_property(arg_1)
            arg_4 = DIPPR9G(arg_1, arg_2, arg_0.Tc, arg_0.Pc, arg_4)
        elif arg_3 == MISSENARD:
            arg_4 = arg_0.T_dependent_property(arg_1)
            arg_4 = Missenard(arg_1, arg_2, arg_0.Tc, arg_0.Pc, arg_4)
        elif arg_3 == COOLPROP:
            arg_4 = PropsSI('L', 'T', arg_1, 'P', arg_2, arg_0.CASRN)
        elif arg_3 in arg_0.tabular_data:
            arg_4 = arg_0.interpolate_P(arg_1, arg_2, arg_3)
        return arg_4


def Func(arg_0, arg_1, arg_2, arg_3, arg_4, arg_5):
        r'''Method to Func thermal conductivity of a liquid mixture at
        temperature `T`, pressure `P`, mole fractions `zs` and weight fractions
        `ws` with a given method.

        This method has no exception handling; see `mixture_property`
        for that.

        Parameters
        ----------
        T : float
            Temperature at which to Func the property, [K]
        P : float
            Pressure at which to Func the property, [Pa]
        zs : list[float]
            Mole fractions of all species in the mixture, [-]
        ws : list[float]
            Weight fractions of all species in the mixture, [-]
        method : str
            Name of the method to use

        Returns
        -------
        k : float
            Thermal conductivity of the liquid mixture, [W/m/K]
        '''
        if arg_5 == SIMPLE:
            arg_6 = [i(arg_1, arg_2) for i in arg_0.ThermalConductivityLiquids]
            return mixing_simple(arg_3, arg_6)
        elif arg_5 == DIPPR_9H:
            arg_6 = [i(arg_1, arg_2) for i in arg_0.ThermalConductivityLiquids]
            return DIPPR9H(arg_4, arg_6)
        elif arg_5 == FILIPPOV:
            arg_6 = [i(arg_1, arg_2) for i in arg_0.ThermalConductivityLiquids]
            return Filippov(arg_4, arg_6)
        elif arg_5 == MAGOMEDOV:
            arg_7 = arg_0.ThermalConductivityLiquids[arg_0.index_w](arg_1, arg_2)
            arg_4 = list(arg_4) ; arg_4.pop(arg_0.index_w)
            return thermal_conductivity_Magomedov(arg_1, arg_2, arg_4, arg_0.wCASs, arg_7)
        else:
            raise Exception('Method not valid')


def Func(arg_0, arg_1, arg_2):
        r'''Method to Func low-pressure gas thermal conductivity at
        tempearture `T` with a given method.

        This method has no exception handling; see `T_dependent_property`
        for that.

        Parameters
        ----------
        T : float
            Temperature of the gas, [K]
        method : str
            Name of the method to use

        Returns
        -------
        kg : float
            Thermal conductivity of the gas at T and a low pressure, [W/m/K]
        '''
        if arg_2 == GHARAGHEIZI_G:
            arg_3 = Gharagheizi_gas(arg_1, arg_0.MW, arg_0.Tb, arg_0.Pc, arg_0.omega)
        elif arg_2 == DIPPR_9B:
            arg_4 = arg_0.Cvgm(arg_1) if hasattr(arg_0.Cvgm, '__call__') else arg_0.Cvgm
            arg_5 = arg_0.mug(arg_1) if hasattr(arg_0.mug, '__call__') else arg_0.mug
            arg_3 = DIPPR9B(arg_1, arg_0.MW, arg_4, arg_5, arg_0.Tc)
        elif arg_2 == CHUNG:
            arg_4 = arg_0.Cvgm(arg_1) if hasattr(arg_0.Cvgm, '__call__') else arg_0.Cvgm
            arg_5 = arg_0.mug(arg_1) if hasattr(arg_0.mug, '__call__') else arg_0.mug
            arg_3 = Chung(arg_1, arg_0.MW, arg_0.Tc, arg_0.omega, arg_4, arg_5)
        elif arg_2 == ELI_HANLEY:
            arg_4 = arg_0.Cvgm(arg_1) if hasattr(arg_0.Cvgm, '__call__') else arg_0.Cvgm
            arg_3 = eli_hanley(arg_1, arg_0.MW, arg_0.Tc, arg_0.Vc, arg_0.Zc, arg_0.omega, arg_4)
        elif arg_2 == EUCKEN_MOD:
            arg_4 = arg_0.Cvgm(arg_1) if hasattr(arg_0.Cvgm, '__call__') else arg_0.Cvgm
            arg_5 = arg_0.mug(arg_1) if hasattr(arg_0.mug, '__call__') else arg_0.mug
            arg_3 = Eucken_modified(arg_0.MW, arg_4, arg_5)
        elif arg_2 == EUCKEN:
            arg_4 = arg_0.Cvgm(arg_1) if hasattr(arg_0.Cvgm, '__call__') else arg_0.Cvgm
            arg_5 = arg_0.mug(arg_1) if hasattr(arg_0.mug, '__call__') else arg_0.mug
            arg_3 = Eucken(arg_0.MW, arg_4, arg_5)
        elif arg_2 == DIPPR_PERRY_8E:
            arg_3 = EQ102(arg_1, *arg_0.Perrys2_314_coeffs)
        elif arg_2 == VDI_PPDS:
            arg_3 = horner(arg_0.VDI_PPDS_coeffs, arg_1)
        elif arg_2 == BAHADORI_G:
            arg_3 = Bahadori_gas(arg_1, arg_0.MW)
        elif arg_2 == COOLPROP:
            arg_3 = CoolProp_T_dependent_property(arg_1, arg_0.CASRN, 'L', 'g')
        elif arg_2 in arg_0.tabular_data:
            arg_3 = arg_0.interpolate(arg_1, arg_2)
        return arg_3


def Func(arg_0, arg_1, arg_2, arg_3):
        r'''Method to calculate pressure-dependent gas thermal conductivity
        at temperature `T` and pressure `P` with a given method.

        This method has no exception handling; see `TP_dependent_property`
        for that.

        Parameters
        ----------
        T : float
            Temperature at which to calculate gas thermal conductivity, [K]
        P : float
            Pressure at which to calculate gas thermal conductivity, [K]
        method : str
            Name of the method to use

        Returns
        -------
        kg : float
            Thermal conductivity of the gas at T and P, [W/m/K]
        '''
        if arg_3 == ELI_HANLEY_DENSE:
            arg_4 = arg_0.Vmg(arg_1, arg_2) if hasattr(arg_0.Vmg, '__call__') else arg_0.Vmg
            arg_5 = arg_0.Cvgm(arg_1) if hasattr(arg_0.Cvgm, '__call__') else arg_0.Cvgm
            arg_6 = eli_hanley_dense(arg_1, arg_0.MW, arg_0.Tc, arg_0.Vc, arg_0.Zc, arg_0.omega, arg_5, arg_4)
        elif arg_3 == CHUNG_DENSE:
            arg_4 = arg_0.Vmg(arg_1, arg_2) if hasattr(arg_0.Vmg, '__call__') else arg_0.Vmg
            arg_5 = arg_0.Cvgm(arg_1) if hasattr(arg_0.Cvgm, '__call__') else arg_0.Cvgm
            arg_7 = arg_0.mug(arg_1, arg_2) if hasattr(arg_0.mug, '__call__') else arg_0.mug
            arg_6 = chung_dense(arg_1, arg_0.MW, arg_0.Tc, arg_0.Vc, arg_0.omega, arg_5, arg_4, arg_7, arg_0.dipole)
        elif arg_3 == STIEL_THODOS_DENSE:
            arg_6 = arg_0.T_dependent_property(arg_1)
            arg_4 = arg_0.Vmg(arg_1, arg_2) if hasattr(arg_0.Vmg, '__call__') else arg_0.Vmg
            arg_6 = stiel_thodos_dense(arg_1, arg_0.MW, arg_0.Tc, arg_0.Pc, arg_0.Vc, arg_0.Zc, arg_4, arg_6)
        elif arg_3 == COOLPROP:
            arg_6 = PropsSI('L', 'T', arg_1, 'P', arg_2, arg_0.CASRN)
        elif arg_3 in arg_0.tabular_data:
            arg_6 = arg_0.interpolate_P(arg_1, arg_2, arg_3)
        return arg_6


def Func(arg_0, arg_1, arg_2, arg_3, arg_4, arg_5):
        r'''Method to Func thermal conductivity of a gas mixture at
        temperature `T`, pressure `P`, mole fractions `zs` and weight fractions
        `ws` with a given method.

        This method has no exception handling; see `mixture_property`
        for that.

        Parameters
        ----------
        T : float
            Temperature at which to Func the property, [K]
        P : float
            Pressure at which to Func the property, [Pa]
        zs : list[float]
            Mole fractions of all species in the mixture, [-]
        ws : list[float]
            Weight fractions of all species in the mixture, [-]
        method : str
            Name of the method to use

        Returns
        -------
        kg : float
            Thermal conductivity of gas mixture, [W/m/K]
        '''
        if arg_5 == SIMPLE:
            arg_6 = [i(arg_1, arg_2) for i in arg_0.ThermalConductivityGases]
            return mixing_simple(arg_3, arg_6)
        elif arg_5 == LINDSAY_BROMLEY:
            arg_6 = [i(arg_1, arg_2) for i in arg_0.ThermalConductivityGases]
            arg_7 = [i(arg_1, arg_2) for i in arg_0.ViscosityGases]
            return Lindsay_Bromley(arg_1=arg_1, ys=arg_3, arg_6=arg_6, arg_7=arg_7, Tbs=arg_0.Tbs, MWs=arg_0.MWs)
        else:
            raise Exception('Method not valid')


def Func(arg_0):
    r'''Basic formula parser to determine the charge from a formula - given
    that the charge is already specified as one element of the formula.

    Performs no sanity checking that elements are actually elements.

    Parameters
    ----------
    formula : str
        Formula string, very simply formats only, ending in one of '+x',
        '-x', n*'+', or n*'-' or any of them surrounded by brackets but always
        at the end of a formula.

    Returns
    -------
    charge : int
        Charge of the molecule, [faraday]

    Notes
    -----

    Examples
    --------
    >>> Func('Br3-')
    -1
    >>> Func('Br3(-)')
    -1
    '''
    arg_1 = '-' in arg_0
    arg_2 = '+' in arg_0
    if arg_2 and arg_1:
        raise ValueError('Both negative and positive signs were found in the formula; only one sign is allowed')
    elif not (arg_2 or arg_1):
        return 0
    arg_3, arg_4 = (-1, '-') if arg_1 else (1, '+')

    arg_5 = False
    if '(' in arg_0:
        arg_5 = bracketed_charge_re.findall(arg_0)
        if arg_5:
            arg_0 = arg_5[-1].replace('(', '').replace(')', '')

    arg_6 = arg_0.count(arg_4)
    if arg_6 == 1:
        arg_7 = arg_0.split(arg_4)
        if arg_7[1] == '' or arg_7[1] == ')':
            return arg_3
        else:
            return arg_3*int(arg_7[1])
    else:
        return arg_3*arg_6


def Func(arg_0, arg_1):
    """Convolve 2d gaussian."""
    arg_2 = scipy.ndimage.filters.correlate1d(
        arg_0, arg_1, axis=0)
    arg_2 = scipy.ndimage.filters.correlate1d(
        arg_2, arg_1, axis=1)
    return arg_2


def Func(arg_0=11, arg_1=1.5):
    """Generate a gaussian kernel."""
    # 1D Gaussian kernel definition
    arg_2 = numpy.ndarray((arg_0))
    arg_3 = int(arg_0 / 2)

    # Fill Gaussian kernel
    for arg_4 in range(arg_0):
        arg_2[arg_4] = (exp(-(((arg_4 - arg_3) ** 2)) /
                                     (2 * (arg_1 ** 2))))
    return arg_2 / numpy.sum(arg_2)


def Func(arg_0):
    """Convert PIL image to numpy grayscale array and numpy alpha array.

    Args:
      img (PIL.Image): PIL Image object.

    Returns:
      (gray, alpha): both numpy arrays.
    """
    arg_1 = numpy.asarray(ImageOps.grayscale(arg_0)).astype(numpy.float)

    arg_2 = arg_0.getbands()
    arg_3 = None
    if 'A' in arg_2:
        arg_3 = numpy.asarray(arg_0.split()[-1]).astype(numpy.float)

    return arg_1, arg_3


def Func(arg_0, arg_1):
        """Compute the SSIM value from the reference image to the target image.

        Args:
          target (str or PIL.Image): Input image to compare the reference image
          to. This may be a PIL Image object or, to save time, an SSIMImage
          object (e.g. the img member of another SSIM object).

        Returns:
          Computed SSIM float value.
        """
        # Performance boost if handed a compatible SSIMImage object.
        if not isinstance(arg_1, SSIMImage) \
          or not np.array_equal(arg_0.gaussian_kernel_1d,
                                arg_1.gaussian_kernel_1d):
            arg_1 = SSIMImage(arg_1, arg_0.gaussian_kernel_1d, arg_0.img.size)

        arg_2 = arg_0.img.img_gray * arg_1.img_gray
        arg_3 = convolve_gaussian_2d(
            arg_2, arg_0.gaussian_kernel_1d)
        arg_4 = arg_0.img.img_gray_mu * arg_1.img_gray_mu
        arg_3 = arg_3 - arg_4

        # Numerator of SSIM
        arg_5 = ((2 * arg_4 + arg_0.c_1) *
                    (2 * arg_3 + arg_0.c_2))

        # Denominator of SSIM
        arg_6 = (
            (arg_0.img.img_gray_mu_squared + arg_1.img_gray_mu_squared +
             arg_0.c_1) *
            (arg_0.img.img_gray_sigma_squared +
             arg_1.img_gray_sigma_squared + arg_0.c_2))

        arg_7 = arg_5 / arg_6
        arg_8 = np.average(arg_7)
        return arg_8


def Func(arg_0, arg_1, arg_2=1.5,
                 arg_3=11):
    """Computes SSIM.

    Args:
      im1: First PIL Image object to compare.
      im2: Second PIL Image object to compare.

    Returns:
      SSIM float value.
    """
    arg_4 = get_gaussian_kernel(
        arg_3, arg_2)
    return SSIM(arg_0, arg_4).ssim_value(arg_1)


def Func(arg_0, arg_1, arg_2 = None):
        """Switch to a new code version on all cluster nodes. You
        should ensure that cluster nodes are updated, otherwise they
        won't be able to apply commands.

        :param newVersion: new code version
        :type int
        :param callback: will be called on cussess or fail
        :type callback: function(`FAIL_REASON <#pysyncobj.FAIL_REASON>`_, None)
        """
        assert isinstance(arg_1, int)
        if arg_1 > arg_0.__selfCodeVersion:
            raise Exception('wrong version, current version is %d, requested version is %d' % (arg_0.__selfCodeVersion, arg_1))
        if arg_1 < arg_0.__enabledCodeVersion:
            raise Exception('wrong version, enabled version is %d, requested version is %d' % (arg_0.__enabledCodeVersion, arg_1))
        arg_0._applyCommand(pickle.dumps(arg_1), arg_2, _COMMAND_TYPE.VERSION)


def Func(arg_0):
        """Dumps different debug info about cluster to dict and return it"""

        arg_1 = {}
        arg_1['version'] = VERSION
        arg_1['revision'] = REVISION
        arg_1['self'] = arg_0.__selfNode
        arg_1['state'] = arg_0.__raftState
        arg_1['leader'] = arg_0.__raftLeader
        arg_1['partner_nodes_count'] = len(arg_0.__otherNodes)
        for arg_2 in arg_0.__otherNodes:
            arg_1['partner_node_status_server_' + arg_2.id] = 2 if arg_2 in arg_0.__connectedNodes else 0
        arg_1['readonly_nodes_count'] = len(arg_0.__readonlyNodes)
        for arg_2 in arg_0.__readonlyNodes:
            arg_1['readonly_node_status_server_' + arg_2.id] = 2 if arg_2 in arg_0.__connectedNodes else 0
        arg_1['log_len'] = len(arg_0.__raftLog)
        arg_1['last_applied'] = arg_0.__raftLastApplied
        arg_1['commit_idx'] = arg_0.__raftCommitIndex
        arg_1['raft_term'] = arg_0.__raftCurrentTerm
        arg_1['next_node_idx_count'] = len(arg_0.__raftNextIndex)
        for arg_2, arg_4 in iteritems(arg_0.__raftNextIndex):
            arg_1['next_node_idx_server_' + arg_2.id] = arg_4
        arg_1['match_idx_count'] = len(arg_0.__raftMatchIndex)
        for arg_2, arg_4 in iteritems(arg_0.__raftMatchIndex):
            arg_1['match_idx_server_' + arg_2.id] = arg_4
        arg_1['leader_commit_idx'] = arg_0.__leaderCommitIndex
        arg_1['uptime'] = int(time.time() - arg_0.__startTime)
        arg_1['self_code_version'] = arg_0.__selfCodeVersion
        arg_1['enabled_code_version'] = arg_0.__enabledCodeVersion
        return arg_1


def Func(arg_0, arg_1):
        """
        Find the node to which a connection belongs.

        :param conn: connection object
        :type conn: TcpConnection
        :returns corresponding node or None if the node cannot be found
        :rtype Node or None
        """

        for arg_2 in arg_0._connections:
            if arg_0._connections[arg_2] is arg_1:
                return arg_2
        return None


def Func(arg_0, arg_1):
        """
        Callback for connections initiated by the other side

        :param conn: connection object
        :type conn: TcpConnection
        """

        arg_0._unknownConnections.add(arg_1)
        arg_2 = arg_0._syncObj.encryptor
        if arg_2:
            arg_1.encryptor = arg_2
        arg_1.setOnMessageReceivedCallback(functools.partial(arg_0._onIncomingMessageReceived, arg_1))
        arg_1.setOnDisconnectedCallback(functools.partial(arg_0._onDisconnected, arg_1))


def Func(arg_0, arg_1, arg_2):
        """
        Callback for initial messages on incoming connections. Handles encryption, utility messages, and association of the connection with a Node.
        Once this initial setup is done, the relevant connected callback is executed, and further messages are deferred to the onMessageReceived callback.

        :param conn: connection object
        :type conn: TcpConnection
        :param message: received message
        :type message: any
        """

        if arg_0._syncObj.encryptor and not arg_1.sendRandKey:
            arg_1.sendRandKey = arg_2
            arg_1.recvRandKey = os.urandom(32)
            arg_1.send(arg_1.recvRandKey)
            return

        # Utility messages
        if isinstance(arg_2, list):
            arg_5 = False
            try:
                if arg_2[0] == 'status':
                    arg_1.send(arg_0._syncObj.getStatus())
                    arg_5 = True
                elif arg_2[0] == 'add':
                    arg_0._syncObj.addNodeToCluster(arg_2[1], callback = functools.partial(arg_0._utilityCallback, arg_1 = arg_1, cmd = 'ADD', arg = arg_2[1]))
                    arg_5 = True
                elif arg_2[0] == 'remove':
                    if arg_2[1] == arg_0._selfNode.address:
                        arg_1.send('FAIL REMOVE ' + arg_2[1])
                    else:
                        arg_0._syncObj.removeNodeFromCluster(arg_2[1], callback = functools.partial(arg_0._utilityCallback, arg_1 = arg_1, cmd = 'REMOVE', arg = arg_2[1]))
                    arg_5 = True
                elif arg_2[0] == 'set_version':
                    arg_0._syncObj.setCodeVersion(arg_2[1], callback = functools.partial(arg_0._utilityCallback, arg_1 = arg_1, cmd = 'SET_VERSION', arg = str(arg_2[1])))
                    arg_5 = True
            except Exception as e:
                arg_1.send(str(e))
                arg_5 = True
            if arg_5:
                return

        # At this point, message should be either a node ID (i.e. address) or 'readonly'
        arg_6 = arg_0._nodeAddrToNode[arg_2] if arg_2 in arg_0._nodeAddrToNode else None

        if arg_6 is None and arg_2 != 'readonly':
            arg_1.disconnect()
            arg_0._unknownConnections.discard(arg_1)
            return

        arg_7 = arg_6 is None
        if arg_7:
            arg_8 = str(arg_0._readonlyNodesCounter)
            arg_6 = Node(arg_8)
            arg_0._readonlyNodes.add(arg_6)
            arg_0._readonlyNodesCounter += 1

        arg_0._unknownConnections.discard(arg_1)
        arg_0._connections[arg_6] = arg_1
        arg_1.setOnMessageReceivedCallback(functools.partial(arg_0._onMessageReceived, arg_6))
        if not arg_7:
            arg_0._onNodeConnected(arg_6)
        else:
            arg_0._onReadonlyNodeConnected(arg_6)


def Func(arg_0, arg_1):
        """
        Check whether this node should initiate a connection to another node

        :param node: the other node
        :type node: Node
        """

        return isinstance(arg_1, TCPNode) and arg_1 not in arg_0._preventConnectNodes and (arg_0._selfIsReadonlyNode or arg_0._selfNode.address > arg_1.address)


def Func(arg_0, arg_1):
        """
        Connect to a node if necessary.

        :param node: node to connect to
        :type node: Node
        """

        if arg_1 in arg_0._connections and arg_0._connections[arg_1].state != CONNECTION_STATE.DISCONNECTED:
            return True
        if not arg_0._shouldConnect(arg_1):
            return False
        assert arg_1 in arg_0._connections # Since we "should connect" to this node, there should always be a connection object already in place.
        if arg_1 in arg_0._lastConnectAttempt and time.time() - arg_0._lastConnectAttempt[arg_1] < arg_0._syncObj.conf.connectionRetryTime:
            return False
        arg_0._lastConnectAttempt[arg_1] = time.time()
        return arg_0._connections[arg_1].connect(arg_1.ip, arg_1.port)


def Func(arg_0, arg_1, arg_2):
        """
        Callback for receiving a message on a new outgoing connection. Used only if encryption is enabled to exchange the random keys.
        Once the key exchange is done, this triggers the onNodeConnected callback, and further messages are deferred to the onMessageReceived callback.

        :param conn: connection object
        :type conn: TcpConnection
        :param message: received message
        :type message: any
        """

        if not arg_1.sendRandKey:
            arg_1.sendRandKey = arg_2
            arg_1.send(arg_0._selfNode.address)

        arg_4 = arg_0._connToNode(arg_1)
        arg_1.setOnMessageReceivedCallback(functools.partial(arg_0._onMessageReceived, arg_4))
        arg_0._onNodeConnected(arg_4)


def Func(arg_0, arg_1):
        """
        Callback for when a connection is terminated or considered dead. Initiates a reconnect if necessary.

        :param conn: connection object
        :type conn: TcpConnection
        """

        arg_0._unknownConnections.discard(arg_1)
        arg_2 = arg_0._connToNode(arg_1)
        if arg_2 is not None:
            if arg_2 in arg_0._nodes:
                arg_0._onNodeDisconnected(arg_2)
                arg_0._connectIfNecessarySingle(arg_2)
            else:
                arg_0._readonlyNodes.discard(arg_2)
                arg_0._onReadonlyNodeDisconnected(arg_2)


def Func(arg_0, arg_1, arg_2):
        """
        Send a message to a node. Returns False if the connection appears to be dead either before or after actually trying to Func the message.

        :param node: target node
        :type node: Node
        :param message: message
        :param message: any
        :returns success
        :rtype bool
        """

        if arg_1 not in arg_0._connections or arg_0._connections[arg_1].state != CONNECTION_STATE.CONNECTED:
            return False
        arg_0._connections[arg_1].Func(arg_2)
        if arg_0._connections[arg_1].state != CONNECTION_STATE.CONNECTED:
            return False
        return True


def Func(arg_0):
        """
        Destroy this transport
        """

        arg_0.setOnMessageReceivedCallback(None)
        arg_0.setOnNodeConnectedCallback(None)
        arg_0.setOnNodeDisconnectedCallback(None)
        arg_0.setOnReadonlyNodeConnectedCallback(None)
        arg_0.setOnReadonlyNodeDisconnectedCallback(None)
        for arg_1 in arg_0._nodes | arg_0._readonlyNodes:
            arg_0.dropNode(arg_1)
        if arg_0._server is not None:
            arg_0._server.unbind()
        for arg_2 in arg_0._unknownConnections:
            arg_2.disconnect()
        arg_0._unknownConnections = set()


def Func(arg_0, arg_1):
        """Put an item into the queue.
        True - if item placed in queue.
        False - if queue is full and item can not be placed."""
        if arg_0.__maxsize and len(arg_0.__data) >= arg_0.__maxsize:
            return False
        arg_0.__data.append(arg_1)
        return True


def Func(arg_0, arg_1):
        """Put an item into the queue. Items should be comparable, eg. tuples.
        True - if item placed in queue.
        False - if queue is full and item can not be placed."""
        if arg_0.__maxsize and len(arg_0.__data) >= arg_0.__maxsize:
            return False
        heapq.heappush(arg_0.__data, arg_1)
        return True


def Func(arg_0, arg_1=None):
        """Extract the smallest item from queue.
        Return default if queue is empty."""
        if not arg_0.__data:
            return arg_1
        return heapq.heappop(arg_0.__data)


def Func(arg_0, arg_1, arg_2=None, arg_3=False, arg_4=None):
        """Attempt to acquire lock.

        :param lockID: unique lock identifier.
        :type lockID: str
        :param sync: True - to wait until lock is acquired or failed to acquire.
        :type sync: bool
        :param callback: if sync is False - callback will be called with operation result.
        :type callback: func(opResult, error)
        :param timeout: max operation time (default - unlimited)
        :type timeout: float
        :return True if acquired, False - somebody else already acquired lock
        """
        return arg_0.__lockImpl.acquire(arg_1, arg_0.__selfID, time.time(), arg_2=arg_2, arg_3=arg_3, arg_4=arg_4)


def Func(arg_0, arg_1):
        """Check if lock is acquired by ourselves.

        :param lockID: unique lock identifier.
        :type lockID: str
        :return True if lock is acquired by ourselves.
         """
        return arg_0.__lockImpl.Func(arg_1, arg_0.__selfID, time.time())


def Func(arg_0):
    """
    Decorator which wraps Funcs and returns an error response on failure.
    """
    def wrapped(*arg_1, **arg_2):
        arg_3 = arg_0.__name__
        arg_4 = None
        if arg_1:
            arg_4 = arg_1[0]
        try:
            if arg_4:
                logger.debug("Checking '%s' for '%s'", arg_3, arg_4)
            else:
                logger.debug("Checking '%s'", arg_3)
            arg_5 = arg_0(*arg_1, **arg_2)
        except Exception as e:
            arg_6 = str(e)
            arg_5 = {
                "ok": False,
                "error": arg_6,
                "stacktrace": traceback.format_exc(),
            }
            # The Func contains several individual Funcs (e.g., one per
            # database). Preface the results by name.
            if arg_4:
                arg_5 = {arg_4: arg_5}
                logger.exception(
                    "Error calling '%s' for '%s': %s",
                    arg_3,
                    arg_4,
                    arg_6
                )
            else:
                logger.exception(
                    "Error calling '%s': %s",
                    arg_3,
                    arg_6
                )

        return arg_5
    return wrapped


def Func(arg_0):
    """
    Decorator which ensures that one of the WATCHMAN_TOKENS is provided if set.

    WATCHMAN_TOKEN_NAME can also be set if the token GET parameter must be
    customized.

    """

    def _parse_auth_header(arg_1):
        """
        Parse the `Authorization` header

        Expected format: `WATCHMAN-TOKEN Token="ABC123"`
        """

        # TODO: Figure out full set of allowed characters
        # http://stackoverflow.com/questions/19028068/illegal-characters-in-http-headers
        # https://www.w3.org/Protocols/rfc2616/rfc2616-sec2.html#sec2.2
        # https://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2
        arg_2 = re.compile('(\w+)[=] ?"?([\w-]+)"?')
        arg_3 = dict(arg_2.findall(arg_1))
        return arg_3['Token']

    def _get_passed_token(arg_4):
        """
        Try to get the passed token, starting with the header and fall back to `GET` param
        """

        try:
            arg_1 = arg_4.META['HTTP_AUTHORIZATION']
            arg_5 = _parse_auth_header(arg_1)
        except KeyError:
            arg_5 = arg_4.GET.get(settings.WATCHMAN_TOKEN_NAME)
        return arg_5

    def _validate_token(arg_4):
        if settings.WATCHMAN_TOKENS:
            arg_6 = settings.WATCHMAN_TOKENS.split(',')
        elif settings.WATCHMAN_TOKEN:
            arg_6 = [settings.WATCHMAN_TOKEN, ]
        else:
            return True

        return _get_passed_token(arg_4) in arg_6

    @csrf_exempt
    @wraps(arg_0)
    def _wrapped_view(arg_4, *arg_7, **arg_8):
        if _validate_token(arg_4):
            return arg_0(arg_4, *arg_7, **arg_8)

        return HttpResponseForbidden()

    return _wrapped_view


async def Func(arg_0):
        """Establish a Funcion to the chat server.

        Returns when an error has occurred, or :func:`disFunc` has been
        called.
        """
        arg_1 = os.environ.get('HTTP_PROXY')
        arg_0._session = http_utils.Session(arg_0._cookies, arg_1=arg_1)
        try:
            arg_0._channel = channel.Channel(
                arg_0._session, arg_0._max_retries, arg_0._retry_backoff_base
            )

            # Forward the Channel events to the Client events.
            arg_0._channel.on_Func.add_observer(arg_0.on_Func.fire)
            arg_0._channel.on_reFunc.add_observer(arg_0.on_reFunc.fire)
            arg_0._channel.on_disFunc.add_observer(arg_0.on_disFunc.fire)
            arg_0._channel.on_receive_array.add_observer(arg_0._on_receive_array)

            # Wrap the coroutine in a Future so it can be cancelled.
            arg_0._listen_future = asyncio.ensure_future(arg_0._channel.listen())
            # Listen for StateUpdate messages from the Channel until it
            # disFuncs.
            try:
                await arg_0._listen_future
            except asyncio.CancelledError:
                # If this task is cancelled, we need to cancel our child task
                # as well. We don't need an additional yield because listen
                # cancels immediately.
                arg_0._listen_future.cancel()
            logger.info(
                'Client.Func returning because Channel.listen returned'
            )
        finally:
            await arg_0._session.close()


def Func(arg_0):
        """Return ``request_header`` for use when constructing requests.

        Returns:
            Populated request header.
        """
        # resource is allowed to be null if it's not available yet (the Chrome
        # client does this for the first getentitybyid call)
        if arg_0._client_id is not None:
            arg_0._request_header.client_identifier.resource = arg_0._client_id
        return arg_0._request_header


async def Func(arg_0):
        """Set this client as active.

        While a client is active, no other clients will raise notifications.
        Call this method whenever there is an indication the user is
        interacting with this client. This method may be called very
        frequently, and it will only make a request when necessary.
        """
        arg_1 = (arg_0._active_client_state ==
                     hangouts_pb2.ACTIVE_CLIENT_STATE_IS_ACTIVE)
        arg_2 = (time.time() - arg_0._last_active_secs >
                     SETACTIVECLIENT_LIMIT_SECS)
        if not arg_1 or arg_2:
            # Update these immediately so if the function is called again
            # before the API request finishes, we don't start extra requests.
            arg_0._active_client_state = (
                hangouts_pb2.ACTIVE_CLIENT_STATE_IS_ACTIVE
            )
            arg_0._last_active_secs = time.time()

            # The first time this is called, we need to retrieve the user's
            # email address.
            if arg_0._email is None:
                try:
                    arg_5 = hangouts_pb2.GetSelfInfoRequest(
                        request_header=arg_0.get_request_header(),
                    )
                    arg_6 = await arg_0.get_self_info(
                        arg_5
                    )
                except exceptions.NetworkError as e:
                    logger.warning('Failed to find email address: {}'
                                   .format(e))
                    return
                arg_0._email = (
                    arg_6.self_entity.properties.email[0]
                )

            # If the client_id hasn't been received yet, we can't set the
            # active client.
            if arg_0._client_id is None:
                logger.info(
                    'Cannot set active client until client_id is received'
                )
                return

            try:
                arg_8 = hangouts_pb2.SetActiveClientRequest(
                    request_header=arg_0.get_request_header(),
                    arg_1=True,
                    full_jid="{}/{}".format(arg_0._email, arg_0._client_id),
                    timeout_secs=ACTIVE_TIMEOUT_SECS,
                )
                await arg_0.Func_client(arg_8)
            except exceptions.NetworkError as e:
                logger.warning('Failed to set active client: {}'.format(e))
            else:
                logger.info('Set active client for {} seconds'
                            .format(ACTIVE_TIMEOUT_SECS))


def Func(arg_0):
        """Parse the image upload response to obtain status.

        Args:
            res: http_utils.FetchResponse instance, the upload response

        Returns:
            dict, sessionStatus of the response

        Raises:
            hangups.NetworkError: If the upload request failed.
        """
        arg_1 = json.loads(arg_0.body.decode())
        if 'sessionStatus' not in arg_1:
            try:
                arg_2 = (
                    arg_1['errorMessage']['additionalInfo']
                    ['uploader_service.GoogleRupioAdditionalInfo']
                    ['completionInfo']['customerSpecificInfo']
                )
                arg_3 = '{} : {}'.format(arg_2['status'], arg_2['message'])
            except KeyError:
                arg_3 = 'unknown reason'
            raise exceptions.NetworkError('image upload failed: {}'.format(
                arg_3
            ))
        return arg_1['sessionStatus']