[Python] Why does seqprint not happen after seqinput?

Discussão em 'Python' iniciado por Stack, Janeiro 26, 2025.

  1. Stack

    Stack Membro Participativo

    I am new at python and have a question. I have defined functions seqprint and seqinput (see screenshots), which work perfectly in isolation, but if I try to call seqprint after seqinput (in that order!), it doesn't happen at all, while e.g. print after seqinput works. I am at loss as for why, so any help would be appreciated.

    I was expecting for seqprint to happen normally, as it did before. Copilot led me to trying sys.stdout.flush() between the two, but that doesn't do anything (and should happen anyway due to exit of ChangeTerminalColor?)

    Edit: Ok, didn't know images were a no no, sorry. Here is the code:

    Definitions


    import time
    import shutil
    import pyfiglet as fig
    import prompt_toolkit
    import os
    import re

    from sympy import Interval
    from rich.console import Console
    from rich.text import Text
    from io import StringIO
    from typing import Optional, Any
    from pathlib import Path

    console = Console()

    ...

    def cprint(*args, **kwargs) -> None:
    """
    Print the given arguments to the console.

    Args:
    *args: The arguments to be printed.
    **kwargs: Additional keyword arguments for the print function.

    Returns:
    None
    """
    console.print(*args, **kwargs)

    ...

    def seqprint(
    text: str = "",
    style: str = "",
    duration: float = 2,
    end: str = "",
    newline: bool = True,
    ) -> None:
    """
    Print the given text to the console one character at a time with a specified delay between each character.

    Args:
    text (str): The text to be printed.
    style (str, optional): The style to be applied to the text. Default is an empty string.
    duration (float, optional): The total duration in seconds for printing the text. Default is 2 seconds.
    end (str, optional): The string to be printed at the end. Default is an empty string.
    newline (bool, optional): Whether to print a newline at the end. Default is True.

    Returns:
    None
    """

    for char in text:
    cprint(char, end=end, style=style, highlight=False)
    time.sleep(duration / len(text))

    if newline:
    cprint() # Move to the next line after the text is displayed

    ...

    def seqinput(prompt: str = "", style: str = "bold red", duration: float = 0.5) -> None:
    """
    Displays a styled prompt to the user, temporarily disables input, and then
    waits for user input.

    Args:
    prompt (str): The text to display as a prompt. Default is an empty string.
    style (str): The style to apply to the prompt text. Default is "bold red".
    duration (float): The duration for which the prompt is printed accepting input. Default is 0.5 seconds.

    Returns:
    str: The user input.
    """
    from utils.classes import HideCursor, DisableInput, ChangeTerminalColor

    if prompt:
    with HideCursor(), DisableInput():
    seqprint(text=prompt, style=style, duration=duration, newline=False)
    with ChangeTerminalColor():
    return input()

    Context managers for seqinput


    import utils.helper_functions as hf
    import json
    import os
    import sys
    import termios
    import tty
    import re
    import time


    class HideCursor:
    """
    A context manager class to hide the cursor in the terminal.

    This class uses ANSI escape codes to hide the cursor when entering the context
    and show the cursor when exiting the context.

    Methods
    -------
    __enter__() -> None
    Hides the cursor using ANSI escape code.
    __exit__(exc_type: Optional[type], exc_value: Optional[BaseException], exc_tb: Optional[object]) -> None
    Shows the cursor using ANSI escape code.
    """

    def __str__(self) -> str:
    """
    Return the arguments of the class as a json.dumps dict.
    """
    return json.dumps({}, indent=4)

    def __enter__(self) -> None:
    """
    Enter the runtime context related to this object.

    This method hides the cursor using ANSI escape code.

    Returns:
    None
    """
    sys.stdout.write("\033[?25l")
    sys.stdout.flush()

    def __exit__(
    self,
    exc_type: hf.Optional[type],
    exc_value: hf.Optional[BaseException],
    exc_tb: hf.Optional[object],
    ) -> None:
    """
    Exit the runtime context related to this object.

    This method shows the cursor using ANSI escape code.

    Parameters:
    exc_type (Optional[type]): The exception type, if an exception was raised.
    exc_value (Optional[BaseException]): The exception instance, if an exception was raised.
    exc_tb (Optional[object]): The traceback object, if an exception was raised.

    Returns:
    None
    """
    sys.stdout.write("\033[?25h")
    sys.stdout.flush()


    class DisableInput:
    """
    A context manager class to temporarily disable input and restore it upon exit.

    Attributes
    ----------
    _old_settings : Any
    The previous input settings before disabling input.

    Methods
    -------
    __init__(old_settings: Any) -> None
    Initializes the DisableInput instance with the given old settings.
    __str__() -> str
    Returns the arguments of the class as a JSON-formatted string.
    __enter__() -> None
    Disables input and stores the old settings.
    __exit__(exc_type: Optional[type], exc_value: Optional[BaseException], exc_tb: Optional[object]) -> None
    Restores the old input settings and flushes the input
    buffer.
    disable_input() -> tcgetattr
    Disables terminal input.
    enable_input(old_settings: tcgetattr) -> None
    Enables terminal input.
    flush_input() -> None
    Flushes the input buffer.
    """

    def __init__(self, old_settings: hf.Any = None) -> None:
    self._old_settings = old_settings

    def __str__(self) -> str:
    """
    Return the arguments of the class as a json.dumps dict.
    """
    return json.dumps(
    {
    "old_settings": self._old_settings,
    },
    indent=4,
    )

    def __enter__(self) -> None:
    """
    Enter the runtime context related to this object.

    This method saves the current input settings and disables input.

    Returns:
    None
    """
    self._old_settings = self.disable_input()

    def __exit__(
    self,
    exc_type: hf.Optional[type],
    exc_value: hf.Optional[BaseException],
    exc_tb: hf.Optional[object],
    ) -> None:
    """
    Exit the runtime context related to this object.

    This method restores the old input settings and flushes the input buffer.

    Parameters:
    exc_type (Optional[type]): The exception type, if an exception was raised.
    exc_value (Optional[BaseException]): The exception instance, if an exception was raised.
    exc_tb (Optional[object]): The traceback object, if an exception was raised.

    Returns:
    None
    """
    self.flush_input() # Flush the input buffer
    self.enable_input(self._old_settings)

    @staticmethod
    def disable_input() -> termios.tcgetattr:
    """
    Disable terminal input.
    """
    fd = sys.stdin.fileno()
    old_settings = termios.tcgetattr(fd)
    tty.setcbreak(fd)
    return old_settings

    @staticmethod
    def enable_input(old_settings: termios.tcgetattr) -> None:
    """
    Enable terminal input.
    """
    fd = sys.stdin.fileno()
    termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)

    @staticmethod
    def flush_input() -> None:
    """
    Flush the input buffer.
    """
    fd = sys.stdin.fileno()
    termios.tcflush(fd, termios.TCIFLUSH)


    class ChangeTerminalColor:
    """
    A context manager class to change the terminal text color and style.

    Attributes:
    style (str): The style to be applied to the terminal text. Default is "bold red".

    Methods:
    __str__(): Returns a JSON string representation of the style attribute.
    __enter__(): Applies the specified style to the terminal text.
    __exit__(): Reverts the terminal text to its original style.
    """

    def __init__(self, style: str = "bold red") -> None:
    """
    Initializes the ChangeTerminalColor with the specified style.

    Args:
    style (str): The style to be applied to the terminal text. Default is "bold red".
    """
    self._style = style

    def __str__(self) -> str:
    """
    Returns a JSON string representation of the style attribute.

    Returns:
    str: A JSON string representation of the style attribute.
    """
    return json.dumps(
    {
    "style": self._style,
    },
    indent=4,
    )

    def __enter__(self) -> None:
    """
    Enter the runtime context related to this object.

    This method applies the specified style to the terminal text.

    Returns:
    None
    """
    sys.stdout.write(hf.rich_to_ansi(hf.style_string(" ", self._style))[0])
    sys.stdout.flush()

    def __exit__(
    self,
    exc_type: hf.Optional[type],
    exc_value: hf.Optional[BaseException],
    exc_tb: hf.Optional[object],
    ) -> None:
    """
    Exit the runtime context related to this object.

    This method reverts the terminal text to its original style.

    Parameters:
    exc_type (Optional[type]): The exception type, if an exception was raised.
    exc_value (Optional[BaseException]): The exception instance, if an exception was raised.
    exc_tb (Optional[object]): The traceback object, if an exception was raised.

    Returns:
    None
    """
    sys.stdout.write(hf.rich_to_ansi(hf.style_string(" ", self._style))[1])
    sys.stdout.flush()

    Continue reading...

Compartilhe esta Página