import enum class ExtendedSymbols: class Symbol(enum.Enum): # Correctly differentiating between single and double line symbols TOP_RIGHT_L = '\u2510' # ┐ Single line top right corner BOTTOM_RIGHT_L = '\u2518' # ┘ Single line bottom right corner TOP_LEFT_L = '\u250C' # ┌ Single line top left corner BOTTOM_LEFT_L = '\u2514' # └ Single line bottom left corner RIGHT_T = '\u2524' # ┤ Single line right T LEFT_T = '\u251C' # ├ Single line left T TOP_T = '\u252C' # ┬ Single line top T BOTTOM_T = '\u2534' # ┴ Single line bottom T CROSS = '\u253C' # ┼ Single line cross SINGLE_HORIZONTAL = '\u2500' # ─ Single horizontal line SINGLE_VERTICAL = '\u2502' # │ Single vertical line # Double line versions DOUBLE_TOP_RIGHT_L = '\u2557' # ╗ Double line top right corner DOUBLE_BOTTOM_RIGHT_L = '\u255D' # ╝ Double line bottom right corner DOUBLE_TOP_LEFT_L = '\u2554' # ╔ Double line top left corner DOUBLE_BOTTOM_LEFT_L = '\u255A' # ╚ Double line bottom left corner DOUBLE_RIGHT_T = '\u2563' # ╣ Double line right T DOUBLE_LEFT_T = '\u2560' # ╠ Double line left T DOUBLE_TOP_T = '\u2566' # ╦ Double line top T DOUBLE_BOTTOM_T = '\u2569' # ╩ Double line bottom T DOUBLE_CROSS = '\u256C' # ╬ Double line cross DOUBLE_HORIZONTAL = '\u2550' # ═ Double horizontal line DOUBLE_VERTICAL = '\u2551' # ║ Double vertical line SOLID_BLOCK = '\u2588' # █ Solid block TOP_HALF_BLOCK = '\u2580' # ▀ Top half block BOTTOM_HALF_BLOCK = '\u2584' # ▄ Bottom half block SHADED_BLOCK = '\u2592' # ▒ Shaded block def __getattr__(self, name): try: return self.Symbol[name].value except KeyError: raise AttributeError(f"No such symbol: {name}") # Make ExtendedSymbols an instance so it can be used directly ExtendedSymbols = ExtendedSymbols() def draw_box(msg=None, width=None, height=None, title=None, line_type='single'): # Use extended symbols correctly with Unicode line_char = ExtendedSymbols.SINGLE_HORIZONTAL if line_type == 'single' else ExtendedSymbols.DOUBLE_HORIZONTAL corner_tl = ExtendedSymbols.TOP_LEFT_L if line_type == 'single' else ExtendedSymbols.DOUBLE_TOP_LEFT_L corner_tr = ExtendedSymbols.TOP_RIGHT_L if line_type == 'single' else ExtendedSymbols.DOUBLE_TOP_RIGHT_L corner_bl = ExtendedSymbols.BOTTOM_LEFT_L if line_type == 'single' else ExtendedSymbols.DOUBLE_BOTTOM_LEFT_L corner_br = ExtendedSymbols.BOTTOM_RIGHT_L if line_type == 'single' else ExtendedSymbols.DOUBLE_BOTTOM_RIGHT_L vertical_line = ExtendedSymbols.SINGLE_VERTICAL if line_type == 'single' else ExtendedSymbols.DOUBLE_VERTICAL # Determine width based on message length if not specified if msg and (width is None or height is None): width = max(len(msg), width if width else 0) + 2 # Add padding height = 3 # Minimum box height with top, middle, and bottom # Use default dimensions if none provided if width is None: width = 10 # Default width if height is None: height = 3 # Default minimum height # Draw top border top_border = f"{corner_tl}{line_char * width}{corner_tr}" if title: title_str = f" {title} " title_length = len(title_str) pre_title_length = (width - title_length) // 2 post_title_length = width - title_length - pre_title_length top_border = f"{corner_tl}{line_char * pre_title_length}{title_str}{line_char * post_title_length}{corner_tr}" # Prepare message line or blank lines if msg: message_line = f"{vertical_line} {msg} {vertical_line}" if len(msg) < width - 2: msg = msg + ' ' * (width - 2 - len(msg)) message_line = f"{vertical_line}{msg}{vertical_line}" else: message_line = f"{vertical_line}{' ' * (width)}{vertical_line}" # Draw middle lines middle_lines = (f"{vertical_line}{' ' * width}{vertical_line}\n") * (height - 2) middle_lines = middle_lines[:-1] # Remove the last newline for proper formatting # Draw bottom border bottom_border = f"{corner_bl}{line_char * width}{corner_br}" # Combine all parts box = f"{top_border}\n{message_line}\n{middle_lines}\n{bottom_border}" print(box) def format_arrow(root_symbol=None, line_type='single', length=10): """ Draw an arrow with a specified root symbol, line type, and length. """ symbol_map = { 'L': { 'single': ExtendedSymbols.BOTTOM_LEFT_L, 'double': ExtendedSymbols.DOUBLE_BOTTOM_LEFT_L, }, 'T': { 'single': ExtendedSymbols.LEFT_T, 'double': ExtendedSymbols.DOUBLE_LEFT_T }, '+': { 'single': ExtendedSymbols.CROSS, 'double': ExtendedSymbols.DOUBLE_CROSS } } # Default to a single horizontal line if undefined symbol or line type chosen_symbol = symbol_map.get(root_symbol, {}).get(line_type, '') line_char = ExtendedSymbols.DOUBLE_HORIZONTAL if line_type == 'double' else ExtendedSymbols.SINGLE_HORIZONTAL # Construct the arrow string return chosen_symbol + line_char * length + ">" def draw_arrow(root_symbol=None, line_type='single', length=10): format_arrow_str = format_arrow(root_symbol, line_type, length) print(format_arrow_str)