Python – создайте текстовую границу с динамическим размером

Я создаю сценарий командной строки, и я бы хотел, чтобы там было поле…

+--------+
|        |
|        |
|        |
+--------+

… который всегда будет соответствовать его содержимому. Я знаю, как сделать верх и низ, но правая и правая части работают правильно. В каждой строке может быть одна замена строки или 5, а длина этих строк может быть любой от 0 до 80.

Я делал такие вещи, как:

print "|%s|" % (my_string.ljust(80-len(my_string)))

Но черт возьми, какой беспорядок… И это всего лишь одна жестко запрограммированная замена. Я понятия не имею, как сделать его динамическим, скажем, с двумя подписчиками в первой строке, тремя подписчиками во второй строке и 1 подпиской в ​​​​третьей строке (все это в формате столбца).

Итак, для базового примера мне нужно:

+--------+
| 1      |
| 1 2 3  |
| 1 2    |
+--------+

См. также:  как указать python == 3.6.8 для оценщика PyTorch (conda_packages недостаточно)
Понравилась статья? Поделиться с друзьями:
IT Шеф
Комментарии: 5
  1. jtsmith1287

    Я делаю это так:

    def bordered(text):
        lines = text.splitlines()
        width = max(len(s) for s in lines)
        res = ['┌' + '─' * width + '┐']
        for s in lines:
            res.append('│' + (s + ' ' * width)[:width] + '│')
        res.append('└' + '─' * width + '┘')
        return '\n'.join(res)
    

    Таким образом, вы сначала форматируете все свои объекты в text wariable, а затем передаете их через bordered() функцию.

  2. jtsmith1287

    Вы можете использовать модуль curses из стандартной библиотеки Python для Linux и Mac. Также вы можете попробовать библиотеку pygcurse для Mac, Linux и Windows. Кроме того, вы можете прочитать его. Но для простого диалога вы можете использовать следующий код:

    def my_text_frame(string_lst, width=20):
        g_line = "+{0}+".format("-"*(width-2))
        print g_line
        for line in string_lst:
            print "| {0:<{1}} |".format(line, width-4)
        print g_line
    my_text_frame("""Some text
    123456 789
    123""".splitlines())
    

    Выход:

    +------------------+
    | Some text        |
    | 123456 789       |
    | 123              |
    +------------------+
    
  3. jtsmith1287

    Вы можете использовать '*' для полей ширины и точности строкового формата, как описано в этот ответ. Вот пример:

    text = """\
    This is
    a test of the
    column formatting
    system.""".splitlines()
    
    maxlen = max(len(s) for s in text)
    colwidth = maxlen + 2
    
    print '+' + '-'*colwidth + '+'
    for s in text:
        print '| %-*.*s |' % (maxlen, maxlen, s)
    print '+' + '-'*colwidth + '+'
    

    печатает:

    +-------------------+
    | This is           |
    | a test of the     |
    | column formatting |
    | system.           |
    +-------------------+
    
  4. jtsmith1287

    Я опаздываю на вечеринку, но вот моя версия:

    def breakLine(text, wrap=80):
        if len(text) > wrap:
            char = wrap
            while char > 0 and text[char] != ' ':
                char -= 1
            if char:
                text = [text[:char]] + breakLine(text[char + 1:], wrap)
            else:
                text = [text[:wrap - 1] + '-'] + breakLine(text[wrap - 1:], wrap)
            return text
        else:
            return [cleanLine(text)]
    
    def cleanLine(text):
        if text[-1] == ' ':
            text = text[:-1]
        if text[0] == ' ':
            text = text[1:]
        return text
    
    def boxPrint(text, wrap=0):
        line_style = '-'
        paragraph = text.split('\n')
        if wrap>0:
            index = 0
            while index < len(paragraph):
                paragraph[index] = cleanLine(paragraph[index])
                if len(paragraph[index]) > wrap:
                    paragraph = paragraph[:index] + breakLine(paragraph[index]\
                        , wrap) + paragraph[index + 1:]
                index += 1
    
        length = (max([len(line) for line in paragraph]))
        print '+' + line_style * length + '+'
        for line in paragraph:
            print '|' + line + ' ' * (length - len(line)) + '|'
        print '+' + line_style * length + '+'
    
    if __name__ == "__main__":
        text = "Some text comes here to be printed in a box!!!"
        boxPrint(text, 20)
        text = "Title:\nBody lorem ipsum something body\ncheers,"
        boxPrint(text, 20)
        boxPrint(text)
        text = "No Space:\nThisIsATextThatHasNoSpaceForWrappingWhichGetsBrokenUsingDashes"
        boxPrint(text, 20)
    

    Что печатает:

    +--------------------+
    |Some text comes here|
    |to be printed in a  |
    |box!!!              |
    +--------------------+
    +----------------+
    |Title:          |
    |Body lorem ipsum|
    |something body  |
    |cheers,         |
    +----------------+
    +-------------------------------+
    |Title:                         |
    |Body lorem ipsum something body|
    |cheers,                        |
    +-------------------------------+
    +--------------------+
    |No Space:           |
    |ThisIsATextThatHasN-|
    |oSpaceForWrappingWh-|
    |ichGetsBrokenUsingD-|
    |ashes               |
    +--------------------+
    
  5. jtsmith1287

    Вы можете сделать это с помощью tabulate.

    from tabulate import tabulate
    
    text = """
    some words that
    could be dynamic but 
    are currently static
    """
    
    table = [[text]]
    output = tabulate(table, tablefmt='grid')
    
    print(output)
    

    Выход:

    +-----------------------+
    | some words that       |
    | could be dynamic but  |
    | are currently static  |
    +-----------------------+
    
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: