{"id":820,"date":"2015-01-23T14:19:52","date_gmt":"2015-01-23T22:19:52","guid":{"rendered":"http:\/\/blog.ls-al.com\/?p=820"},"modified":"2015-01-24T06:04:39","modified_gmt":"2015-01-24T14:04:39","slug":"python-output-align-by-column","status":"publish","type":"post","link":"https:\/\/blog.ls-al.com\/python-output-align-by-column\/","title":{"rendered":"Python Output Align by Column"},"content":{"rendered":"
I have used several ways in the past to have very simple column headers and subsequent output lines line up. Of course everything can be static but I like to have column headers adjust their size based on some of the data.<\/p>\n
For example if I have column headers in an array like this:
\nheader = ['File Name','File Size']<\/p>\n
I want to use this array to print the header line but before printing it I want to adjust the column width for 'File Name' to the longest file name that is in the list yet to be processed. The following example is one way of doing it.<\/p>\n
I played with other options also(see update 01.24.15 below).<\/p>\n
Honestly I think the main reason for doing it dynamically is I like to print the headers and data with minimal lines of code.<\/p>\n
\r\n#!\/usr\/bin\/env python\r\nimport os,glob,sys\r\nFORMAT = [('File Name',10),('Size',12)]\r\n\r\n## In a real use case this function will probably do a lot more\r\n## for example MB to GB conversions etc.\r\n## But important here is where I make the adjustment to the main array\r\n## to stretch the 'File Name' field.\r\ndef makeEntry(fileN,fileS):\r\n global FORMAT\r\n entry = []\r\n entry = [fileN, fileS]\r\n\r\n if len(fileN) > FORMAT[0][1]:\r\n n = dict(FORMAT)\t\t\t# tuples are immutable so have to change to something writeable\r\n n['File Name'] = len(fileN) + 2\t# expanding field width\r\n FORMAT = n.items()\t\t\t# overwrite original\r\n\r\n return entry\r\n\r\nos.chdir('\/DATA\/')\r\nvideo_files = []\r\nfor files in ('*.m4v', '*.mp4', '*.ts','*.dvr-ms','*.avi','*.mkv'):\r\n video_files.extend(glob.glob(files))\r\n\r\n## Loop through files and build an array\r\nfArr = []\r\nfor fileN in video_files:\r\n fArr.append(makeEntry(fileN, os.path.getsize(fileN)))\r\n\r\n## Print header\r\nfor item in FORMAT:\r\n print "{header:{width}}".format (header=item[0], width=item[1]),\r\nprint\r\n\r\n## Print entries\r\nfor entry in fArr:\r\n #print ("%-" + str(FORMAT[0][1]) + "s %-" + str(FORMAT[1][1]) + "s") % (entry[0], entry[1])\t\t# old style\r\n print "{f0:{w0}} {f1:{w1}}".format ( f0=entry[0], w0=FORMAT[0][1], f1=entry[1], w1=FORMAT[1][1] )\t# new style\r\n<\/pre>\nUpdate 01.24.15<\/strong><\/span>
\nAbove example is fine except I did not like the way I updated the tuple. Below example use a dict for the header.<\/p>\n\r\n#!\/usr\/bin\/env python\r\nimport os,glob,sys\r\n\r\nFORMAT = {'File Name':10,'Size':12} \r\n\r\ndef makeEntry(fileN,fileS):\r\n global FORMAT\r\n entry = []\r\n entry = [fileN, fileS]\r\n if len(fileN) > FORMAT['File Name']:\r\n FORMAT['File Name'] = len(fileN) + 2\t# expanding field width\r\n return entry\r\n\r\nos.chdir('\/DATA\/')\r\nvideo_files = []\r\nfor files in ('*.m4v', '*.mp4', '*.ts','*.dvr-ms','*.avi','*.mkv'):\r\n video_files.extend(glob.glob(files))\r\n\r\nfArr = []\r\nfor fileN in video_files:\r\n fArr.append(makeEntry(fileN, os.path.getsize(fileN)))\r\n\r\n## Print header.\r\nprint "{header:{width}}".format (header='File Name', width=FORMAT['File Name']),\r\nprint "{header:{width}}".format (header='Size', width=FORMAT['Size'])\r\nprint\r\n\r\nfor entry in fArr:\r\n print "{f0:{w0}} {f1:{w1}}".format ( f0=entry[0], w0=FORMAT['File Name'], f1=entry[1], w1=FORMAT['Size'] )\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"I have used several ways in the past to have very simple column headers and subsequent output lines line up.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[13],"tags":[],"class_list":["post-820","post","type-post","status-publish","format-standard","hentry","category-python"],"_links":{"self":[{"href":"https:\/\/blog.ls-al.com\/wp-json\/wp\/v2\/posts\/820","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.ls-al.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.ls-al.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.ls-al.com\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.ls-al.com\/wp-json\/wp\/v2\/comments?post=820"}],"version-history":[{"count":0,"href":"https:\/\/blog.ls-al.com\/wp-json\/wp\/v2\/posts\/820\/revisions"}],"wp:attachment":[{"href":"https:\/\/blog.ls-al.com\/wp-json\/wp\/v2\/media?parent=820"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.ls-al.com\/wp-json\/wp\/v2\/categories?post=820"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.ls-al.com\/wp-json\/wp\/v2\/tags?post=820"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}