I'm trying to format some strings for output on the command-line, report style, and am looking for the easiest method to format a string such that I can get automatic paragraph formatting.
In perlform formatting is done through the "format" function
format Something =
Test: @<<<<<<<< @||||| @>>>>>
$str, $%, '$' . int($num)
.
$str = "widget";
$num = $cost/$quantity;
$~ = 'Something';
write;
Variations of the perlform allow texts to be wrapped cleanly, useful for help screens, log reports and such.
Is there a python equivalent? Or a reasonable hack that I could write using Python's new string format function?
Example output I'd like:
Foobar-Title Blob
0123 This is some long text which would wrap
past the 80 column mark and go onto the
next line number of times blah blah blah.
hi there dito
something more text here. more text here. more text
here.
There isn't automatic formatting like this built into Python. (The .format
function syntax is borrowed from C#.) After all, Perl was "Practical Extraction and Report Language" and Python isn't designed for formatting reports.
Your output could be done with the textwrap
module, e.g.
from textwrap import fill
def formatItem(left, right):
wrapped = fill(right, width=41, subsequent_indent=' '*15)
return ' {0:<13}{1}'.format(left, wrapped)
...
>>> print(formatItem('0123', 'This is some long text which would wrap past the 80 column mark and go onto the next line number of times blah blah blah.'))
0123 This is some long text which would wrap
past the 80 column mark
and go onto the next line
number of times blah blah
blah.
Note that this assumes the "left" does not span over 1 line. A more general solution would be
from textwrap import wrap
from itertools import zip_longest
def twoColumn(left, right, leftWidth=13, rightWidth=41, indent=2, separation=2):
lefts = wrap(left, width=leftWidth)
rights = wrap(right, width=rightWidth)
results = []
for l, r in zip_longest(lefts, rights, fillvalue=''):
results.append('{0:{1}}{2:{5}}{0:{3}}{4}'.format('', indent, l, separation, r, leftWidth))
return "\n".join(results)
>>> print(twoColumn("I'm trying to format some strings for output on the command-line", "report style, and am looking for the easiest method to format a string such that I can get automatic paragraph formatting."))
I'm trying to report style, and am looking for the
format some easiest method to format a string such
strings for that I can get automatic paragraph
output on the formatting.
command-line
import textwrap
import itertools
def formatter(format_str,widths,*columns):
'''
format_str describes the format of the report.
{row[i]} is replaced by data from the ith element of columns.
widths is expected to be a list of integers.
{width[i]} is replaced by the ith element of the list widths.
All the power of Python's string format spec is available for you to use
in format_str. You can use it to define fill characters, alignment, width, type, etc.
formatter takes an arbitrary number of arguments.
Every argument after format_str and widths should be a list of strings.
Each list contains the data for one column of the report.
formatter returns the report as one big string.
'''
result=[]
for row in zip(*columns):
lines=[textwrap.wrap(elt, width=num) for elt,num in zip(row,widths)]
for line in itertools.izip_longest(*lines,fillvalue=''):
result.append(format_str.format(width=widths,row=line))
return '\n'.join(result)
For example:
widths=[17,41]
form='{row[0]:<{width[0]}} {row[1]:<{width[1]}}'
titles=['Foobar-Title','0123','hi there','something']
blobs=['Blob','This is some long text which would wrap past the 80 column mark and go onto the next line number of times blah blah blah.','dito','more text here. more text here. more text here.']
print(formatter(form,widths,titles,blobs))
yields
# Foobar-Title Blob
# 0123 This is some long text which would wrap
# past the 80 column mark and go onto the
# next line number of times blah blah blah.
# hi there dito
# something more text here. more text here. more text
# here.
formatter
can take an arbitrary number of columns.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With