def live(ctx: click.Context, **args: str) -> None: """ Show live departures and arrivals for a train station. \b Examples: locomotive live "Paris Montparnasse" """ stations = ctx.obj["stations"] station = stations.find_or_raise(args["station"]) client = Client(stations) dep_gs = None arr_gs = None if args["color"]: dep_gs = tf.AlternatingRowGrid(bg(25), bg(18)) arr_gs = tf.AlternatingRowGrid(bg(34), bg(28)) departures = client.board_request(BoardRequest(station, "departure")) cols = ["Destination", "Number", "Time", "Delay", "Platform"] click.echo(tf.generate_table(get_rows(departures), cols, grid_style=dep_gs)) arrivals = client.board_request(BoardRequest(station, "arrival")) cols = ["Origin", "Number", "Time", "Delay", "Platform"] click.echo(tf.generate_table(get_rows(arrivals), cols, grid_style=arr_gs))
def ptable(self, rows, columns, grid_args, row_stylist): """Format tabular data for pretty-printing as a fixed-width table and then display it using a pager. :param rows: required argument - can be a list-of-lists (or another iterable of iterables), a two-dimensional NumPy array, or an Iterable of non-iterable objects :param columns: column headers and formatting options per column :param grid_args: argparse arguments for formatting the grid :param row_stylist: function to determine how each row gets styled """ if grid_args.color: grid = tf.AlternatingRowGrid(BACK_PRI, BACK_ALT) elif grid_args.fancy: grid = tf.FancyGrid() elif grid_args.sparse: grid = tf.SparseGrid() else: grid = None transpose = False if grid_args.transpose: transpose = True formatted_table = tf.generate_table(rows=rows, columns=columns, grid_style=grid, row_tagger=row_stylist, transpose=transpose) self.ppaged(formatted_table, chop=True)
def test_namedtuple_rows(): expected = ''' ╔══════════════════════╤════════╤═════╤═══════╤════════════╗ ║ │ │ Num │ │ ║ ║ First │ Second │ 1 │ Num 2 │ Multiplied ║ ╠══════════════════════╪════════╪═════╪═══════╪════════════╣ ║ RLonger text that │ RA2 │ R5 │ R56 │ R280 ║ ║ Rwill trigger the │ │ │ │ ║ ║ Rcolumn wrapping │ │ │ │ ║ ║ GB1 │ GB2 │ G23 │ G8 │ G184 ║ ║ │ GB2 │ │ │ ║ ║ │ GB2 │ │ │ ║ ║ C1 │ C2 │ 4 │ 9 │ 36 ║ ║ D1 │ D2 │ 7 │ 5 │ 35 ║ ╚══════════════════════╧════════╧═════╧═══════╧════════════╝ '''.lstrip('\n') rows = [ tf.Row(NamedTupleRow( 'Longer text that will trigger the column wrapping', 'A2', 5, 56), text_color='R'), tf.Row(NamedTupleRow('B1', 'B2\nB2\nB2', 23, 8), text_color='G'), NamedTupleRow('C1', 'C2', 4, 9), NamedTupleRow('D1', 'D2', 7, 5) ] columns = (tf.Column('First', width=20, attrib='field1'), tf.Column('Second', attrib='field2'), tf.Column('Num 1', width=3, attrib='field3'), tf.Column('Num 2', attrib='field4'), tf.Column('Multiplied', obj_formatter=multiply_named_tuple)) table = tf.generate_table(rows, columns) assert table == expected
def test_tuple_rows(): expected = ''' ╔══════════════════════╤════════╤═══════╤═══════════╤════════════╗ ║ First │ Second │ Num 1 │ Num 2 │ Multiplied ║ ╠══════════════════════╪════════╪═══════╪═══════════╪════════════╣ ║ RLonger text that wil │ RA2 │ R5 │ RFifty-six │ R280 ║ ║ GB1 │ GB2 │ G23 │ GEight │ G184 ║ ║ │ GB2 │ │ │ ║ ║ │ GB2 │ │ │ ║ ║ C1 │ C2 │ 4 │ Nine │ 36 ║ ║ D1 │ D2 │ 7 │ Five │ 35 ║ ╚══════════════════════╧════════╧═══════╧═══════════╧════════════╝ '''.lstrip('\n') rows = [ tf.Row('Longer text that will trigger the column wrapping', 'A2', 5, 56, None, text_color='R'), tf.Row('B1', 'B2\nB2\nB2', 23, 8, None, text_color='G'), ('C1', 'C2', 4, 9, None), ('D1', 'D2', 7, 5, None) ] columns = (tf.Column('First', width=20, wrap_mode=tf.WrapMode.TRUNCATE_HARD), tf.Column('Second'), tf.Column('Num 1'), tf.Column('Num 2', formatter=int2word), tf.Column('Multiplied', obj_formatter=multiply_tuple)) table = tf.generate_table(rows, columns) assert table == expected
def test_fmt_tuple_rows(): expected = ''' ╔═══════════╤═══════════════════╤═══════╤═══════════╤════════════╗ ║ First │ Second │ Num 1 │ Num 2 │ Multiplied ║ ╠═══════════╪═══════════════════╪═══════╪═══════════╪════════════╣ ║ │ │ 17 │ Four │ 68 ║ ║ 123.00 B │ 123 │ 5 │ Fifty-six │ 280 ║ ║ 123.00 B │ 123 │ 5 │ Fifty-six │ 280 ║ ║ 12.06 KB │ 12,345 │ 23 │ Eight │ 184 ║ ║ 11.77 MB │ 12,345,678 │ 4 │ Nine │ 36 ║ ║ 1.15 GB │ 1,234,567,890 │ 7 │ Five │ 35 ║ ║ 1.12 TB │ 1,234,567,890,123 │ 7 │ Five │ 35 ║ ╚═══════════╧═══════════════════╧═══════╧═══════════╧════════════╝ '''.lstrip('\n') rows = [(None, None, 17, 4, None), ('123', '123', 5, 56, None), (123, 123, 5, 56, None), (12345, 12345, 23, 8, None), (12345678, 12345678, 4, 9, None), (1234567890, 1234567890, 7, 5, None), (1234567890123, 1234567890123, 7, 5, None)] columns = (tf.Column('First', width=20, formatter=tf.FormatBytes(), cell_halign=tf.ColumnAlignment.AlignRight), tf.Column('Second', formatter=tf.FormatCommas(), cell_halign=tf.ColumnAlignment.AlignRight), tf.Column('Num 1'), tf.Column('Num 2', formatter=int2word), tf.Column('Multiplied', obj_formatter=multiply_tuple)) table = tf.generate_table(rows, columns) assert table == expected
def test_iterable_of_non_iterable_objects(): rows = [MyRowObject(1, 2, 3, 4), MyRowObject(5, 6, 7, 8)] columns = (tf.Column('col1', attrib='field1'), tf.Column('col2', attrib='field2'), tf.Column('col3', attrib='get_field3'), tf.Column('col4', attrib='field4')) table = tf.generate_table(rows, columns) assert table == EXPECTED_WITH_HEADERS
def befe_print_mgt_status(txrx): mgts = befe_get_all_mgts(txrx) cols = mgt_get_status_labels() rows = [] for mgt in mgts: status = mgt.get_status() status[0] = txrx.name + " " + status[0] rows.append(status) print(tf.generate_table(rows, cols, grid_style=DEFAULT_TABLE_GRID_STYLE))
def test_iterable_of_dicts(): d1 = {1: 'a', 2: 'b', 3: 'c', 4: 'd'} d2 = {5: 'e', 6: 'f', 7: 'g', 8: 'h'} iterable_of_dicts = [ OrderedDict(sorted(d1.items(), key=lambda t: t[0])), OrderedDict(sorted(d2.items(), key=lambda t: t[0])) ] table = tf.generate_table(iterable_of_dicts) assert table == EXPECTED_BASIC
def test_basic_sparse_grid(rows): expected = ''' A1 A2 A3 A4 B1 B2 B3 B4 B2 B2 C1 C2 C3 C4 D1 D2 D3 D4 \n \n'''.lstrip('\n') table = tf.generate_table(rows, grid_style=tf.SparseGrid()) assert table == expected
def test_object_table_sparse_grid(obj_rows, obj_cols): expected = ''' A1 A2 A3 A4 B1 B2 B3 B4 B2 B2 C1 C2 C3 C4 D1 D2 D3 D4 \n \n'''.lstrip('\n') table = tf.generate_table(obj_rows, obj_cols, grid_style=tf.SparseGrid()) assert table == expected
def test_table_with_header_transposed_sparse(rows, cols): expected = ''' Col1 A1 B1 C1 D1 Col2 A2 B2 C2 D2 B2 B2 Col3 A3 B3 C3 D3 Col4 A4 B4 C4 D4 \n \n'''.lstrip('\n') table = tf.generate_table(rows, cols, grid_style=tf.SparseGrid(), transpose=True) assert table == expected
def envs_display(env1_path, env2_path, heading, diff_or_similar_list, similar: bool): """Displays the table of similar or different module versions.""" color = Colors.OKGREEN if similar else Colors.WARNING title = "SAME MODULE VERSIONS " if similar else "DIFFERENT MODULE VERSIONS " print(color + title + Colors.END) print(f'{env1_path.split(os.sep)[-1]} - {env1_path}') print(f'{env2_path.split(os.sep)[-1]} - {env2_path}') print(tf.generate_table(diff_or_similar_list, heading))
def befe_print_link_status(links, txrx=None): if len(links) == 0: return cols = links[0].get_status_labels() if txrx is None else links[0].get_txrx_status_labels(txrx) rows = [] for link in links: status = link.get_status() if txrx is None else link.get_txrx_status(txrx) rows.append(status) print(tf.generate_table(rows, cols, grid_style=DEFAULT_TABLE_GRID_STYLE)) # FULL_TABLE_GRID_STYLE
def edit(**kwargs: str) -> None: # FIXME: Compare plan afterwards before submitting. api = priolib.client.APIClient(SERVER_ADDR) try: plan = api.get_plan() except priolib.client.ConnectionError: print(f'Unable to connect to server {SERVER_ADDR}.') return except priolib.client.APIError as exc: print(exc.message) print(exc.details) return opts = parse_display_options('STATUS,TASK,ID') tasks = \ plan.done + \ plan.today + \ plan.todo + \ plan.blocked + \ plan.later cols = task_col_obj(opts) rows = [TaskRowObject.From_task(t) for t in tasks] table = tf.generate_table(rows, cols, grid_style=EditGrid()) message = click.edit(table) if message is None: return p = priolib.model.Plan([], [], [], [], []) for line in message.split('\n')[:-2]: tokens = line.split() print(tokens) status = tokens[0] t = priolib.model.Task( status=status, id_=tokens[-1], ) if status == 'Done': p.done.append(t) if status == 'Today': p.today.append(t) if status == 'Todo': p.todo.append(t) if status == 'Blocked': p.blocked.append(t) if status == 'Later': p.later.append(t) try: api.update_plan(p) except priolib.client.ConnectionError: print(f'Unable to connect to server {SERVER_ADDR}.') return except priolib.client.APIError as exc: print(exc.message) print(exc.details) return
def main(host: str, basicauth: bool): services = get_object(object='services', basicauth=basicauth, host=host) rows = [] for service, data in services.items(): rows.append(IcingaStatus(service, data['state'], data['output'])) print( generate_table(rows, columns, grid_style=FancyGrid(), row_tagger=status_color))
def prbs_status(): cols = ["Link", "RX Usage", "RX Type", "RX MGT", "RX PRBS Mode", "TX PRBS Mode", "PRBS Error Count"] rows = [] links = befe_get_all_links() for link in links: rx_mgt = link.get_mgt(MgtTxRx.RX) tx_mgt = link.get_mgt(MgtTxRx.TX) prbs_err_cnt = link.get_prbs_err_cnt() row = [link.idx, link.rx_usage, rx_mgt.type, rx_mgt.idx, rx_mgt.get_prbs_mode(), tx_mgt.get_prbs_mode(), prbs_err_cnt] rows.append(row) print(tf.generate_table(rows, cols, grid_style=DEFAULT_TABLE_GRID_STYLE))
def test_basic_table(rows): expected = ''' ╔════╤════╤════╤════╗ ║ A1 │ A2 │ A3 │ A4 ║ ║ B1 │ B2 │ B3 │ B4 ║ ║ │ B2 │ │ ║ ║ │ B2 │ │ ║ ║ C1 │ C2 │ C3 │ C4 ║ ║ D1 │ D2 │ D3 │ D4 ║ ╚════╧════╧════╧════╝ '''.lstrip('\n') table = tf.generate_table(rows) assert table == expected
def test_basic_transposed(rows): expected = ''' ╔════╤════╤════╤════╗ ║ A1 │ B1 │ C1 │ D1 ║ ║ A2 │ B2 │ C2 │ D2 ║ ║ │ B2 │ │ ║ ║ │ B2 │ │ ║ ║ A3 │ B3 │ C3 │ D3 ║ ║ A4 │ B4 │ C4 │ D4 ║ ╚════╧════╧════╧════╝ '''.lstrip('\n') table = tf.generate_table(rows, transpose=True) assert table == expected
def test_numpy_record_array(): np_rec_array = np.rec.array([(1, 2., 'Hello'), (2, 3., "World")], dtype=[('foo', 'i4'), ('bar', 'f4'), ('baz', 'U10')]) table = tf.generate_table(np_rec_array) expected = ''' ╔═════╤═════╤═══════╗ ║ foo │ bar │ baz ║ ╠═════╪═════╪═══════╣ ║ 1 │ 2.0 │ Hello ║ ║ 2 │ 3.0 │ World ║ ╚═════╧═════╧═══════╝ '''.lstrip('\n') assert table == expected
def __str__(self): string = Style.BRIGHT + f'FitResult' + Style.NORMAL + f' of\n{self.loss} \nwith\n{self.minimizer}\n' string += tafo.generate_table( [[ color_on_bool(self.converged), format_value(self.edm, highprec=False), format_value(self.fmin) ]], ['converged', 'edm', 'min value'], # grid_style=tafo.SparseGrid() ) string += Style.BRIGHT + "Parameters\n" string += str(self.params) return string
def get_scratched_ticket(self): new_tkt = self.ticket self.ticket = [ strike_through(x) if x in list(set(self.ticket) - set(self.remaining_ticket)) else "\033[1;31m" + str(x) + "\033[1;31m" for x in new_tkt ] np_ticket = np.array(self.ticket) shape = constants.NUMPY_SHAPE[len(self.ticket)] np_ticket = np_ticket.reshape(shape[0], shape[1]) print( tf.generate_table(np_ticket, grid_style=tf.AlternatingRowGrid( BACK_GREEN, BACK_BLUE)))
def test_basic_fancy_grid(rows): expected = ''' ╔════╤════╤════╤════╗ ║ A1 │ A2 │ A3 │ A4 ║ ╟────┼────┼────┼────╢ ║ B1 │ B2 │ B3 │ B4 ║ ║ │ B2 │ │ ║ ║ │ B2 │ │ ║ ╟────┼────┼────┼────╢ ║ C1 │ C2 │ C3 │ C4 ║ ╟────┼────┼────┼────╢ ║ D1 │ D2 │ D3 │ D4 ║ ╚════╧════╧════╧════╝ '''.lstrip('\n') table = tf.generate_table(rows, grid_style=tf.FancyGrid()) assert table == expected
def test_table_with_header_transposed_fancy(rows, cols): expected = ''' ╔══════╦════╤════╤════╤════╗ ║ Col1 ║ A1 │ B1 │ C1 │ D1 ║ ╟──────╫────┼────┼────┼────╢ ║ Col2 ║ A2 │ B2 │ C2 │ D2 ║ ║ ║ │ B2 │ │ ║ ║ ║ │ B2 │ │ ║ ╟──────╫────┼────┼────┼────╢ ║ Col3 ║ A3 │ B3 │ C3 │ D3 ║ ╟──────╫────┼────┼────┼────╢ ║ Col4 ║ A4 │ B4 │ C4 │ D4 ║ ╚══════╩════╧════╧════╧════╝ '''.lstrip('\n') table = tf.generate_table(rows, cols, grid_style=tf.FancyGrid(), transpose=True) assert table == expected
def _commands_plugin_show_all(self, limit: int) -> None: """ Shows all commands """ max_cmd_w, max_out_w = available_max_width_on_screen_for_commands( self.selected_client.max_commands_width, self.selected_client.max_outputs_width) table = tf.generate_table( grid_style=tf.FancyGrid(), columns=['ID', 'Status', 'Created On', 'Command', 'Output'], rows=[ cmd.to_table_list(max_cmd_w, max_out_w) for cmd in self.selected_client.reversed_commands[:limit] ]) self.ppaged(table, chop=True)
def _print_alphabets(alphabets_map: dict) -> None: columns = ['Cypher alphabet'] columns.extend(alphabets_map.keys()) rows = list() for value in itertools.zip_longest(*alphabets_map.values(), fillvalue=None): value_list = list(value) if len(rows) == 0: value_list.insert(0, 'Plain alphabet') else: value_list.insert(0, None) rows.append(tuple(value_list)) #print("") # tableformatter doesn't appear to prevent further bold formatting. logger.info(tableformatter.generate_table(rows, columns) + "\033[0m")
def test_object_table_fancy_grid(obj_rows, obj_cols): expected = ''' ╔══════╤══════╤══════╤══════╗ ║ Col1 │ Col2 │ Col3 │ Col4 ║ ╠══════╪══════╪══════╪══════╣ ║ A1 │ A2 │ A3 │ A4 ║ ╟──────┼──────┼──────┼──────╢ ║ B1 │ B2 │ B3 │ B4 ║ ║ │ B2 │ │ ║ ║ │ B2 │ │ ║ ╟──────┼──────┼──────┼──────╢ ║ C1 │ C2 │ C3 │ C4 ║ ╟──────┼──────┼──────┼──────╢ ║ D1 │ D2 │ D3 │ D4 ║ ╚══════╧══════╧══════╧══════╝ '''.lstrip('\n') table = tf.generate_table(obj_rows, obj_cols, grid_style=tf.FancyGrid()) assert table == expected
def test_object_table_columns_rearranged(obj_rows): cols2 = (tf.Column('Col1', attrib='field3'), tf.Column('Col2', attrib='field2'), tf.Column('Col3', attrib='field1'), tf.Column('Col4', attrib='field4')) expected = ''' ╔══════╤══════╤══════╤══════╗ ║ Col1 │ Col2 │ Col3 │ Col4 ║ ╠══════╪══════╪══════╪══════╣ ║ │ A2 │ A1 │ A4 ║ ║ │ B2 │ B1 │ B4 ║ ║ │ B2 │ │ ║ ║ │ B2 │ │ ║ ║ │ C2 │ C1 │ C4 ║ ║ │ D2 │ D1 │ D4 ║ ╚══════╧══════╧══════╧══════╝ '''.lstrip('\n') table = tf.generate_table(obj_rows, cols2) assert table == expected
def test_truncate_middle_cell_align_bottom(obj_rows): columns = (tf.Column('First', width=20, attrib='field1', wrap_mode=tf.WrapMode.TRUNCATE_MIDDLE), tf.Column('Second', attrib='field2'), tf.Column('Num 1', attrib='get_field3'), tf.Column('Num 2', attrib='field4', cell_valign=tf.ColumnAlignment.AlignBottom), tf.Column('Multiplied', attrib=None, obj_formatter=multiply)) table = tf.generate_table(obj_rows, columns) expected = ''' ╔══════════════════════╤════════╤═══════╤═══════╤════════════╗ ║ First │ Second │ Num 1 │ Num 2 │ Multiplied ║ ╠══════════════════════╪════════╪═══════╪═══════╪════════════╣ ║ Longer t … wrapping │ A2 │ 5 │ 56 │ 280 ║ ║ B1 │ B2 │ 23 │ │ 184 ║ ║ │ B2 │ │ │ ║ ║ │ B2 │ │ 8 │ ║ ║ C1 │ C2 │ 4 │ 9 │ 36 ║ ║ D1 │ D2 │ 7 │ 5 │ 35 ║ ╚══════════════════════╧════════╧═══════╧═══════╧════════════╝ '''.lstrip('\n') assert table == expected
def test_truncate_front_custom_padding_cell_align_right(obj_rows): columns = (tf.Column('First', width=20, attrib='field1', wrap_mode=tf.WrapMode.TRUNCATE_FRONT), tf.Column('Second', attrib='field2', cell_padding=5, cell_halign=tf.ColumnAlignment.AlignRight), tf.Column('Num 1', attrib='get_field3'), tf.Column('Num 2', attrib='field4'), tf.Column('Multiplied', attrib=None, obj_formatter=multiply)) table = tf.generate_table(obj_rows, columns) expected = ''' ╔══════════════════════╤════════════════╤═══════╤═══════╤════════════╗ ║ First │ Second │ Num 1 │ Num 2 │ Multiplied ║ ╠══════════════════════╪════════════════╪═══════╪═══════╪════════════╣ ║ …the column wrapping │ A2 │ 5 │ 56 │ 280 ║ ║ B1 │ B2 │ 23 │ 8 │ 184 ║ ║ │ B2 │ │ │ ║ ║ │ B2 │ │ │ ║ ║ C1 │ C2 │ 4 │ 9 │ 36 ║ ║ D1 │ D2 │ 7 │ 5 │ 35 ║ ╚══════════════════════╧════════════════╧═══════╧═══════╧════════════╝ '''.lstrip('\n') assert table == expected
def test_truncate_hard_field_formatter(obj_rows): columns = (tf.Column('First', width=20, attrib='field1', wrap_mode=tf.WrapMode.TRUNCATE_HARD), tf.Column('Second', attrib='field2'), tf.Column('Num 1', attrib='get_field3'), tf.Column('Num 2', attrib='field4', formatter=int2word), tf.Column('Multiplied', attrib=None, obj_formatter=multiply)) table = tf.generate_table(obj_rows, columns) expected = ''' ╔══════════════════════╤════════╤═══════╤═══════════╤════════════╗ ║ First │ Second │ Num 1 │ Num 2 │ Multiplied ║ ╠══════════════════════╪════════╪═══════╪═══════════╪════════════╣ ║ Longer text that wil │ A2 │ 5 │ Fifty-six │ 280 ║ ║ B1 │ B2 │ 23 │ Eight │ 184 ║ ║ │ B2 │ │ │ ║ ║ │ B2 │ │ │ ║ ║ C1 │ C2 │ 4 │ Nine │ 36 ║ ║ D1 │ D2 │ 7 │ Five │ 35 ║ ╚══════════════════════╧════════╧═══════╧═══════════╧════════════╝ '''.lstrip('\n') assert table == expected