0

I have a function which takes a nested list that I input and writes it into the console in the format that I am after.

def print_table(table):
    longest_cols = [(max(
        [len(str(row[i])) for row in table]) + 2) 
        for i in range(len(table[0]))]
    row_format = "".join(["{:>" + str(longest_col) + "}" 
        for longest_col in longest_cols])
    for row in table:
        print(row_format.format(*row))

How would I modify the function so that it writes the output into an output file?

I attempted this by saying

x = print_table(table)

and then

f.write(x)
f.close()

But all this did is write none into the output file

Any help in this is greatly appreciated. Thank you!

tdelaney
  • 73,364
  • 6
  • 83
  • 116
Dan
  • 55
  • 4
  • This may help... just direct output to a file in append mode: [directing output to a text file](https://stackoverflow.com/questions/36571560/directing-print-output-to-a-txt-file-in-python-3/36571602) – Fubar Apr 08 '20 at 17:44
  • You need a `return row_format` line at the end of a function. if you don't return anything, the result of a function call is `None` – tdelaney Apr 08 '20 at 17:48

2 Answers2

3

When you define a function and call it, you have to use return to assign it to something.
But if its row_format.format(*row) you want to store, open it in the function:

def print_table(table,f):
    longest_cols = [ (max([len(str(row[i])) for row in table]) + 2) for i in range(len(table[0]))]
    row_format = "".join(["{:>" + str(longest_col) + "}" for longest_col in longest_cols])
    for row in table:
        f.write(row_format.format(*row))
    f.close()

Now just call it:

print_table(table,f)

Lets say, you want to add it line by file, then use:

for row in table:
    f.seek(0)
    f.write("\n") #not possible if file opened as byte
    f.write(row_format.format(*row))

Now if you want it your way, try:

def print_table(table):
    longest_cols = [(max(
        [len(str(row[i])) for row in table]) + 2) 
        for i in range(len(table[0]))]
    row_format = "".join(["{:>" + str(longest_col) + "}" 
        for longest_col in longest_cols])
    return '\n'.join(row_format.format(*row) for row in table)

Now call it:

x = print_table(table)
f.write(x)
f.close()
Joshua Varghese
  • 5,082
  • 1
  • 13
  • 34
2

There are lots of ways to solve this, depending on what responsibilities you want your function to have. You could have the function format the table but leave the output to the caller (this may be more generally useful if the caller wants the formatted table to go to different places)

def print_table(table):
    longest_cols = [(max(
        [len(str(row[i])) for row in table]) + 2) 
        for i in range(len(table[0]))]
    for longest_col in longest_cols:
        yield "".join(["{:>" + str(longest_col) + "}" 

with open("foo.txt", "w") as f:
    f.writelines(row + "\n" for row in print_table(table))

Or you could give output responsibility to the function and pass it the output stream you want

import sys

def print_table(table, file=sys.stdout):
    longest_cols = [(max(
        [len(str(row[i])) for row in table]) + 2) 
        for i in range(len(table[0]))]
    row_format = "".join(["{:>" + str(longest_col) + "}" 
        for longest_col in longest_cols])
    for row in table:
        print(row_format.format(*row), file=file)

with open("foo.txt", "w") as f:
    print_table(table, f)
tdelaney
  • 73,364
  • 6
  • 83
  • 116