import math


def floatToShortestString( value, significantDigits = 15, trimZeros = True, keepPeriod = False, favorEFormBy = 0, includeSign = False ) :
    """
    This function returns the shortest string representation of the float 'value' that is accurate to 
    'significantDigits' digits when converted back to a float.

    The float is converted to both the E-form (i.e., '%e') and F-form (i.e., '%f') with significantDigits.
    Then, after 'trimZeros' and 'keepPeriod' options are implemented, if the length of the E-form minus 
    favorEFormBy is less than or equal to the length of the F-form, the E-form is returned. Otherwise 
    the F-form is returned.

    For example, for significantDigits = 12 the returned string for the float 1.234 will be "1.234", and
    not "1.234000000000" or "1.23400000000e+00" while the string for the float 1.234e-9 will be "1.234-9", and
    not "0.00000000123400000000" or "1.23400000000e-09".

    :param value:               The float to convert.
    :type value: float

    :param significantDigits:   The number of significant digits desired. Restricted to the range 0 to 24 inclusive.
    :type significantDigits: integer

    :param trimZeros:           If True, unneeded zeros to the right of '.' are removed.
    :type trimZeros: bool

    :param keepPeriod:          If False, '.' is removed if there is no digit to its right.
    :type keepPeriod: bool

    :param favorEFormBy:        The integer subtracted from the length of the E-form before the form
                                with the shortest representation is determined.
    :type favorEFormBy: integer

    :param includeSign:         If True, the returned string will always start with a sign character 
                                (i.e., '+' or '-'). Otherwise, only negative values will have a sign.
    :type includeSign: bool

    :rtype: `str`
    """

    if type(value)==str: return value

    def isfinite( value ) :
        """Returns True if value is neither infinite nor not-a-number (NaN) and False otherwise."""

        if( math.isinf( value ) or math.isnan( value ) ) : return( False )
        return( True )

    signNeeded = ''
    if( includeSign ) : signNeeded = '+'

    if( not( isfinite( value ) ) ) : return( ( "%" + signNeeded + "e" ) % value )

    significantDigitsMinus1 = min( 24, max( 0, significantDigits - 1 ) )  # 24 is arbitrary.

    EForm = ( '%%%s.%de' % ( signNeeded, significantDigitsMinus1 ) ) % value

    mantissa, exponent = EForm.split( 'e' )
    if( significantDigitsMinus1 == 0 ) :
        if( mantissa[-1] != '.' ) : mantissa += '.'     # This is required, else the trimZeros will remove all characters for value = 0.
    if( trimZeros ) : mantissa = mantissa.rstrip( '0' )
    if( not( keepPeriod ) and ( mantissa[-1] == '.' ) ) : mantissa = mantissa[:-1]

    exponent = int( exponent )
    if( exponent == 0 ) : return( mantissa )
    EForm = mantissa + 'e' + "%d" % exponent            # Reconstruct "%e" string.

    digitsRightOfPeriod = significantDigitsMinus1 - exponent  # For "%f" string, determine number of digit to the right of the '.'.
    if( ( digitsRightOfPeriod > 25 ) or ( exponent > 50 ) ) : return( EForm )
    digitsRightOfPeriod = max( digitsRightOfPeriod, 0 )

    FForm = ( '%%%s.%df' % ( signNeeded, digitsRightOfPeriod ) ) % value
    if( 'e' in FForm ) : return( EForm )                # For very large numbers, the '%.?f' format returns 'e' format (e.g., .1234e300 --> "1e+299").

    if( '.' in FForm ) :
        if( trimZeros ) : FForm = FForm.rstrip( '0' )
        if( not( keepPeriod ) ) :
            if( FForm[-1] == '.' ) : FForm = FForm[:-1]
    else :
        if( keepPeriod ) : FForm += '.'
    if( ( len( FForm ) + favorEFormBy ) < len( EForm ) ) : return( FForm )

    return( EForm )