Reputation: 3075
My script needs to print a table while it is crunching some numbers. Its total run time is several hours, and I need it to add more and more rows to the printed table while it is running. I am trying to use PrettyTable, but I am open to other suggestions how else it can be accomplished. Here is an example of what I am trying to do:
from prettytable import PrettyTable
t = PrettyTable(['Name', 'Age'])
t.add_row(['Alice', 24])
print t
#do some work
t.add_row(['Bob', 19])
print t
The outcome that I get is this:
+-------+-----+
| Name | Age |
+-------+-----+
| Alice | 24 |
+-------+-----+
+-------+-----+
| Name | Age |
+-------+-----+
| Alice | 24 |
| Bob | 19 |
+-------+-----+
Is there a way not to print the entire table every time I add a row but print just a new row underneath of what has already been printed? I am trying to get somethig like this:
+-------+-----+
| Name | Age |
+-------+-----+
| Alice | 24 |
+-------+-----+
| Bob | 19 |
+-------+-----+
Left alignment for the first column would be a nice bonus.
Upvotes: 2
Views: 6458
Reputation:
The code below covers all what you have asked for IF you specify enough SPACES in the column names definition to cover the maximal width of all incoming items (thanks to all contributors to this question - I have used all of what came up here in the code provided below):
from __future__ import print_function
from prettytable import PrettyTable
t = PrettyTable(['Name ', ' Age'])
t.align['Name '] = 'l'
t.align[' Age'] = 'r'
t.hrules = 1
t.add_row(['Alice', 24])
print(t)
#do some work
t.add_row(['Bob', 19])
print( "\n".join(t.get_string().splitlines()[-2:]) )
#do some work
t.add_row(['AliceInWonderland', 1019])
print( "\n".join(t.get_string().splitlines()[-2:]) )
Here the output generated by the code above that works also for "AliceInWonderland" being 1019 years old :D :
+---------------------+--------+
| Name | Age |
+---------------------+--------+
| Alice | 24 |
+---------------------+--------+
| Bob | 19 |
+---------------------+--------+
| AliceInWonderland | 1019 |
+---------------------+--------+
Upvotes: 3
Reputation: 5529
You could do something like this:
print "\n".join(t.get_string().splitlines()[-2:])
Replacing the last line of your script with this results in exactly what you want:
+-------+-----+
| Name | Age |
+-------+-----+
| Alice | 24 |
+-------+-----+
| Bob | 19 |
+-------+-----+
As grr says, you can also use t.align['Name'] = 'l'
to left-align the Name column.
+-------+-----+
| Name | Age |
+-------+-----+
| Alice | 24 |
+-------+-----+
| Bob | 19 |
+-------+-----+
Upvotes: 2
Reputation: 16079
You can print the last two rows with:
print t[-2:]
To set the Name
field to be left justified just use the align
style option:
t.align['Name'] = 'l'
print t
+-------+-----+
| Name | Age |
+-------+-----+
| Alice | 24 |
| Bob | 19 |
+-------+-----+
To print a line of +-----+-----+
between each entry set the hrules
style option to 1:
t.hrules = 1
print t
+-------+-----+
| Name | Age |
+-------+-----+
| Alice | 24 |
+-------+-----+
| Bob | 19 |
+-------+-----+
If you don't want the header to print each time you can set the header
style option to False
.
t.header = False
print t
+-------+----+
| Alice | 24 |
+-------+----+
| Bob | 19 |
+-------+----+
There are a couple of good examples that cover what you are asking and more available in the PrettyTable Tutorials Wiki
Upvotes: 1
Reputation: 1590
What you can do is clean the screen before each print and redraw the entire table each time. I think the result would be pretty close to what you describe, to see what it looks like you can try this:
import time
from prettytable import PrettyTable
t = PrettyTable(['Name', 'Age'])
t.add_row(['Alice', 24])
for _ in range(10):
t.add_row(['Alice', 24])
print("\033c")
print(t)
time.sleep(1)
The magic is the print("\033c")
, I'm not sure how portable this is, if it doesn't work you can look the way to clear the terminal for your particular system.
Upvotes: 0