12
12
- pip install tableformatter
13
13
"""
14
14
import argparse
15
+ from typing import Tuple
15
16
16
17
import cmd2
17
18
import tableformatter as tf
@@ -93,12 +94,11 @@ def get_area(self):
93
94
return self ._area
94
95
95
96
96
- def pop_density (data : CityInfo ):
97
+ def pop_density (data : CityInfo ) -> str :
97
98
"""Calculate the population density from the data entry"""
98
- if isinstance (data , CityInfo ):
99
- return no_dec (data .get_population () / data .get_area ())
100
-
101
- return ''
99
+ if not isinstance (data , CityInfo ):
100
+ raise AttributeError ("Argument to pop_density() must be an instance of CityInfo" )
101
+ return no_dec (data .get_population () / data .get_area ())
102
102
103
103
104
104
# Convert the Iterable of Iterables data to an Iterable of non-iterable objects for demonstration purposes
@@ -122,7 +122,24 @@ def pop_density(data: CityInfo):
122
122
cell_halign = tf .ColumnAlignment .AlignRight , obj_formatter = pop_density ),
123
123
]
124
124
125
- # TODO: Color row text foreground based on population density
125
+
126
+ EXTREMELY_HIGH_POULATION_DENSITY = 25000
127
+
128
+
129
+ def high_density_tuples (row_tuple : Tuple ) -> dict :
130
+ """Color rows with extremely high population density red."""
131
+ opts = dict ()
132
+ if len (row_tuple ) >= 7 and row_tuple [6 ] > EXTREMELY_HIGH_POULATION_DENSITY :
133
+ opts [tf .TableFormatter .ROW_OPT_TEXT_COLOR ] = tf .TableColors .TEXT_COLOR_RED
134
+ return opts
135
+
136
+
137
+ def high_density_objs (row_obj : CityInfo ) -> dict :
138
+ """Color rows with extremely high population density red."""
139
+ opts = dict ()
140
+ if float (pop_density (row_obj )) > EXTREMELY_HIGH_POULATION_DENSITY :
141
+ opts [tf .TableFormatter .ROW_OPT_TEXT_COLOR ] = tf .TableColors .TEXT_COLOR_RED
142
+ return opts
126
143
127
144
128
145
class TableDisplay (cmd2 .Cmd ):
@@ -131,13 +148,14 @@ class TableDisplay(cmd2.Cmd):
131
148
def __init__ (self ):
132
149
super ().__init__ ()
133
150
134
- def ptable (self , rows , columns , grid_args ):
151
+ def ptable (self , rows , columns , grid_args , row_stylist ):
135
152
"""Format tabular data for pretty-printing as a fixed-width table and then display it using a pager.
136
153
137
154
:param rows: required argument - can be a list-of-lists (or another iterable of iterables), a two-dimensional
138
155
NumPy array, or an Iterable of non-iterable objects
139
156
:param columns: column headers and formatting options per column
140
157
:param grid_args: argparse arguments for formatting the grid
158
+ :param row_stylist: function to determine how each row gets styled
141
159
"""
142
160
if grid_args .color :
143
161
grid = tf .AlternatingRowGrid (BACK_PRI , BACK_ALT )
@@ -148,7 +166,7 @@ def ptable(self, rows, columns, grid_args):
148
166
else :
149
167
grid = None
150
168
151
- formatted_table = tf .generate_table (rows = rows , columns = columns , grid_style = grid )
169
+ formatted_table = tf .generate_table (rows = rows , columns = columns , grid_style = grid , row_tagger = row_stylist )
152
170
self .ppaged (formatted_table , chop = True )
153
171
154
172
table_parser = argparse .ArgumentParser ()
@@ -160,12 +178,12 @@ def ptable(self, rows, columns, grid_args):
160
178
@cmd2 .with_argparser (table_parser )
161
179
def do_table (self , args ):
162
180
"""Display data in iterable form on the Earth's most populated cities in a table."""
163
- self .ptable (EXAMPLE_ITERABLE_DATA , COLUMNS , args )
181
+ self .ptable (EXAMPLE_ITERABLE_DATA , COLUMNS , args , high_density_tuples )
164
182
165
183
@cmd2 .with_argparser (table_parser )
166
184
def do_object_table (self , args ):
167
185
"""Display data in object form on the Earth's most populated cities in a table."""
168
- self .ptable (EXAMPLE_OBJECT_DATA , OBJ_COLS , args )
186
+ self .ptable (EXAMPLE_OBJECT_DATA , OBJ_COLS , args , high_density_objs )
169
187
170
188
171
189
if __name__ == '__main__' :
0 commit comments