patternpythonMinor
Printing an array in columns
Viewed 0 times
arrayprintingcolumns
Problem
I'm trying to define a function which takes an array and prints it to a predefined total width in as many columns as needed. Think of the way
Here is the kind of output I am looking for:
I created the following script to do that. I'm trying to brush up on my Python, and re-learn how to write pythonic code in the most modern way (latest Python 3), and it doesn't feel very pythonic (and it's not the kind of code I usually write).
```
#!/usr/bin/env python3
import sys, subprocess, json, math
def col_print(title, array):
print()
print()
print(title)
indent = " " * 4
if not array:
print(indent + "")
return
padsize = 1
# Hardcoded for this example
termwidth = 150
maxitemwidth = len(max(array, key=len))
numCols = int((ter
ls prints files for example.Here is the kind of output I am looking for:
$ ./print-columns.py
Files
/home/stephen/dev/src/cmake-browser/cmakeclient.cpp /home/stephen/dev/src/cmake-browser/projectsources.cpp
/home/stephen/dev/src/cmake-browser/main.cpp /home/stephen/dev/src/cmake-browser/includesmodel.cpp
/home/stephen/dev/src/cmake-browser/mainwindow.cpp /home/stephen/dev/src/cmake-browser/definesmodel.cpp
/home/stephen/dev/src/cmake-browser/debugwidget.cpp /home/stephen/dev/src/cmake-browser/highlighter.cpp
/home/stephen/dev/src/cmake-browser/projecttree.cpp /home/stephen/dev/src/cmake-browser/helpviewer.cpp
/home/stephen/dev/src/cmake-browser/projectmodel.cpp /home/stephen/dev/src/cmake-browser/main.cpp
/home/stephen/dev/src/cmake-browser/projectcode.cpp /home/stephen/dev/src/cmake-browser/helpviewer.cpp
/home/stephen/dev/src/cmake-browser/projectdetail.cpp
Targets
KF5ItemModels kdescendantsproxymodel_smoketest klinkitemselectionmodeltest
krecursivefilterproxymodeltest kselectionproxymodel_smoketest kselectionproxymodeltest
proxymodeltestapp proxymodeltestsuite testmodelqueuedconnectionsI created the following script to do that. I'm trying to brush up on my Python, and re-learn how to write pythonic code in the most modern way (latest Python 3), and it doesn't feel very pythonic (and it's not the kind of code I usually write).
```
#!/usr/bin/env python3
import sys, subprocess, json, math
def col_print(title, array):
print()
print()
print(title)
indent = " " * 4
if not array:
print(indent + "")
return
padsize = 1
# Hardcoded for this example
termwidth = 150
maxitemwidth = len(max(array, key=len))
numCols = int((ter
Solution
There are a few style changes in Python.
The main one is Python uses 4 spaces, not 2, as it's standard indent size.
This is important as indent size matters in Python.
Also most variables are
So my code examples may have small changes.
-
I would recommend splitting the displaying and formatting into separate functions.
This is as then you can manipulate the output. Which can be nice.
This means that you would have to change your returns.
Changing this allows you to remove the two empty lines at the beginning,
for having to explicitly call
And you can print both files and targets at the same time:
-
You could pass
This allows you to change them if you wish at a later point.
-
You may want to change
It makes the code slightly easier to understand.
This is as I originally was a bit confused when I saw the
-
Division changed in Python3.
Rather than doing
Python2 division can be nice at times, and so they kept it in.
Python3 division automatically casts
In short this means that you don't have to do things like
Instead you can do
At this point the code looks quite nice:
The main one is Python uses 4 spaces, not 2, as it's standard indent size.
This is important as indent size matters in Python.
Also most variables are
snake_case.So my code examples may have small changes.
-
I would recommend splitting the displaying and formatting into separate functions.
This is as then you can manipulate the output. Which can be nice.
This means that you would have to change your returns.
Changing this allows you to remove the two empty lines at the beginning,
for having to explicitly call
print.And you can print both files and targets at the same time:
print("\n\n".join([
col_print("Files",
[...]
),
col_print("Targets",
[...]
)
]))-
You could pass
termwidth and padsize as default values.This allows you to change them if you wish at a later point.
def col_print(title, array, pad_size=1, term_width=150):
...-
You may want to change
maxitemwidth so there is only one len.It makes the code slightly easier to understand.
This is as I originally was a bit confused when I saw the
len(max(...)).max_item_width = max(map(len, array))-
Division changed in Python3.
Rather than doing
int(a / b) you can do a // b.Python2 division can be nice at times, and so they kept it in.
Python3 division automatically casts
a and b to floats.In short this means that you don't have to do things like
a / float(int(b / c)).Instead you can do
a / (b // c). Which is much more readable.At this point the code looks quite nice:
def col_print(title, array, term_width=150, pad_size=1):
indent = " " * 4
pad = " " * pad_size
title += "\n"
if not array:
return title + indent + ""
max_item_width = max(map(len, array))
num_rows = int(math.ceil(len(array) / ((term_width + pad_size) // (max_item_width + pad_size))))
return title + "\n".join(
indent + pad.join(item.ljust(max_item_width) for item in array[index::num_rows])
for index in range(num_rows)
)Code Snippets
print("\n\n".join([
col_print("Files",
[...]
),
col_print("Targets",
[...]
)
]))def col_print(title, array, pad_size=1, term_width=150):
...max_item_width = max(map(len, array))def col_print(title, array, term_width=150, pad_size=1):
indent = " " * 4
pad = " " * pad_size
title += "\n"
if not array:
return title + indent + "<None>"
max_item_width = max(map(len, array))
num_rows = int(math.ceil(len(array) / ((term_width + pad_size) // (max_item_width + pad_size))))
return title + "\n".join(
indent + pad.join(item.ljust(max_item_width) for item in array[index::num_rows])
for index in range(num_rows)
)Context
StackExchange Code Review Q#116331, answer score: 3
Revisions (0)
No revisions yet.