Skip to content

Instantly share code, notes, and snippets.

@gregpinero
Created November 21, 2014 17:50
Show Gist options
  • Select an option

  • Save gregpinero/614b6af033bc292e5839 to your computer and use it in GitHub Desktop.

Select an option

Save gregpinero/614b6af033bc292e5839 to your computer and use it in GitHub Desktop.
Python Formatting Functions
import re
import datetime
import math
def format_timeinterval(start, end=None):
if not end:
end = datetime.now()
return format_timedelta(end - start)
def format_secondsdelta(seconds):
""""""Useful for database time differences""""""
return format_timedelta(datetime.timedelta(0, seconds, 0))
def format_timedelta(td):
if td.days > 365:
return _format_num(td.days / 365.0, 'yrs')
if td.days > 30:
return _format_num(td.days / 30.0, 'mos')
if td.days > 7:
return _format_num(td.days / 7.0, 'wks')
if td.days > 0:
return _format_num(td.days + td.seconds / (60.0 * 60.0 * 24.0), 'days')
if td.seconds > 3600:
return _format_num(td.seconds / 3600.0, 'hrs')
if td.seconds > 60:
return _format_num(td.seconds / 60.0, 'min')
if td.seconds > 0:
return _format_num(td.seconds + td.microseconds / 1000000.0, 'sec')
return _format_num(td.microseconds / 1000.0, 'msec')
def _format_num(val, units):
s = ""%.1f %s"" % (val, units)
# HACK works but ugly
return s.replace('.0 ', ' ')
def commas(value):
return """".join(commafy(value))
def commafy(s):
if s.startswith('-'):
s = s[1:]
yield ""-""
pieces = str(s).split(""."")
n = len(pieces[0])
for i in range(0, n):
if (n - i) % 3 or not i:
yield pieces[0][i]
else:
yield "",""
yield pieces[0][i]
if len(pieces) > 1:
yield ""."" + pieces[1]
# TODO make this fancy like C# formatting...
def format(value, fmt):
""""""Format a numeric value supporting things
like commas, parens for negative values and
special cases for zeros. Format is:
'n[cpzZ]%' ex: '2c', '0cpz', '1%'
n - number of decimals
c - use commas
p - wrap negative numbers in parenthesis
z - use a ' ' for zero values
Z - use a '-' for zero values
K - convert to thousands and add 'K' suffix
M - convert to millions and add 'M' suffix
B - convert to billions and add 'B' suffix
S - convert to shorter of KMB formats
% - scale by 100 and add a percent sign at the end (unless z/Z)
""""""
# first ensure we have a reasonable value
try:
value = float(value)
except:
return value or ''
# now format it
try:
m = re.match(r'^(\d)[cpzZKMBS%]{0,4}$', fmt)
if not m:
return value
# handle zero specially, if requested
if value == 0:
if 'z' in fmt:
return ''
elif 'Z' in fmt:
return '-'
# scale if using %, K, M or B formats
suffix = ''
factor = { '%': 1e2, 'K': 1e-3, 'M': 1e-6, 'B': 1e-9 }
for k in factor.keys():
if k in fmt:
suffix = k
value *= factor[k]
break
# use parens for negative values
parens = False
if 'p' in fmt and value < 0:
value = -value
parens = True
# format the number to the specified number of decimal places
s = '%%.%sf' % m.group(1)
val = s % value
# fix up with commas
if 'c' in fmt:
val = commas(val)
# wrap in parens
if parens:
val = '(%s)' % val
elif 'p' in fmt:
# pad positive numbers so the last digit lines up better
val = '%s' % val
val += suffix
return val
except Exception, e:
return value or ''
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment