user19498579
user19498579

Reputation:

How to align strings in columns(detailed)?

I am sorry for re-asking this but I made the mistake of not providing enough detail. I want to align string and adjust spacing in a column I asked this question.

Here: How to align strings in columns?

But I was not able to apply it to my detailed code which was my mistake for not providing.

My code:

import time
seperator='|'+'-'*33+'|\n'
seperator2='|'+'='*33+'|\n'
end = '|'+'^'*33+'|'
t=['Tuesday','July','2022','03','06']
try:
 with open('time.txt','r') as f: 
    content = f.readlines()
except:
 with open('time.txt','w') as f: 
    f.write('pass')
with open('time.txt','r') as f: 
 content = f.readlines()
if content[0] != '_________________________________\n':
 with open('time.txt','w') as f:
            header= '_'*33+'\n'+\
                    '|Day |Month |Year |Hour |Minute |\n'
            data = (f'|{t[0]} |{t[1]} |{t[2]}'
            f'|{t[3]} |{t[4]} |\n')
            f.write(header+seperator+data+end)
elif content[0] == '_________________________________\n':
 with open('time.txt','r+') as f:
            saved=f.readlines()[:-1]
            f.seek(0)
            data = (f'|{t[0]} |{t[1]} |{t[2]}'
            f'|{t[3]} |{t[4]} |\n')
            f.writelines(saved+[seperator2,data,end]) 

Output in the time.txt file(if it has been ran once):

_________________________________
|Day |Month |Year |Hour |Minute |
|---------------------------------|
|Tuesday |July |2022|03 |06 |
|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^|

Output(twice)(showing this to clarify that the data should be saved and re-printed):


_________________________________
|Day |Month |Year |Hour |Minute |
|---------------------------------|
|Tuesday |July |2022|03 |06 |
|=================================|
|Tuesday |July |2022|03 |06 |
|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^|

The output I want:

_________________________________
|Day |Month |Year |Hour |Minute |
|-------------------------------|
|Tuesday |July |2022|03 |06     |
|===============================|
|Tuesday |July |2022|03 |06     |
|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^|

The post I made at first is here: How to align strings in columns?

The one I didn't detail my post in maybe you could read the question I asked their and the answers.

Sorry for not adding detail the first time.

Any help would be appreciated, Thanks.

Upvotes: 1

Views: 115

Answers (2)

constantstranger
constantstranger

Reputation: 9389

Though there may be alternative approaches that will save you some effort if you don't mind parsing the entire existing file (pandas, tabulate, etc.), here's a strategy specific to your datetime data and your approach of appending to an arbitrary number of rows of existing data (which requires that the existing data is already in a predetermined format consistent with the row to be appended) that will ensure field labels, fields and separators are all aligned:

import calendar

def appendDatetimeToFile(t, fname='time.txt'):
    labels = ['Day', 'Month', 'Year', 'Hour', 'Minute']
    maxDayLen = len(max(calendar.day_name, key=len))
    maxMonthLen = len(max(calendar.month_name, key=len))
    fieldLens = [maxDayLen + 1, maxMonthLen + 1, 5, 3, 3]
    fieldLens = [max(fieldLens[i], len(labels[i])) for i in range(len(labels))]

    def makeLineFromFields(fields):
        toEval = [f'f"{{\'{fields[i]}\':{fieldLens[i] + 1}}}"' for i in range(len(fields))]
        return '|'.join([''] + [eval(toEval[i]) for i in range(len(fields))] + ['\n'])

    def makeSeparator(c, border=None):
        border = border if border else c
        return ''.join([border] + [c] * (sum(fieldLens) + 2 * len(fieldLens) - 1) + [border] + ['\n'])
    labelsHeader = makeSeparator('_')
    labelsFooter = makeSeparator('-', '|')
    dataSeparator = makeSeparator('=', '|')
    dataFooter = makeSeparator('^', '|')

    data = makeLineFromFields(t)

    try:
        with open('time.txt','r') as f: 
            content = f.readlines()
    except:
        with open('time.txt','w') as f: 
            f.write('pass')
    with open('time.txt','r') as f: 
        content = f.readlines()
    if content[0] != labelsHeader:
        with open('time.txt','w') as f:
            header = labelsHeader + makeLineFromFields(labels) + labelsFooter
            f.write(header + data + dataFooter)
    else:
        with open('time.txt','r+') as f:
            saved = f.readlines()[:-1]
            f.seek(0)
            f.writelines(saved +[dataSeparator, data, dataFooter]) 

t=['Tuesday','July','2022','03','06']
appendDatetimeToFile(t)

Output if file doesn't exist:

______________________________________________
|Day        |Month      |Year  |Hour |Minute |
|--------------------------------------------|
|Tuesday    |July       |2022  |03   |06     |
|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^|

Output if file exists with one row:

______________________________________________
|Day        |Month      |Year  |Hour |Minute |
|--------------------------------------------|
|Tuesday    |July       |2022  |03   |06     |
|============================================|
|Tuesday    |July       |2022  |03   |06     |
|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^|

Upvotes: 1

pterodactella
pterodactella

Reputation: 121

As someone already mentioned, if you want the print statement to look exactly like the dashed table you should use tabulate

I guess if you use tabulate there should be a cleaner way of parsing the .txt file, here is an example on how to use tabulate

table = tabulate(rows, headers=["Day","Month","Year", "Hour","Minute"])

Where rows is a list of lists or another tabular data type.

Upvotes: 3

Related Questions