Skip to main content

Create a table like output using Python in Terminals

Often times in the terminal, output from a program needs to be presented in tabular format. While many programming languages provide formatted printing, customizing the table printing to each use case could be tedious at times. In this article, a generic approach to printing tables on the terminal or command line using Python is discussed.

Environment 

The code presented in this article is developed and executed using the tools listed below,

  • Operating System - Windows 11
  • IDE - JetBrains PyCharm
  • Python version - 3.12.0 

We will start by defining a class called Table, and build the needed methods within the table. Once the class is defined, multiple objects can be spawned using the same class, hence each object of the class could be viewed as a separate table on its own, and object may be modified and output independently.

The class contains the following fields,

  • list of headers (these act as table headers, 1 for each column)
  • list of rows (data rows) - number of columns
  • length of the row (computed based on the number of columns)


The Table class, however, comes with a few restrictions to make the code simpler. These restrictions become part of the validations, and a corresponding exception is thrown in case of such violations. Some of the validations are,

  • can not add columns to a non-empty table
  • can not add rows which has number of columns more than the configured columns
  • column alignment could only be either left or right

First, the class is defined and all the methods described later in this article go within the class.

class Table:


During the object initialization, the object specific fields in the table are given a default value.

def __init__(self):
    self.headers = []
    self.rows = []
    self.num_cols = 0
    self.row_len = 0

The first method in the class is to add a column. The columns have to be configured in place before any data could be added inside the table. The method takes column name, maximum length of the column (i.e., column width) and an alignment option. The method validates the inputs, adds the header if inputs are valid and then updates the row length. The total number of columns is also kept track for the object.
def add_column(self, name, length, alignment="left"):
    self.validate(alignment)
    column = {
        "value": name,
        "length": length,
        "alignment": alignment.lower(),
    }
    self.headers.append(column)
    self.row_len += length
    self.num_cols += 1

The next method in the class is the validator for the column, - it prevents adding a column to a table which already has data (and), - validates the alignment input to be one of either "left" or "right"
def validate(self, alignment):
    if len(self.rows) != 0:
        raise ValueError("Can not add columns to table with existing data")

    if alignment.lower() not in ["left", "right"]:
        raise ValueError("Invalid value for alignment, expected only 'left' or 'right'")

The next method in the class is to add a given row, the input for the method is a list of data, equal to the number of columns configured. If the input data does not have all the columns or has additional columns, an exception will be raised.
def add_row(self, row):
    if len(row) != self.num_cols:
        raise ValueError("Length of input row does not match with number of columns")
    self.rows.append(row)

The next set of methods are for printing the table,

  • print_line is used to print a horizontal line in the terminal using hyphens
  • print_row is used to print the data for a given row, each row data is separated by a pipe ('|')
  • print_header is used to print the header row
  • print_table prints the header, rows in a nice format

To note, some of these print methods also take care of the alignment.

def print_line(self):
    computed_len = self.row_len + (1 + self.num_cols * 3) - 2
    print(f"+{'-' * computed_len}+")

def print_row(self, row):
    for i, element in enumerate(row):
        if self.headers[i]["alignment"] == "left":
            print(f"| {element:{self.headers[i]["length"]}} ", end="")
        else:
            print(f"| {element:>{self.headers[i]["length"]}} ", end="")
    print("|")

def print_header(self):
    self.print_line()
    for element in self.headers:
        if element["alignment"] == "left":
            print(f"| {element["name"]:{element["length"]}} ", end="")
        else:
            print(f"| {element["name"]:>{element["length"]}} ", end="")
    print("|")
    self.print_line()

def print_table(self):
    self.print_header()
    for row in self.rows:
        self.print_row(row)
    self.print_line()

Finally, some test code to see the Table in action.
table = Table()
table.add_column("ID", 4, "right")
table.add_column("Name", 16, "left")
table.add_column("Salary", 8, "right")
table.add_column("Commission", 10, "right")

table.add_row([1001, "Gabriel", 9000, 700])
table.add_row([1002, "Elizabeth", 9500, 1250])
table.add_row([1003, "Wilson", 10500, 925])
table.add_row([1004, "Frankenstein", 8500, 1500])
table.add_row([1005, "Stephanie", 12000, 800])
table.print_table()

Running the test code will yield the below output,
+-------------------------------------------------+
|   ID | Name             |   Salary | Commission |
+-------------------------------------------------+
| 1001 | Gabriel          |     9000 |        700 |
| 1002 | Elizabeth        |     9500 |       1250 |
| 1003 | Wilson           |    10500 |        925 |
| 1004 | Frankenstein     |     8500 |       1500 |
| 1005 | Stephanie        |    12000 |        800 |
+-------------------------------------------------+

Thanks for reading. Please share any suggestions or errors through the comment section below.

Comments

Popular posts from this blog

BMI Calculator using Python and Tkinter

Body Mass Index can be calculated using a simple formula kg/m 2 , where the weight is represented in kilograms (kg) and the height is represented in metres (m). The article presents code to create a simple GUI to calculate BMI based on user input values. The GUI is implemented using tkinter and tkinter.ttk libraries in Python language.

Tic-tac-toe game using Python and tkinter

Tic-tac-toe is a popular two player game where each player tries to occupy an empty slot in a 3x3 board until one of them wins or the entire board is filled without any winner. The winner has to occupy three continuous cells in any direction, including the two diagonals. In this article, a version of the tic-tac-toe game is coded using Python and tkinter library.

Using hilite.me API in Python

hilite.me is a light weight website made by Alexander Kojevnikov , used to format source code from various programming languages into formatted HTML snippets which can be added to blogs, articles, and other web pages as needed. I personally use the API to format the source code snippets in this blog, and it has greatly reduced the time taken to complete an article, much thanks to the creator. In this article, an automated way of using the hilite.me API through Python and a simple HTML document is created with formatted code snippets.

Double ended queue (deque) in C

A double-ended queue, pronounced deque in short is a LIFO queue where entries can be pushed and popped at both the ends of the queue, apart from push and pop an additional peek method is also discussed which fetches the value at either ends without removing it. In this article, one such queue is implemented using the C language.