Friday, 16 August 2013

Print left-aligned formatted float with suffix text

Print left-aligned formatted float with suffix text

I want to easily format and left-align a quantity that is a compound of
float plus string (in my case the string is a unit of measure), using the
standard format_spec syntax.
Using underscores to represent consumed space:
>>> print '{:<20.2f} {:s}'.format(1.0, 'kg/hr')
1.00_________________kg/hr
But what I really want is a convenient way of producing this:
1.00_kg/hr________________
Furthermore, I would like the total width to be the width component of the
format_spec, in this case 20 (but I want a general solution).
I have already searched Google and SO and have not found anything. My
fallback is to write a hacky format_spec parser to filter out the float
formatting parts, apply that to make the float become a string and then
reconstruct a new format_spec that I apply to the concatenation of the
two. I am overriding __format__() in a class, so I receive the format_spec
when '{:<20.2f}'.format(my_obj) is called (my_obj internally contains the
unit of measure, which must be shown when __repr__() is called). Proposed
pseudocode:
def __format__(self, format_spec):
float_spec = extract_float_part(format_spec)
# Using the example above, float_spec becomes '.2f'
float_str = string.format(float_value, float_spec)
# Using example, float_str becomes '1.00'
new_format_spec = make_new_format_spec(format_spec)
# Using example, new_format_spec should become '<20s'
output = string.format(' '.join([float_str, unit_str]), new_format_spec)
I really don't want to write (nor have to maintain) extract_float_part()
and make_new_format_spec(). It will be easy to do for a subset of cases
(e.g. detect for, and split at the period, etc.) but I am worried that
there will be lots of corner cases and I'll have to add a lot of
boilerplate to handle them. In general, the format_spec could be whatever
is allowed in the standard format function, and any standard errors that
are triggered should propagate and be reported correctly for the float
part.
Is there a smarter way?

No comments:

Post a Comment