I need to build a table with the data like this:
┌────────┬───────────┬────────┐
│ ID │ Name │ Age │
├────────┼───────────┼────────┤
│ 1 │ Jonh │ 35 │
├────────┼───────────┼────────┤
│ 2 │ Joseph │ 40 │
└────────┴───────────┴────────┘
I am not allowed use any Python libraries for that. It has to be done from scratch. I found that there are some box drawing unicode characters that I could use to draw the table(https://en.wikipedia.org/wiki/Box-drawing_character). Ex:
print(u'\u250C') -> will print ─
I am lost on how I should approach this problem. Should I print the data and then draw the table around or should I print the complete boxed row by row. Any help is appreciated.
My work so far:
length_list = [len(element) for row in data for element in row]
column_width = max(length_list)
for row in data:
print(u'\u250C' + (u'\u2500'*column_width*len(data[0])) + u'\u2510')
row = "".join(element.ljust(column_width + 2) for element in row)
print(row)
print(u'\u2514' + (u'\u2500'*column_width*len(data[0])) + u'\u2518')
Gives me this:
┌──────────────────┐
ID Name Age
└──────────────────┘
┌──────────────────┐
1 John 35
└──────────────────┘
┌──────────────────┐
2 Joseph 40
└──────────────────┘
Your text-file needs a fixed structure (for example all values are separated by a tabulate or a line break). Then you can use the pd. read_csv method and define the separator by hand with pd. read_csv('yourFileName', sep='yourseperator') .
You're nearly there. You could divide the task into smaller portions and use join()
to make your life easier.
Let's first define some constant characters to improve code readability
char_line = u'\u2500'
char_lcorner_top = u'\u250C'
char_rcorner_top = u'\u2510'
char_lside = u'\u251C'
char_rside = u'\u2524'
char_top = u'\u252C'
char_bot = u'\u2534'
char_cross = u'\u253C'
char_lcorner_bot = u'\u2514'
char_rcorner_bot = u'\u2518'
Now let's write functions to create the lines between rows:
def top_rule(width, ncols):
return char_lcorner_top + char_top.join([char_line * width for i in range(ncols)]) + char_rcorner_top
Explanation:
char_line * width
multiplies the -
character width
times. Let's say width = 4
. This would give four dashes like so: ----
[char_line * width for i in range(ncols)]
creates a list with ncols
items, each of which is ----
.char_top.join(...)
joins the elements of the list with the ┬
character┌
before and ┐
after the string we just created.So top_rule(4, 3)
gives "┌────┬────┬────┐"
Similarly, we can define more functions:
def bot_rule(width, ncols):
return char_lcorner_bot + char_bot.join([char_line * width for i in range(ncols)]) + char_rcorner_bot
def mid_rule(width, ncols):
return char_lside + char_cross.join([char_line * width for i in range(ncols)]) + char_rside
In each row, we have multiple cells to format. Let's write a function to format each row individually.
def fmt_row(row, width, loffset):
return "|" + "|".join([cell.ljust(width - loffset).rjust(width) for cell in row]) + "|"
For each cell in the row, we left-justify the cell text to a length of (width - loffset)
and right-justify it to width
. Then, join with a pipe (|
) and add pipes before and after
Now all we need to do is call the functions we made. Remember we only need to print a single mid_rule
after all rows except the last. After the last row, we need to print a bot_rule
.
num_cols = len(data[0])
length_list = [len(element) for row in data for element in row]
column_width = max(length_list) + 2
print(top_rule(column_width, num_cols))
for row in data[:-1]:
print(fmt_row(row, column_width, 1))
print(mid_rule(column_width, num_cols))
print(fmt_row(data[-1], column_width, 1))
print(bot_rule(column_width, num_cols))
With your data, you should get this:
┌────────┬────────┬────────┐
| ID | Name | Age |
├────────┼────────┼────────┤
| 1 | John | 35 |
├────────┼────────┼────────┤
| 2 | Joseph | 40 |
└────────┴────────┴────────┘
It seems like you've basically got it. The only two minor changes you need to make are
Should I print the data and then draw the table around or should I print the complete boxed row by row.
Printing to the terminal is done row by row. With the basic print()
function in Python, there is no way to go back to a previous row. This means that you have to print the data and the borders as you go.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With