[CentralOH] Python % Formatting
Mark Erbaugh
mark at microenh.com
Fri Dec 7 18:12:12 CET 2007
Here is my first cut at some code to do what I want. I've added a
couple of features that weren't in the original request, but should add
some value. See the docstrings below for more information.
Feedback is welcome!
Mark
===============================================================
import UserDict
def split_fmt(fmt):
"""
split a partial format string into the format portion
and any trailing characters.
the format string includes all characters up to and
including the first letter after the ')'
split_fmt('first)2s.') -> ('first)2s', '.')
if no formatting field is found return the input and ''
"""
p = fmt.find(')')
if p > -1:
l = len(fmt)
p += 1
while p < l:
if fmt[p].isalpha():
p += 1
return fmt[:p], fmt[p:]
else:
p +=1
return fmt, ''
class csDict(UserDict.UserDict):
"""
user dict that returns '' if element not found
"""
def __getitem__(self, key):
return self.data.get(key, '')
def cs(fmt, data={}, **kwds):
"""
implement 'conditional' separator formatting.
This expands the % mapping formatting.
i.e. data = {'first': 'Mark', 'midle': 'E.', 'last': 'Erbaugh'}
fmt = '%(first)s %(middle)s %(last)s'
fmt % data -> 'Mark E. Erbaugh'
This is the similar to 'normal' % dict formatting.
Extensions to % mapping formatting
if the field referenced does not exist or the data field is
empty, that field and any characters follwing it are
skipped. This does not apply to the last field. Any trailing
characters or whitespace will be printed. If fields at the end
are empty, the trailing characters or whitespace from the last
non-empty field will be skipped
Examples:
FMT = '%(first)s %(middle)s %(last)s.'
data(first, middle, last)
'Mark', '', 'Erbaugh' -> 'Mark Erbaugh.'
(space after middle omitted)
'Mark', '', '', -> 'Mark.'
(spaces after first and middle omitted, period
after empty last kept)
FMT = '%(last)s, %(first) %(middle).'
data (first, middle, last)
'Mark', '', 'Erbaugh' -> 'Erbaugh, 'Mark.'
'', '', 'Erbaugh -> 'Erbaugh.' comma after last ommited
(no further non-blank fields)
'', 'Edwin', 'Erbaugh -> 'Erbaugh, Edwin.'
(space after first omitted)
data can be a mapping(dict) or keyword parameters or both
if a keyword parameter is the same as a dict key,
the keyword parameter will overwrite the dict value
"""
def fmt_str(f): return ('%(' + f) % d
d = {}
d.update(data)
d.update(kwds)
d = csDict(d)
r = []
r1 = fmt.split('%(')
r.append(r1[0]) # first element will not have field to be formatted
added_last = False
for i in r1[1:-1]:
f,t = split_fmt(i)
if f > '':
o = fmt_str(f)
if o > '':
r.append(o)
r.append(t)
added_last = True
f,t = split_fmt(r1[-1])
o = fmt_str(f)
if o == '' and added_last:
del r[-1]
else:
r.append(o)
r.append(t)
return ''.join(r)
More information about the CentralOH
mailing list