struggling
struggling

Reputation: 111

How to print a message box in python?

I'm trying to print out a message within a created box in python, but instead of it printing straight down, it prints horizontally.

def border_msg(msg):
    row = len(msg)
    columns = len(msg[0])
    h = ''.join(['+'] + ['-' *columns] + ['+'])
    result = [h] + ["|%s|" % row for row in msg] + [h]
    return result

Expected result

border_msg('hello')

+-------+
| hello |
+-------+

but got

['+-+', '|h|', '|e|', '|l|', '|l|', '|o|', '+-+'].

Upvotes: 6

Views: 14024

Answers (3)

Darkonaut
Darkonaut

Reputation: 21654

Here's a mildly elaborated function for printing a message-box with optional title and indent which centers around the longest line:

def print_msg_box(msg, indent=1, width=None, title=None):
    """Print message-box with optional title."""
    lines = msg.split('\n')
    space = " " * indent
    if not width:
        width = max(map(len, lines))
    box = f'╔{"═" * (width + indent * 2)}╗\n'  # upper_border
    if title:
        box += f'║{space}{title:<{width}}{space}║\n'  # title
        box += f'║{space}{"-" * len(title):<{width}}{space}║\n'  # underscore
    box += ''.join([f'║{space}{line:<{width}}{space}║\n' for line in lines])
    box += f'╚{"═" * (width + indent * 2)}╝'  # lower_border
    print(box)

Demo:

print_msg_box('\n~ PYTHON ~\n')
╔════════════╗
║            ║
║ ~ PYTHON ~ ║
║            ║
╚════════════╝
print_msg_box('\n~ PYTHON ~\n', indent=10)
╔══════════════════════════════╗
║                              ║
║          ~ PYTHON ~          ║
║                              ║
╚══════════════════════════════╝
print_msg_box('\n~ PYTHON ~\n', indent=10, width=20)
╔════════════════════════════════════════╗
║                                        ║
║          ~ PYTHON ~                    ║
║                                        ║
╚════════════════════════════════════════╝
msg = "And I thought to myself,\n" \
      "'a little fermented curd will do the trick',\n" \
      "so, I curtailed my Walpoling activites, sallied forth,\n" \
      "and infiltrated your place of purveyance to negotiate\n" \
      "the vending of some cheesy comestibles!"

print_msg_box(msg=msg, indent=2, title='In a nutshell:')
╔══════════════════════════════════════════════════════════╗
║  In a nutshell:                                          ║
║  --------------                                          ║
║  And I thought to myself,                                ║
║  'a little fermented curd will do the trick',            ║
║  so, I curtailed my Walpoling activites, sallied forth,  ║
║  and infiltrated your place of purveyance to negotiate   ║
║  the vending of some cheesy comestibles!                 ║
╚══════════════════════════════════════════════════════════╝

Upvotes: 16

Michael DiStefano
Michael DiStefano

Reputation: 594

The above answers are good if you only want to print one line, however, they break down for multiple lines. If you want to print multiple lines you can use the following:

def border_msg(msg):
    l_padding = 2
    r_padding = 4

    msg_list = msg.split('\n')
    h_len = max([len(m) for m in msg]) + sum(l_padding, r_padding)
    top_bottom = ''.join(['+'] + ['-' * h_len] + ['+'])
    result = top_bottom

    for m in msg_list:
        spaces = h_len - len(m)
        l_spaces = ' ' * l_padding
        r_spaces = ' ' * (spaces - l_padding)
        result += '\n' + '|' + l_spaces + m + r_spaces + '|\n'

    result += top_bottom
    return result

This will print a box around a multi-line string that is left-aligned with the specified padding values determining the positioning of the text in the box. Adjust accordingly.

If you would like to center the text, just use one padding value and interleave half of the spaces value from the spaces = h_len - len(m) line between the pipes.

Upvotes: 1

R__raki__
R__raki__

Reputation: 975

When you use list comprehension you get the output as list , as seen by your output, to see the new line character you need to print the result

And also you are using columns to multiply - which is only one for all strings. Change it to `row'

def border_msg(msg):
    row = len(msg)
    h = ''.join(['+'] + ['-' *row] + ['+'])
    result= h + '\n'"|"+msg+"|"'\n' + h
    print(result)

Output

>>> border_msg('hello')
+-----+
|hello|
+-----+
>>> 

Upvotes: 5

Related Questions