By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
 429,434 Members | 1,820 Online
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 429,434 IT Pros & Developers. It's quick & easy.

# Number Format function

 P: n/a I'm am relatively new to Python but use it daily. Today, I went looking for a function, like PHP's number_function, that will take a number and return a string with number formatted with grouped thousands and the decimal portion rounded to a given number of places. This is certainly needed when you want to take a floating-point value from a database and display it as currency, for instance. I could not find what I was looking for so I wrote the following function. I hope either (a) I've provided something useful or (b) someone can tell me what I *should* have done! Thanks. import math def number_format(num, places=0): """Format a number with grouped thousands and given decimal places""" #is_negative = (num < 0) #if is_negative: # num = -num places = max(0,places) tmp = "%.*f" % (places, num) point = tmp.find(".") integer = (point == -1) and tmp or tmp[:point] decimal = (point != -1) and tmp[point:] or "" count = commas = 0 formatted = [] for i in range(len(integer) - 1, 0, -1): count += 1 formatted.append(integer[i]) if count % 3 == 0: formatted.append(",") integer = "".join(formatted[::-1]) return integer+decimal Feb 8 '06 #1
Share this Question
5 Replies

 P: n/a Your code has a little bug, I highly recommend to add a test to your code, for an idea see below - I fixed your code as well. #!/usr/bin/env python import math def number_format(num, places=0): """Format a number with grouped thousands and given decimal places""" #is_negative = (num < 0) #if is_negative: # num = -num places = max(0,places) tmp = "%.*f" % (places, num) point = tmp.find(".") integer = (point == -1) and tmp or tmp[:point] decimal = (point != -1) and tmp[point:] or "" count = commas = 0 formatted = [] for i in range(len(integer) - 1, 0, -1): count += 1 formatted.append(integer[i]) if count % 3 == 0: formatted.append(",") formatted.append(integer[0]) # this misses in your part integer = "".join(formatted[::-1]) return integer+decimal # # add something like this: it helps to prevent you break your code # import unittest class test_number_format(unittest.TestCase): def test(self): self.assertEqual(number_format(1000000, 2), '1,000,000.00') self.assertEqual(number_format(100000, 2), '100,000.00') self.assertEqual(number_format(100, 2), '100.00') self.assertEqual(number_format(1000000.33, 2), '1,000,000.33') self.assertEqual(number_format(1000000.333, 2), '1,000,000.33') self.assertEqual(number_format(1000000.3, 2), '1,000,000.30') self.assertEqual(number_format(123456, 2), '123,456.00') self.assertEqual(number_format(12345, 2), '12,345.00') self.assertEqual(number_format(123, 2), '123.00') self.assertEqual(number_format(123456.33, 2), '123,456.33') self.assertEqual(number_format(12345.333, 2), '12,345.33') self.assertEqual(number_format(123.3, 2), '123.30') suite = unittest.makeSuite(test_number_format) unittest.TextTestRunner(verbosity=2).run(suite) Feb 8 '06 #2

 P: n/a Thanks. I noticed the bugs later. But after talking with my boss, he suggested something more elegant (again *untested*, yet): import locale def number_format(num, places=0) """Format a number according to locality and given places""" locale.setlocale(locale.LC_ALL, locale.getdefaultlocale()[0]) return locale.format("%.*f", (places, num), 1) wi******@hotmail.com wrote: Your code has a little bug, I highly recommend to add a test to your code, for an idea see below - I fixed your code as well. #!/usr/bin/env python import math def number_format(num, places=0): """Format a number with grouped thousands and given decimal places""" #is_negative = (num < 0) #if is_negative: # num = -num places = max(0,places) tmp = "%.*f" % (places, num) point = tmp.find(".") integer = (point == -1) and tmp or tmp[:point] decimal = (point != -1) and tmp[point:] or "" count = commas = 0 formatted = [] for i in range(len(integer) - 1, 0, -1): count += 1 formatted.append(integer[i]) if count % 3 == 0: formatted.append(",") formatted.append(integer[0]) # this misses in your part integer = "".join(formatted[::-1]) return integer+decimal # # add something like this: it helps to prevent you break your code # import unittest class test_number_format(unittest.TestCase): def test(self): self.assertEqual(number_format(1000000, 2), '1,000,000.00') self.assertEqual(number_format(100000, 2), '100,000.00') self.assertEqual(number_format(100, 2), '100.00') self.assertEqual(number_format(1000000.33, 2), '1,000,000.33') self.assertEqual(number_format(1000000.333, 2), '1,000,000.33') self.assertEqual(number_format(1000000.3, 2), '1,000,000.30') self.assertEqual(number_format(123456, 2), '123,456.00') self.assertEqual(number_format(12345, 2), '12,345.00') self.assertEqual(number_format(123, 2), '123.00') self.assertEqual(number_format(123456.33, 2), '123,456.33') self.assertEqual(number_format(12345.333, 2), '12,345.33') self.assertEqual(number_format(123.3, 2), '123.30') suite = unittest.makeSuite(test_number_format) unittest.TextTestRunner(verbosity=2).run(suite) Feb 8 '06 #3

 P: n/a This is a little faster: def number_format(num, places=0): """Format a number according to locality and given places""" locale.setlocale(locale.LC_ALL, "") return locale.format("%.*f", (places, num), True) I tested this ok with my test Feb 8 '06 #4

 P: n/a "wi******@hotmail.com" wrote in news:11**********************@f14g2000cwb.googlegr oups.com: def number_format(num, places=0): """Format a number according to locality and given places""" locale.setlocale(locale.LC_ALL, "") return locale.format("%.*f", (places, num), True) There are some edge cases in the format conversion that could present some issues. For example: print number_format( 2312753.44500000, 2 ) 2,312,753.44 print number_format( 2312753.44500001, 2 ) 2,312,753.45 I would expect the first to produce the same results as the second, but, I suppose because of one of floating point's features, it doesn't work that way. -- rzed Feb 8 '06 #5

 P: n/a Rick Zantow wrote: print number_format( 2312753.44500000, 2 )2,312,753.44 print number_format( 2312753.44500001, 2 )2,312,753.45I would expect the first to produce the same results as the second, but,I suppose because of one of floating point's features, it doesn't workthat way. 2312753.44500000 2312753.4449999998 2312753.44500001 2312753.4450000101 So, yeah, the nature of floating points is going to make that first one round "unexpectedly". -- \S -- si***@chiark.greenend.org.uk -- http://www.chaos.org.uk/~sion/ ___ | "Frankly I have no feelings towards penguins one way or the other" \X/ | -- Arthur C. Clarke her nu becomež se bera eadward ofdun hlęddre heafdes bęce bump bump bump Feb 9 '06 #6

### This discussion thread is closed

Replies have been disabled for this discussion.