Reputation: 5
I want to make a program that replicates at an extremely basic level, and displays all the stock prices and the amount of it owned neatly keeping the columns in the same line, making it look neat. I've tried doing this code:
print '{:1s} {:1s} {:1s} {:4.2f} {:1s} {:10d} {:1s}'.format('|','NAME','|',53.63,'|', 10000000, '|')
print '{:1s} {:1s} {:1s} {:4.2f} {:1s} {:10d} {:1s}'.format('|','NAME','|',4837.34,'|', 1000000000, '|')
but that displays them like this:
| NAME | 53.63 | 10000000 |
| NAME | 4837.34 | 1000000000 |
and I want it to display like this
| NAME | 53.63 | 10000000 |
| NAME | 4837.34 | 1000000000 |
or in a similar way. I want the lines on either side of them to be in line, so it looks neater
Is there a way for me to be able to achieve this?
Thanks in Advance
Upvotes: 1
Views: 2412
Reputation: 123463
Using the Format Specification Mini-Language described the documentation, you can use an optional width specifier with each field (along with others controlling alignment and precision of numerical values).
fmt = '| {:^8s} | {:>10,.2f} | {:>14,d} |'
print fmt.format('NAME', 53.63, 10000000)
print fmt.format('NAME', 4837.34, 1000000000)
The width values can also be mixed in with the field data:
fmt = '| {:^{}s} | {:>{},.2f} | {:>{},d} |'
print fmt.format('NAME', 8, 53.63, 10, 10000000, 14)
print fmt.format('NAME', 8, 4837.34, 10, 1000000000, 14)
Or each can be supplied in a separate step to keep the two types of values apart:
fmt = '| {{:^{}s}} | {{:>{},.2f}} | {{:>{},d}} |'.format(8, 10, 14) # widths only
print fmt.format('NAME', 53.63, 10000000) # data only
print fmt.format('NAME', 4837.34, 1000000000)
Whatevers, this would be the output:
| NAME | 53.63 | 10,000,000 |
| NAME | 4,837.34 | 1,000,000,000 |
Obviously you need to know the maximum width of each column of data in advance. If that's not known, then you may have to examine all the values in each column to find the largest one in order to determine the proper field width specifier value to use -- assuming all the data is available before being output.
Upvotes: 1
Reputation: 250941
Something like this:
print '| {:^4} | {:^7.2f} | {:<10} |'.format('NAME', 53.63, 10000000)
print '| {:^4} | {:^7.2f} | {:<10} |'.format('NAME',4837.34,1000000000)
Output:
| NAME | 53.63 | 10000000 |
| NAME | 4837.34 | 1000000000 |
You can also pass the field width from format
:
print '| {:^{}} | {:^{}.2f} | {:<{}} |'.format('NAME', 4, 53.63, 7, 10000000, 10)
print '| {:^{}} | {:^{}.2f} | {:<{}} |'.format('NAME', 4, 4837.34, 7, 1000000000, 10)
output:
| NAME | 53.63 | 10000000 |
| NAME | 4837.34 | 1000000000 |
Upvotes: 3
Reputation: 113945
Assuming that you have the data in some tab-delimited file, to begin with, this should work for you:
def tabularize(infilepath, outfilepath, delim='\t', largeFile=False):
""" Return nothing
Write into the file in outfilepath, the contents of infilepath, expressed in tabular form.
The tabular form is similar to the way in which SQL tables are displayed.
If largeFile is set to True, then no caching of lines occurs. However, two passes of the infile are required"""
if largeFile:
widths = getWidths(infilepath, delim)
else:
with open(infilepath) as infile:
lines = [line.strip().split(delim) for line in infile.readlines() if line.strip()]
widths = [max([len(row) for row in rows])+2 for rows in izip_longest(*lines, fillvalue="")]
with open(outfilepath, 'w') as outfile:
outfile.write("+")
for width in widths:
outfile.write('-'*width + "+")
outfile.write('\n')
for line in lines:
outfile.write("|")
for col,width in izip_longest(line,widths, fillvalue=""):
outfile.write("%s%s%s|" %(' '*((width-len(col))/2), col, ' '*((width+1-len(col))/2)))
outfile.write('\n+')
for width in widths:
outfile.write('-'*width + "+")
outfile.write('\n')
def getWidths(infilepath, delim):
answer = defaultdict(int)
with open(infilepath) as infile:
for line in infile:
cols = line.strip().split(delim)
lens = map(len, cols)
for i,l in enumerate(lens):
if answer[i] < l:
answer[i] = l
return [answer[k] for k in sorted(answer)]
if __name__ == "__main__":
print 'starting'
infilepath = 'testin'
outfilepath = 'testout'
tabularize(infilepath, outfilepath, '...', False)
print 'done'
Upvotes: 0