peng/functions.py
def to_scientific_string(number, frac_length=None, exp_length=None, sign_always=False):
    """
    Convert number or number string to a number string in scientific notation.

    Full precision is maintained if the number is represented as a string

    :param number: Number to convert
    :type  number: number or string

    :param frac_length: Number of digits of fractional part, None indicates
                        that the fractional part of the number should not be
                        limited
    :type  frac_length: integer or None

    :param exp_length: Number of digits of the exponent; the actual length of
                       the exponent takes precedence if it is longer
    :type  exp_length: integer or None

    :param sign_always: Flag that indicates whether the sign always
                        precedes the number for both non-negative and negative
                        numbers (True) or only for negative numbers (False)
    :type  sign_always: boolean

    :rtype: string

    For example:

        >>> import peng
        >>> peng.to_scientific_string(333)
        '3.33E+2'
        >>> peng.to_scientific_string(0.00101)
        '1.01E-3'
        >>> peng.to_scientific_string(99.999, 1, 2, True)
        '+1.0E+02'
    """
    # pylint: disable=W0702
    try:
        number = -1e20 if np.isneginf(number) else number
    except:
        pass
    try:
        number = +1e20 if np.isposinf(number) else number
    except:
        pass
    exp_length = 0 if not exp_length else exp_length
    mant, exp = to_scientific_tuple(number)
    fmant = float(mant)
    if (not frac_length) or (fmant == int(fmant)):
        return "{sign}{mant}{period}{zeros}E{exp_sign}{exp}".format(
            sign="+" if sign_always and (fmant >= 0) else "",
            mant=mant,
            period="." if frac_length else "",
            zeros="0" * frac_length if frac_length else "",
            exp_sign="-" if exp < 0 else "+",
            exp=str(abs(exp)).rjust(exp_length, "0"),
        )
    rounded_mant = round(fmant, frac_length)
    # Avoid infinite recursion when rounded mantissa is _exactly_ 10
    if abs(rounded_mant) == 10:
        rounded_mant = fmant = -1.0 if number < 0 else 1.0
        frac_length = 1
        exp = exp + 1
    zeros = 2 + (1 if (fmant < 0) else 0) + frac_length - len(str(rounded_mant))
    return "{sign}{mant}{zeros}E{exp_sign}{exp}".format(
        sign="+" if sign_always and (fmant >= 0) else "",
        mant=rounded_mant,
        zeros="0" * zeros,
        exp_sign="-" if exp < 0 else "+",
        exp=str(abs(exp)).rjust(exp_length, "0"),
    )
def to_scientific_string(number, frac_length=None, exp_length=None, sign_always=False):
    """
    Convert number or number string to a number string in scientific notation.

    Full precision is maintained if the number is represented as a string

    :param number: Number to convert
    :type  number: number or string

    :param frac_length: Number of digits of fractional part, None indicates
                        that the fractional part of the number should not be
                        limited
    :type  frac_length: integer or None

    :param exp_length: Number of digits of the exponent; the actual length of
                       the exponent takes precedence if it is longer
    :type  exp_length: integer or None

    :param sign_always: Flag that indicates whether the sign always
                        precedes the number for both non-negative and negative
                        numbers (True) or only for negative numbers (False)
    :type  sign_always: boolean

    :rtype: string

    For example:

        >>> import peng
        >>> peng.to_scientific_string(333)
        '3.33E+2'
        >>> peng.to_scientific_string(0.00101)
        '1.01E-3'
        >>> peng.to_scientific_string(99.999, 1, 2, True)
        '+1.0E+02'
    """
    # pylint: disable=W0702
    try:
        number = -1e20 if np.isneginf(number) else number
    except:
        pass
    try:
        number = +1e20 if np.isposinf(number) else number
    except:
        pass
    exp_length = 0 if not exp_length else exp_length
    mant, exp = to_scientific_tuple(number)
    fmant = float(mant)
    if (not frac_length) or (fmant == int(fmant)):
        return "{sign}{mant}{period}{zeros}E{exp_sign}{exp}".format(
            sign="+" if sign_always and (fmant >= 0) else "",
            mant=mant,
            period="." if frac_length else "",
            zeros="0" * frac_length if frac_length else "",
            exp_sign="-" if exp < 0 else "+",
            exp=str(abs(exp)).rjust(exp_length, "0"),
        )
    rounded_mant = round(fmant, frac_length)
    # Avoid infinite recursion when rounded mantissa is _exactly_ 10
    if abs(rounded_mant) == 10:
        rounded_mant = fmant = -1.0 if number < 0 else 1.0
        frac_length = 1
        exp = exp + 1
    zeros = 2 + (1 if (fmant < 0) else 0) + frac_length - len(str(rounded_mant))
    return "{sign}{mant}{zeros}E{exp_sign}{exp}".format(
        sign="+" if sign_always and (fmant >= 0) else "",
        mant=rounded_mant,
        zeros="0" * zeros,
        exp_sign="-" if exp < 0 else "+",
        exp=str(abs(exp)).rjust(exp_length, "0"),
    )
Convert number or number string to a number string in scientific notation.

    Full precision is maintained if the number is represented as a string

    :param number: Number to convert
    :type  number: number or string

    :param frac_length: Number of digits of fractional part, None indicates
                        that the fractional part of the number should not be
                        limited
    :type  frac_length: integer or None

    :param exp_length: Number of digits of the exponent; the actual length of
                       the exponent takes precedence if it is longer
    :type  exp_length: integer or None

    :param sign_always: Flag that indicates whether the sign always
                        precedes the number for both non-negative and negative
                        numbers (True) or only for negative numbers (False)
    :type  sign_always: boolean

    :rtype: string

    For example:

        >>> import peng
        >>> peng.to_scientific_string(333)
        '3.33E+2'
        >>> peng.to_scientific_string(0.00101)
        '1.01E-3'
        >>> peng.to_scientific_string(99.999, 1, 2, True)
        '+1.0E+02'