zhzluke96
update
1df74c6
raw
history blame
3.75 kB
#!/usr/bin/env python3
import re
import sys
from contextlib import contextmanager
class ANSI:
ansi_color = {
"black": "\033[30m",
"red": "\033[31m",
"green": "\033[32m",
"yellow": "\033[33m",
"blue": "\033[34m",
"purple": "\033[35m",
"blue_light": "\033[36m",
"white": "\033[37m",
"reset": "\033[0m",
"upline": "\033[1A",
"clear_line": "\033[2K",
"clear": "\033[2J",
}
ansi_nocolor = {
"black": "",
"red": "",
"green": "",
"yellow": "",
"blue": "",
"purple": "",
"blue_light": "",
"white": "",
"reset": "",
"upline": "\033[1A\033[",
"clear_line": "\033[K",
"clear": "\033[2J",
}
def __init__(self):
self._dict = ANSI.ansi_color if ("--color" in sys.argv) else ANSI.ansi_nocolor
def switch(self, color: bool):
self._dict = ANSI.ansi_color if color else ANSI.ansi_nocolor
def keys(self):
return self._dict.keys()
def items(self):
return self._dict.items()
def __getitem__(self, key):
return self._dict[key]
def __str__(self):
return str(self._dict)
def __repr__(self):
return repr(self._dict)
ansi = ANSI()
def remove_ansi(s: str) -> str:
ansi_escape = re.compile(r"(\x9B|\x1B\[)[0-?]*[ -\/]*[@-~]")
return ansi_escape.sub("", s)
def get_ansi_len(s: str) -> int:
return len(s) - len(remove_ansi(s))
def prints(*args: str, indent: int = 0, prefix: str = "", **kwargs):
assert indent >= 0
new_args = []
for arg in args:
new_args.append(indent_str(str(arg), indent=indent))
if len(new_args):
new_args[0] = prefix + str(new_args[0])
print(*new_args, **kwargs)
def output_iter(_iter: int, iteration: int = None, iter_len: int = 4) -> str:
if iteration is None:
pattern = "{blue_light}[ {red}{0}{blue_light} ]{reset}"
return pattern.format(str(_iter).rjust(iter_len), **ansi)
else:
iter_str = str(iteration)
length = len(iter_str)
pattern = (
"{blue_light}[ {red}{0}{blue_light} " "/ {red}{1}{blue_light} ]{reset}"
)
return pattern.format(str(_iter).rjust(length), iter_str, **ansi)
def indent_str(s_: str, indent: int = 0) -> str:
# modified from torch.nn.modules._addindent
if indent > 0 and s_:
s_ = indent * " " + str(s_[:-1]).replace("\n", "\n" + indent * " ") + s_[-1]
return s_
class IndentRedirect: # TODO: inherit TextIOWrapper?
def __init__(self, buffer: bool = True, indent: int = 0):
self.__console__ = sys.stdout
self.indent = indent
self.__buffer: str = None
if buffer:
self.__buffer = ""
def write(self, text: str, indent: int = None):
indent = indent if indent is not None else self.indent
text = indent_str(text, indent=indent)
if self.__buffer is None:
self.__console__.write(text)
else:
self.__buffer += text
def flush(self):
if self.__buffer is not None:
self.__console__.write(self.__buffer)
self.__buffer = ""
self.__console__.flush()
@contextmanager
def __call__(self) -> None:
try:
sys.stdout = self
yield
finally:
sys.stdout = self.__console__
self.__buffer = ""
def enable(self):
sys.stdout = self
def disable(self):
if self.__buffer is not None:
self.__buffer = ""
sys.stdout = self.__console__
@property
def buffer(self) -> str:
return self.__buffer
redirect = IndentRedirect()