Posts: 4,648
Threads: 1,495
Joined: Sep 2016
i am looking for a program to line up ( white-space by default, otherwise specified string) separated columns, given in a list of strings (lines) for a function/module implementation, or in a file or stdin for a command implementation. the columns should be left justified unless all rows of that column are decimal numbers in which case they are right justified. a more advanced version could also line up CIDR addresses so the '/' characters in them line up.
Tradition is peer pressure from dead people
What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
Posts: 1,298
Threads: 38
Joined: Sep 2016
This tutorial gives some excellent examples of formatting. https://docs.python.org/3/tutorial/input...formatting
If it ain't broke, I just haven't gotten to it yet.
OS: Windows 10, openSuse 42.3, freeBSD 11, Raspian "Stretch"
Python 3.6.5, IDE: PyCharm 2018 Community Edition
Posts: 4,648
Threads: 1,495
Joined: Sep 2016
Jan-07-2017, 04:11 AM
(This post was last modified: Jan-07-2017, 04:12 AM by Skaperen.)
one of the complications of a program like this is that it needs to figure out the width of each column, for as many columns as are present, across all rows. it also needs verify the datatype of each column across all rows. and it gets more complex when working with different justifications on adjacent columns.
Tradition is peer pressure from dead people
What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
Posts: 4,220
Threads: 97
Joined: Sep 2016
I've done this before, I just can't remember where. It's not that hard. Loop through the columns, determining the maximum width of the string representations. Construct a format string (with {}'s) using the width information plus 1 or 2 spaces for a gutter. Loop through the rows, passing the row to the format method with * notation. Join the resulting strings with '\n'. You just have the added wrinkle of detecting numeric columns and putting that into the format specification.
Posts: 2,953
Threads: 48
Joined: Sep 2016
Jan-07-2017, 08:05 AM
(This post was last modified: Jan-07-2017, 08:05 AM by wavic.)
How about Pandas module? print(pandas.DataFrame.from_records(data))
Posts: 4,648
Threads: 1,495
Joined: Sep 2016
i mean text data that may be numbers or may be words and names, more often the latter. i want to line them up for printing. here is a list states i have been in and their capitals, lined up, sorted by state and boxed:
Output: +---<STDIN>-------------------+
| Arkansas Little_Rock |
| Delaware Dover |
| Illinois Springfield |
| Indiana Indianapolis |
| Kentucky Frankfort |
| New_Jersey Trenton |
| New_York Albany |
| North_Carolina Raleigh |
| Ohilo Columbus |
| Pennsylvania Harrisburg |
| South_Carolina Columbia |
| Texas Austin |
| Virginia Richmond |
| West_Virginia Charleston |
+-----------------------------+
Tradition is peer pressure from dead people
What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
Posts: 4,220
Threads: 97
Joined: Sep 2016
Here's my attempt to recreate my code just after waking up:
states = [['Arkansas', 'Little_Rock'], ['Delaware', 'Dover'], ['Illinois', 'Springfield'], ['Indiana', 'Indianapolis'],
['Kentucky', 'Frankfort'], ['New_Jersey', 'Trenton'], ['New_York', 'Albany'], ['North_Carolina', 'Raleigh'],
['Ohilo', 'Columbus'], ['Pennsylvania', 'Harrisburg'], ['South_Carolina', 'Columbia'], ['Texas', 'Austin'],
['Virginia', 'Richmond'], ['West_Virginia', 'Charleston']]
max_widths = []
for column_index in range(len(states[0])):
column = [row[column_index] for row in states]
max_widths.append(len(max([str(datum) for datum in column], key = len)))
specs = ['{{:<{}}}'.format(width) for width in max_widths]
format_spec = ' '.join(specs)
lines = [format_spec.format(*row) for row in states]
print('\n'.join(lines)) Here's the output:
Output: Arkansas Little_Rock
Delaware Dover
Illinois Springfield
Indiana Indianapolis
Kentucky Frankfort
New_Jersey Trenton
New_York Albany
North_Carolina Raleigh
Ohilo Columbus
Pennsylvania Harrisburg
South_Carolina Columbia
Texas Austin
Virginia Richmond
West_Virginia Charleston
You would just need to vary the justification indicator in the format specification based on the type of the column.
Posts: 7,320
Threads: 123
Joined: Sep 2016
String formatting as advised.
Example:
data = '''\
Arkansas,Little_Rock
Delaware,Dover
Illinois,Springfield
Indiana,Indianapolis
Kentucky,Frankfort'''
data_list = [line.split(',') for line in data.split('\n')]
header = ['State', 'Capital']
sf = "{:<10s} {:>5s}"
print(sf.format(*header))
print('-'*23)
for sublist in data_list:
print(sf.format(*sublist))
print('-'*23) Output: State Capital
-----------------------
Arkansas Little_Rock
Delaware Dover
Illinois Springfield
Indiana Indianapolis
Kentucky Frankfort
-----------------------
Posts: 4,648
Threads: 1,495
Joined: Sep 2016
(Jan-07-2017, 04:25 AM)ichabod801 Wrote: I've done this before, I just can't remember where. It's not that hard. Loop through the columns, determining the maximum width of the string representations. Construct a format string (with {}'s) using the width information plus 1 or 2 spaces for a gutter. Loop through the rows, passing the row to the format method with * notation. Join the resulting strings with '\n'. You just have the added wrinkle of detecting numeric columns and putting that into the format specification.
one thing i was looking for was to see how intermixing of column types was handled. if left justified column is to the the left of a right justified column it leave open the option to squeeze them tighter. would you (dare to) do that? that's code i'd like to see.
FYI, i did this decades ago in 370 assembler ... with the justification mix.
Tradition is peer pressure from dead people
What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
|