Last active
August 22, 2021 02:40
-
-
Save SegFaultAX/2e8007d01bd7141390d8 to your computer and use it in GitHub Desktop.
Draw nested ascii tables in Python
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from StringIO import StringIO | |
from operator import attrgetter | |
import textwrap | |
class Node(object): | |
def __init__(self, val=None, *children): | |
self.val = val | |
self.children = list(children) | |
test1 = Node("foo") | |
test2 = Node("foo", Node("bar")) | |
test3 = Node("foo", Node("spam", Node("spam1"), Node("spam2")), | |
Node("eggs", Node("eggs1"), Node("eggs2"))) | |
test4 = Node("", Node("", Node("", Node("", Node("", Node(("suck it", "you", "bitch"))))))) | |
def draw_nested(tree, valfn=attrgetter("val"), childfn=attrgetter("children"), maxwidth=0): | |
def _draw_table(root, prefix, acc): | |
val, children = valfn(root), childfn(root) | |
acc.append((prefix+".", "", "-", False)) | |
if isinstance(val, (list, tuple)): | |
for val in val: | |
acc.append((prefix + "| ", val, " ", True)) | |
elif val: | |
acc.append((prefix+ "| ", val, " ", True)) | |
for child in children: | |
_draw_table(child, prefix + "| ", acc) | |
acc.append((prefix+"'", "", "-", False)) | |
return acc | |
table = _draw_table(tree, "", []) | |
buff = StringIO() | |
if maxwidth <= 0: | |
maxwidth = max(2 * len(prefix) + len(text) for prefix, text, _, _ in table) | |
for prefix, text, fill, is_content in table: | |
if is_content: | |
contentwidth = maxwidth - 2 * len(prefix) | |
lines = textwrap.wrap(text, width=contentwidth) | |
else: | |
lines = [text] | |
for line in lines: | |
fillwidth = maxwidth - 2 * len(prefix) - len(line) | |
buff.write("{}{}{}{}\n".format( | |
prefix, line.encode("utf-8"), fill * fillwidth, prefix[::-1])) | |
return buff.getvalue() | |
lines = draw_nested(test4) | |
print lines |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.---------------. | |
| foo | | |
| .-----------. | | |
| | spam | | | |
| | .-------. | | | |
| | | spam1 | | | | |
| | '-------' | | | |
| | .-------. | | | |
| | | spam2 | | | | |
| | '-------' | | | |
| '-----------' | | |
| .-----------. | | |
| | eggs | | | |
| | .-------. | | | |
| | | eggs1 | | | | |
| | '-------' | | | |
| | .-------. | | | |
| | | eggs2 | | | | |
| | '-------' | | | |
| '-----------' | | |
'---------------' | |
Reddit comment example: | |
.-------------------------------------------. | |
| .---------------------------------------. | | |
| | ingolemo (2/0) | | | |
| | Looks to me like it would be better | | | |
| | to split at the commas and then strip | | | |
| | off the whitespace. Either way, this | | | |
| | would be best accomplished with a | | | |
| | list comprehesion; for line in | | | |
| | gradefile: linelist = | | | |
| | [field.strip() for field in | | | |
| | line.split(',')] # do | | | |
| | something with linelist | | | |
| | .-----------------------------------. | | | |
| | | Blackshirt12 (1/0) | | | | |
| | | So what is a field in this | | | | |
| | | context? This worked for me, but | | | | |
| | | I don't understand why. I haven't | | | | |
| | | used this method before. | | | | |
| | | .-------------------------------. | | | | |
| | | | ingolemo (1/0) | | | | | |
| | | | It's just the name that I | | | | | |
| | | | gave to the variable that | | | | | |
| | | | temporarily holds each of the | | | | | |
| | | | sub-items in | | | | | |
| | | | `line.split(',')`. it's | | | | | |
| | | | analogous to `line` on the | | | | | |
| | | | line above it. | | | | | |
| | | | .---------------------------. | | | | | |
| | | | | zahlman (1/0) | | | | | | |
| | | | | I don't know why you were | | | | | | |
| | | | | downvoted. This is | | | | | | |
| | | | | exactly how I'd do it and | | | | | | |
| | | | | it's perfectly idiomatic | | | | | | |
| | | | | and correct. | | | | | | |
| | | | '---------------------------' | | | | | |
| | | '-------------------------------' | | | | |
| | '-----------------------------------' | | | |
| '---------------------------------------' | | |
| .---------------------------------------. | | |
| | ahnakel (1/0) | | | |
| | Do you just need to remove the last | | | |
| | character? linelist[:-1] should | | | |
| | reference all elements in a list | | | |
| | before the last one. | | | |
| '---------------------------------------' | | |
| .---------------------------------------. | | |
| | pkkid (1/0) | | | |
| | Assuming `gradefile` is a list of 4 | | | |
| | strings as you suggest in your | | | |
| | description, something like the | | | |
| | following should work: # Remove | | | |
| | trailing commas gradefile = | | | |
| | [x.rstrip(",") for x in gradefile] | | | |
| | # Convert one of them to a float | | | |
| | gradefile[3] = float(gradefile[3]) | | | |
| '---------------------------------------' | | |
'-------------------------------------------' | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment