I wanted to write a quick post to document how to format nice columns in Python. Mainly I want to remember this myself and if I put it on my blog, I can find it quickly. There are probably better posts out there but so be it.
If you have read my other posts, you will realize that I am command line oriented. Yes, I know that makes me a dinosaur. ??? My two main GitHub repositories are command line scripts. PythonDBAGraphs displays graphs but you run it from the command line. OracleDatabaseTuningSQL is a collection of SQL*Plus scripts that I run from the command line. Typically I work on my Windows 10 laptop running the Windows version of command line SQL*Plus in a command prompt window. Some of the SQL*Plus scripts like tablestats.sql use the column command to format query output in nicely sized columns:
The column commands just trim owner to 20 characters and table_name to 30 to format the output nicely.
Since I am not a professional application developer and since programming is not my primary task, I tend to learn just enough of something to get by. In the C language that I learned in college around 1984 – eons ago – I know that there is a formatted print command printf that will do all kinds of fancy output. But I just use it in the most basic way such as:
printf("%s is a string.\n",mystringvariable);%s is for strings, %d integers, %f floats – simple. But you can format columns nicely if you need to. I recently did a little formatted output for a Nethack code modification that I played with. In my hacked version of the delivered files.c I put some commands to print out some debugging information in column format(edited for clarity):
fprintf(fptr,"\nInventory Letter     Object Type or Name                     Priority\n");
fprintf(fptr,"---------------------------------------------------------------------\n");
for (i = 0; i < num_autoletter ; i++) {
    fprintf(fptr,"%c                    %-40s    %4d \n",letter, object_type_or_name, priority);
}The output looks something like this:
Inventory Letter     Object Type or Name                     Priority
---------------------------------------------------------------------
b                    blindfold                                      1
l                    magic lamp                                     1
l                    lamp                                           2
l                    oil lamp                                       2
l                    brass lantern                                  2
k                    key                                            1
This is just a game, but the point is that I needed to line up the output in columns. %-40s and %4d were the C formatting strings that I can never remember and had to look up for that situation, but they did the job. So, the question is how to do the same in Python?
Usually in Python I just use the print() command and pass it a string that I construct. For example:
Python 3.8.3 (tags/v3.8.3:6f8c832, May 13 2020, 22:20:19) [MSC v.1925 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> i = 5
>>> print("i = "+str(i))
i = 5
>>>I use the str() function to convert numbers to strings and the concatenation operator + to combine strings. Then I pass the full string to print(). Easy and good enough for basic output that does not need to be formatted into columns or otherwise. But I know there is a Python equivalent to C’s printf formats, but it just is not in the forefront of my mind. I have to look it up to use it. I recently did that for a Rosetta Code example program. The output was supposed to look like this:
Name     Bits  Start  End
=======  ====  =====  ===
ID         16      0   15
QR          1     16   16
Opcode      4     17   20
AA          1     21   21
TC          1     22   22
RD          1     23   23
RA          1     24   24
Z           3     25   27
RCODE       4     28   31
QDCOUNT    16     32   47
ANCOUNT    16     48   63
NSCOUNT    16     64   79
ARCOUNT    16     80   95Here is the code to print this formatted output (simplified):
print("Name     Bits  Start  End")
print("=======  ====  =====  ===")
for line in lines:
    print('{0:7}    {1:2d}     {2:2d}   {3:2d}'.format(name, bits, startbit, endbit))
I guess the 0:, 1:, 2:, 3: numbers represent the arguments to the format method of the type str. A regular string like “Hello World” is of type str in Python.
>>> type("asdfa")
<class 'str'>
>>>:7 seems to just say that this is a string and stick the string in a 7-character width column. :2d seems to say that this is an integer and stick it in a two-character column. The spaces between the {} bracketed format strings line up the columns. I know this is a simple example.
There are a lot of nice web pages out there. This is from the tutorial:
7.1.2. The String format() Method
This seems to be from the reference:
Crazily complex examples:
There is a lot of great Python help on print formatting on Stack Overflow. I had a great post that I wanted to link in but could not find it.
Anyway, this is not a database post, but I use Python in my Oracle database work and wanted to do a quick post for my own reference if nothing else.
Bobby
 
			