Click here to Skip to main content
15,885,278 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I want to print custom format but am facing an issue with alignment
This is my code:
Python
import os
def has_data(file_name, res1=True):
    if not os.path.exists(file_name):
        res1 = False
    else:
        with open(file_name) as f:
            if not f.read():
                res1 = False
    return res1
def solution(file_name="data.txt"):
    header = ['test123', 'test12345', 'test123', 'test12345']
    data = ['test12345', 'test123', 'test123', 'test12345'] 
    if not has_data(file_name):
        contents = ["____________________________________________________"]
        contents.append("|" + "|".join(header) + "|")
        contents.append("|" + "--------------------------------------------------" + "|")
        contents.append("|" + "|".join(data) + "|")
        contents.append("|" + "^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^" + "|")
        with open(file_name, "w") as f:
            f.write("\n".join(contents))
    else:
        with open(file_name) as f:
            contents = f.readlines()[:-1]
            contents.append("|" + "==================================================" + "|")
            contents.append("|" + "|".join(data) + "|")
            contents.append("|" + "^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^" + "|")

            with open(file_name, "w") as f2:
                f2.write("\n".join(contents))
solution()

by the way ^ is our end separator and should only appear at the end of the data = is our data separator and goes between data and - is our header separator between header and data
I want it so that if I run the file once the header and the data align and if I run it again with different length data it looks at header and all old data and aligns with it by adding or removing spaces and also align the length of the separators and end

The output I get when I run the code once while the data being
Python
data = ['test12345', 'test123', 'test123', 'test12345'] 


Python
____________________________________________________
|test123|test12345|test123|test12345|
|--------------------------------------------------|
|test12345|test123|test123|test12345|
|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^|


The output I get when I run the code twice while the data being
Python
data = ['test12345', 'test12345678', 'test12345678', 'test12345']

____________________________________________________

|test123|test12345|test123|test12345|

|--------------------------------------------------|

|test12345|test123|test123|test12345|

|==================================================|
|test12345|test12345678|test12345678|test12345|
|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^|

But the output I want when I run it for the first time:
Python
____________________________________________________
|test123  |test12345|test123|test12345             |#header
|--------------------------------------------------|
|test12345|test123  |test123|test12345             |#newest data
|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^|


And for the second time:

But the output I want when I run it for the first time:
Python
____________________________________________________
|test123  |test12345   |test123     |test12345     |#header
|--------------------------------------------------|
|test12345|test123     |test123     |test12345     |#old data
|==================================================|
|test12345|test12345678|test12345678|test12345     |#newest data
|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^|


If you dont understand me well say so and I will try to explain in more detail + any help would be appreciated thanks

What I have tried:

I tried:

Python
import os


def align_column(items, length):
    res = []
    for index, item in enumerate(items):
        item_length = len(item)
        if item_length < length[index]:
            res.append(item + " " * (length[index] - item_length))
        else:
            res.append(item)
    return "|" + "|".join(res) + "|"

def has_data(file, res1=True):
    if not os.path.exists(file):
        res1 = False
    else:
        with open(file) as f:
            if not f.read():
                res1 = False
    return res1
def solution(file_name="data.txt"):
    header = ['test123', 'test12345', 'test123', 'test12345']
    data = ['test12345', 'test12345678', 'test12345678', 'test12345'] 
    length = [len(max(item, key=len)) for item in zip(header, data)]   
    length_total = sum(length) + len(length) + 1   
    if not has_data(file_name):  
        contents = ["_" * length_total]
        contents.append(align_column(header, length))
        contents.append("|" + "-" * (length_total - 2) + "|")
        contents.append(align_column(data, length))
        contents.append("|" + "^" * (length_total - 2) + "|")

        with open(file_name, "w") as f:
            f.write("\n".join(contents))
    else:
        with open(file_name) as f:
            contents = f.readlines()[:-1]

            contents.append("|" + "=" * (length_total - 2))
            contents.append(align_column(data, length))
            contents.append("|" + "^" * (length_total - 2))

            with open(file_name, "w") as f2:
                f2.write("\n".join(contents))


solution()



But it only aligned the first piece of data with the header only but the rest of the data / new data it wouldn't align and I tried mixing it with the else statement but it wouldn't work
Posted
Updated 16-Jul-22 1:55am
v2

You need to first calculate how wide you want each of your columns. You can then use any of the formatting options as described at https://docs.python.org/3.10/tutorial/inputoutput.html[^]. The key is to use the same format controls for the headers as for the actual data.
 
Share this answer
 
Comments
0x01AA 16-Jul-22 9:40am    
'The key is to use the same format controls for the headers as for the actual data' -> 5
Richard MacCutchan 16-Jul-22 10:13am    
Thank you; points for stating the obvious. :)
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900