Skip to content

Commit ac370cb

Browse files
committed
Updating the example with unicode characters as well as demonstrating the same table entries formatted as both an iterable of iterable as well as an iterable of objects.
1 parent 8e49e5a commit ac370cb

File tree

1 file changed

+86
-21
lines changed

1 file changed

+86
-21
lines changed

examples/table_display.py

Lines changed: 86 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -30,29 +30,13 @@
3030
BACK_ALT = ''
3131

3232
# Format to use for the grid style when displaying tables with the tableformatter module
33-
grid_style = tf.AlternatingRowGrid(BACK_PRI, BACK_ALT) # Use rows of alternating color to assist as a visual guide
33+
grid_style = tf.AlternatingRowGrid(BACK_PRI, BACK_ALT) # Use rows of alternating color to assist as a visual guide
3434

3535
# Create a function to format a fixed-width table for pretty-printing using the desired table format
3636
table = functools.partial(tf.generate_table, grid_style=grid_style)
3737

3838

39-
# Population data from Wikipedia: https://en.wikipedia.org/wiki/List_of_cities_proper_by_population
40-
EXAMPLE_DATA = [['Shanghai', 'Shanghai', 'China', 'Asia', 24183300, 6340.5],
41-
['Beijing', 'Hebei', 'China', 'Asia', 20794000, 1749.57],
42-
['Karachi', 'Sindh', 'Pakistan', 'Asia', 14910352, 615.58],
43-
['Shenzen', 'Guangdong', 'China', 'Asia', 13723000, 1493.32],
44-
['Guangzho', 'Guangdong', 'China', 'Asia', 13081000, 1347.81],
45-
['Mumbai', 'Maharashtra', 'India', 'Asia', 12442373, 465.78],
46-
['Istanbul', 'Istanbul', 'Turkey', 'Eurasia', 12661000, 620.29],
47-
]
48-
49-
# Calculate population density
50-
for row in EXAMPLE_DATA:
51-
row.append(row[-2]/row[-1])
52-
53-
54-
# TODO: Color row text foreground based on population density
55-
39+
# Formatter functions
5640

5741
def no_dec(num: float) -> str:
5842
"""Format a floating point number with no decimal places."""
@@ -64,17 +48,94 @@ def two_dec(num: float) -> str:
6448
return "{0:.2f}".format(num)
6549

6650

51+
# Population data from Wikipedia: https://en.wikipedia.org/wiki/List_of_cities_proper_by_population
52+
53+
54+
# ############ Table data formatted as an iterable of iterable fields ############
55+
56+
EXAMPLE_ITERABLE_DATA = [['Shanghai', 'Shanghai', 'China', 'Asia', 24183300, 6340.5],
57+
['Beijing', 'Hebei', 'China', 'Asia', 20794000, 1749.57],
58+
['Karachi', 'Sindh', 'Pakistan', 'Asia', 14910352, 615.58],
59+
['Shenzen', 'Guangdong', 'China', 'Asia', 13723000, 1493.32],
60+
['Guangzho', 'Guangdong', 'China', 'Asia', 13081000, 1347.81],
61+
['Mumbai', 'Maharashtra', 'India', 'Asia', 12442373, 465.78],
62+
['Istanbul', 'Istanbul', 'Turkey', 'Eurasia', 12661000, 620.29],
63+
]
64+
65+
# Calculate population density
66+
for row in EXAMPLE_ITERABLE_DATA:
67+
row.append(row[-2]/row[-1])
68+
69+
6770
# # Column headers plus optional formatting info for each column
6871
columns = [tf.Column('City', header_halign=tf.ColumnAlignment.AlignCenter),
6972
tf.Column('Province', header_halign=tf.ColumnAlignment.AlignCenter),
7073
'Country', # NOTE: If you don't need any special effects, you can just pass a string
7174
tf.Column('Continent', cell_halign=tf.ColumnAlignment.AlignCenter),
7275
tf.Column('Population', cell_halign=tf.ColumnAlignment.AlignRight, formatter=tf.FormatCommas()),
73-
tf.Column('Area (km^2)', cell_halign=tf.ColumnAlignment.AlignRight, formatter=two_dec),
74-
tf.Column('Pop. Density (/km^2)', width=12, cell_halign=tf.ColumnAlignment.AlignRight, formatter=no_dec),
76+
tf.Column('Area (km²)', width=7, header_halign=tf.ColumnAlignment.AlignCenter,
77+
cell_halign=tf.ColumnAlignment.AlignRight, formatter=two_dec),
78+
tf.Column('Pop. Density (/km²)', width=12, header_halign=tf.ColumnAlignment.AlignCenter,
79+
cell_halign=tf.ColumnAlignment.AlignRight, formatter=no_dec),
7580
]
7681

7782

83+
# ######## Table data formatted as an iterable of python objects #########
84+
85+
class CityInfo(object):
86+
"""City information container"""
87+
def __init__(self, city: str, province: str, country: str, continent: str, population: int, area: float):
88+
self.city = city
89+
self.province = province
90+
self.country = country
91+
self.continent = continent
92+
self._population = population
93+
self._area = area
94+
95+
def get_population(self):
96+
"""Population of the city"""
97+
return self._population
98+
99+
def get_area(self):
100+
"""Area of city in km²"""
101+
return self._area
102+
103+
104+
def pop_density(data: CityInfo):
105+
"""Calculate the population density from the data entry"""
106+
if isinstance(data, CityInfo):
107+
return no_dec(data.get_population() / data.get_area())
108+
109+
return ''
110+
111+
112+
EXAMPLE_OBJECT_DATA = [CityInfo('Shanghai', 'Shanghai', 'China', 'Asia', 24183300, 6340.5),
113+
CityInfo('Beijing', 'Hebei', 'China', 'Asia', 20794000, 1749.57),
114+
CityInfo('Karachi', 'Sindh', 'Pakistan', 'Asia', 14910352, 615.58),
115+
CityInfo('Shenzen', 'Guangdong', 'China', 'Asia', 13723000, 1493.32),
116+
CityInfo('Guangzho', 'Guangdong', 'China', 'Asia', 13081000, 1347.81),
117+
CityInfo('Mumbai', 'Maharashtra', 'India', 'Asia', 12442373, 465.78),
118+
CityInfo('Istanbul', 'Istanbul', 'Turkey', 'Eurasia', 12661000, 620.29),
119+
]
120+
121+
# If table entries are python objects, all columns must be defined with the object attribute to query for each field
122+
# - attributes can be fields or functions. If a function is provided, the formatter will automatically call
123+
# the function to retrieve the value
124+
obj_cols = [tf.Column('City', attrib='city', header_halign=tf.ColumnAlignment.AlignCenter),
125+
tf.Column('Province', attrib='province', header_halign=tf.ColumnAlignment.AlignCenter),
126+
tf.Column('Country', attrib='country'),
127+
tf.Column('Continent', attrib='continent', cell_halign=tf.ColumnAlignment.AlignCenter),
128+
tf.Column('Population', attrib='get_population', cell_halign=tf.ColumnAlignment.AlignRight,
129+
formatter=tf.FormatCommas()),
130+
tf.Column('Area (km²)', attrib='get_area', width=7, header_halign=tf.ColumnAlignment.AlignCenter,
131+
cell_halign=tf.ColumnAlignment.AlignRight, formatter=two_dec),
132+
tf.Column('Pop. Density (/km²)', width=12, header_halign=tf.ColumnAlignment.AlignCenter,
133+
cell_halign=tf.ColumnAlignment.AlignRight, obj_formatter=pop_density),
134+
]
135+
136+
# TODO: Color row text foreground based on population density
137+
138+
78139
class TableDisplay(cmd2.Cmd):
79140
"""Example cmd2 application showing how you can display tabular data."""
80141

@@ -98,7 +159,11 @@ def ptable(self, tabular_data, headers=()):
98159

99160
def do_table(self, _):
100161
"""Display data on the Earth's most populated cities in a table."""
101-
self.ptable(EXAMPLE_DATA, columns)
162+
self.ptable(EXAMPLE_ITERABLE_DATA, columns)
163+
164+
def do_object_table(self, _):
165+
"""Display data on the Earth's most populated cities in a table."""
166+
self.ptable(EXAMPLE_OBJECT_DATA, obj_cols)
102167

103168

104169
if __name__ == '__main__':

0 commit comments

Comments
 (0)