String formatting (%)

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Pascal

    String formatting (%)

    Hello,
    I've a float number 123456789.01 and, I'de like to format it like this
    "123 456 789.01".
    Is this possible with % character?
  • Peter Hansen

    #2
    Re: String formatting (%)

    Pascal wrote:
    [color=blue]
    > Hello,
    > I've a float number 123456789.01 and, I'de like to format it like this
    > "123 456 789.01".
    > Is this possible with % character?[/color]

    No, as shown by http://docs.python.org/lib/typesseq-strings.html
    but you could probably use the 'locale' module instead.

    I suspect there's also a regular expression that could deal with
    that, but I don't want to know what it is. ;-)

    -Peter

    Comment

    • Larry Bates

      #3
      Re: String formatting (%)

      Pascal,

      Here is a function that I had that does what you want.
      Warning-If the floats get very large it breaks down.

      Larry Bates
      Syscon, Inc.

      def fmt_wspaces(amo unt):
      #
      # This function will take the number passed to it and format it with
      # spaces as thousands separators.
      #
      # If I got zero return zero (0.00)
      #
      if not amount: return '0.00'
      #
      # Handle negative numbers
      #
      if amount < 0: sign="-"
      else: sign=""
      #
      # Split into fractional and whole parts
      #
      whole_part=abs( long(amount))
      fractional_part =abs(amount)-whole_part
      #
      # Convert to string
      #
      temp="%i" % whole_part
      #
      # Convert the digits to a list
      #
      digits=list(tem p)
      #
      # Calculate the pad length to fill out a complete thousand and add
      # the pad characters (space(s)) to the beginning of the string.
      #
      padchars=3-(len(digits)%3)
      if padchars != 3: digits=tuple(pa dchars*[' ']+digits)
      else: digits=tuple(di gits)
      #
      # Create the mask for formatting the string
      #
      sections=len(di gits)/3
      mask=sections*" %s%s%s"
      if _debug > 2: logf.writelines ("D","mask=% s" % mask)
      outstring=mask % digits
      #
      # Drop off the leading space and add back the sign
      #
      outstring=sign+ outstring[1:].lstrip()
      #
      # Add back the fractional part
      #
      outstring+="%.2 f" % fractional_part
      #
      return outstring

      if __name__=="__ma in__":

      print "----------testing negative floats------------------------------"
      sign=-1
      invalue=0L
      for j in range(2):
      for i in range(1,10):
      invalue=invalue *10+i
      print fmt_wspaces(flo at(sign*invalue )-.01)

      print "----------testing positive floats------------------------------"
      sign=1
      invalue=0L
      for j in range(2):
      for i in range(1,10):
      invalue=invalue *10+i
      print fmt_wspaces(flo at(sign*invalue )+.01)



      "Pascal" <pascal.parent@ free.fr> wrote in message
      news:e567c03a.0 404280035.79d0d 973@posting.goo gle.com...[color=blue]
      > Hello,
      > I've a float number 123456789.01 and, I'de like to format it like this
      > "123 456 789.01".
      > Is this possible with % character?[/color]


      Comment

      • vincent wehren

        #4
        Re: String formatting (%)

        Pascal wrote:[color=blue]
        > Hello,
        > I've a float number 123456789.01 and, I'de like to format it like this
        > "123 456 789.01".
        > Is this possible with % character?[/color]

        The following should do what you want, although the commafy_float I
        quickly added is probably a little naive:


        def commafy(numstri ng, thousep=","):
        """
        Commafy the given numeric string numstring

        By default the thousands separator is a comma
        """
        numlist = list(numstring)
        numlist.reverse ()
        tmp = []
        for i in range(0, len(numlist), 3):
        tmp.append("".j oin(numlist[i:i+3]))
        numlist = thousep.join(tm p)
        numlist = list(numlist)
        numlist.reverse ()
        return "".join(numlist )

        def commafy_float(f lStr, thousep=","):
        whole, dec = flStr.split("." )
        return ".".join([commafy(whole, thousep=thousep )
        , dec])

        if __name__ == "__main__":

        units = "56746781250450 "
        unitsWithThouSe ps = commafy(units)
        print unitsWithThouSe ps
        aFloatAsString = "1128058.23 "
        aFloatAsStringW ithThouSeps = commafy_float(a FloatAsString
        ,thousep=" ")
        print aFloatAsStringW ithThouSeps


        Regards

        -- Vincent Wehren


        Comment

        • Daniel 'Dang' Griffith

          #5
          Re: String formatting (%)

          On Wed, 28 Apr 2004 09:15:02 -0400, Peter Hansen <peter@engcorp. com>
          wrote:
          [color=blue]
          >Pascal wrote:
          >[color=green]
          >> Hello,
          >> I've a float number 123456789.01 and, I'de like to format it like this
          >> "123 456 789.01".
          >> Is this possible with % character?[/color]
          >
          >No, as shown by http://docs.python.org/lib/typesseq-strings.html
          >but you could probably use the 'locale' module instead.
          >
          >I suspect there's also a regular expression that could deal with
          >that, but I don't want to know what it is. ;-)
          >
          >-Peter[/color]
          Since you don't want to know what it is, I'll at least tell you
          where it is: In Mastering Regular Expressions by Jeffrey E. F. Friedl.
          I don't have it front of me, but it's the "commafying " example. A
          quick search of the author's site looks like it's on pgs 64-65.
          Of course, the OP would substitute spaces for the commas.
          --dang

          Comment

          • Peter Hansen

            #6
            Re: String formatting (%)

            Daniel 'Dang' Griffith wrote:
            [color=blue]
            > On Wed, 28 Apr 2004 09:15:02 -0400, Peter Hansen <peter@engcorp. com>
            > wrote:[color=green]
            >>I suspect there's also a regular expression that could deal with
            >>that, but I don't want to know what it is. ;-)[/color]
            >
            > Since you don't want to know what it is, I'll at least tell you
            > where it is: In Mastering Regular Expressions by Jeffrey E. F. Friedl.
            > I don't have it front of me, but it's the "commafying " example. A
            > quick search of the author's site looks like it's on pgs 64-65.[/color]

            Thank you. You can even get the code listings online, which is
            very nice since my copy has migrated into a closet during a recent
            move.
            [color=blue][color=green][color=darkred]
            >>> import re
            >>> s = '21421906.12'
            >>>
            >>> re.sub(r'(?<=\d )(?=(\d\d\d)+\. )', ',', s)[/color][/color][/color]
            '21,421,906.12'
            [color=blue]
            > Of course, the OP would substitute spaces for the commas.[/color]
            [color=blue][color=green][color=darkred]
            >>> _.replace(',', ' ')[/color][/color][/color]
            '21 421 906.12'

            Very nice... quite elegant, I suppose. I struggled with it a
            bit myself yesterday but I'm no RE expert. :-(

            -Peter

            Comment

            • A. Lloyd Flanagan

              #7
              Re: String formatting (%)

              pascal.parent@f ree.fr (Pascal) wrote in message news:<e567c03a. 0404280035.79d0 d973@posting.go ogle.com>...[color=blue]
              > Hello,
              > I've a float number 123456789.01 and, I'de like to format it like this
              > "123 456 789.01".
              > Is this possible with % character?[/color]

              No, but this works with integers. Not sure how it compares to the
              other approaches mentioned. You could adapt it to do floats by
              stopping at the decimal point:

              def addCommas(aNumb er):
              if len(aNumber) < 4: return aNumber
              #how many digits before first ,?
              prefix = len(aNumber) % 3
              #need special case if digits is multiple of 3
              if prefix == 0: prefix = 3
              result = [aNumber[:prefix]]
              for a in range(len(aNumb er) / 3):
              #get next 'segment' of three digits
              segment = aNumber[prefix + 3*a: prefix + 3*a + 3]
              if segment: #can be '' if len(aNumber) divisible by 3
              result.append(s egment)
              return ','.join(result )

              I'm sure this can be improved.

              Comment

              • Peter Hansen

                #8
                Re: String formatting (%)

                Peter Hansen wrote:
                [color=blue][color=green][color=darkred]
                > >>> import re
                > >>> s = '21421906.12'
                > >>>
                > >>> re.sub(r'(?<=\d )(?=(\d\d\d)+\. )', ',', s)[/color][/color]
                > '21,421,906.12'
                >[color=green]
                >> Of course, the OP would substitute spaces for the commas.[/color]
                >[color=green][color=darkred]
                > >>> _.replace(',', ' ')[/color][/color]
                > '21 421 906.12'[/color]

                And in case the OP is entirely unfamiliar with regular
                expressions, you wouldn't actually do a separate "replace"
                operation like the above, so

                re.sub(r'(?<=\d )(?=(\d\d\d)+\. )', ' ', s)

                should work nicely, at least with any floating that *always*
                has a decimal point present. If the numbers might sometimes
                not have a decimal point, I think this will do the job, so
                it's a more general solution:

                re.sub(r'(?<=\d )(?=(\d\d\d)+(\ .|$))', ' ', s)

                Note that addition of an alternate for \. at the end of the pattern.

                -Peter

                Comment

                • Bengt Richter

                  #9
                  Re: String formatting (%)

                  On Wed, 28 Apr 2004 09:15:02 -0400, Peter Hansen <peter@engcorp. com> wrote:
                  [color=blue]
                  >Pascal wrote:
                  >[color=green]
                  >> Hello,
                  >> I've a float number 123456789.01 and, I'de like to format it like this
                  >> "123 456 789.01".
                  >> Is this possible with % character?[/color]
                  >
                  >No, as shown by http://docs.python.org/lib/typesseq-strings.html
                  >but you could probably use the 'locale' module instead.
                  >
                  >I suspect there's also a regular expression that could deal with
                  >that, but I don't want to know what it is. ;-)
                  >[/color]

                  If you are willing to use a special name mod (you can choose it), you
                  can get there with % and a commafy that stuffs spaces instead of commas ;-)
                  [color=blue][color=green][color=darkred]
                  >>> class Doit(dict):[/color][/color][/color]
                  ... def __init__(self, d): dict.__init__(s elf, d)
                  ... def __getitem__(sel f, name):
                  ... if name.startswith ('cfy_'):
                  ... return commafy(self.ge t(name[4:],'??'))
                  ... else: return self.get(name,' ??')
                  ...[color=blue][color=green][color=darkred]
                  >>> def commafy(val):[/color][/color][/color]
                  ... sign, val = '-'[:val<0], str(abs(val))
                  ... val, dec = (val.split('.') +[''])[:2]
                  ... if dec: dec = '.'+dec
                  ... rest = ''
                  ... while val: val, rest = val[:-3], '%s %s'%(val[-3:], rest)
                  ... return '%s%s%s' %(sign, rest[:-1], dec)
                  ...[color=blue][color=green][color=darkred]
                  >>> x=1234
                  >>> 'x: %(x)s cfy_x: %(cfy_x)s' % Doit(vars())[/color][/color][/color]
                  'x: 1234 cfy_x: 1 234'[color=blue][color=green][color=darkred]
                  >>> x=12345.678
                  >>> 'x: %(x)s cfy_x: %(cfy_x)s' % Doit(vars())[/color][/color][/color]
                  'x: 12345.678 cfy_x: 12 345.678'[color=blue][color=green][color=darkred]
                  >>> x = -12345.678
                  >>> 'x: %(x)s cfy_x: %(cfy_x)s' % Doit(vars())[/color][/color][/color]
                  'x: -12345.678 cfy_x: -12 345.678'

                  And the OP's example:
                  [color=blue][color=green][color=darkred]
                  >>> x = 123456789.01
                  >>> 'x: %(x)s cfy_x: %(cfy_x)s' % Doit(vars())[/color][/color][/color]
                  'x: 123456789.01 cfy_x: 123 456 789.01'

                  Regards,
                  Bengt Richter

                  Comment

                  • P Adhia

                    #10
                    Re: String formatting (%)

                    alloydflanagan@ comcast.net (A. Lloyd Flanagan) wrote in message

                    Another version of a more compact function would be,

                    def commafy(s):
                    return len(s) > 3 and "%s,%s" % (commafy(s[:-3]), s[-3:]) or s

                    Note that this function accepts string representation of an integer
                    (without checks of course).

                    P Adhia

                    Comment

                    • A. Lloyd Flanagan

                      #11
                      Re: String formatting (%)

                      padhia@yahoo.co m (P Adhia) wrote in message news:<3281a460. 0404291301.3c3c 647d@posting.go ogle.com>...[color=blue]
                      > Another version of a more compact function would be,
                      >
                      > def commafy(s):
                      > return len(s) > 3 and "%s,%s" % (commafy(s[:-3]), s[-3:]) or s
                      >
                      > Note that this function accepts string representation of an integer
                      > (without checks of course).
                      >
                      > P Adhia[/color]

                      And it seeems to work beautifully. Thanks, that's a great improvement.

                      Comment

                      Working...