Source code for neuralib.util.verbose

from collections.abc import Callable
from datetime import datetime
from pathlib import Path
from typing import Literal, cast

import h5py
import pandas as pd
import polars as pl
from colorama import Fore, Style
from neuralib.typing import DataFrame, PathLike, PathLikeType

__all__ = ['fprint',
           'printdf',
           'print_h5py',
           'print_load',
           'print_save',
           'publish_annotation']

_PREV_LOAD_FILE = None
_PREV_SAVE_FILE = None


[docs] def fprint(*msgs, vtype: Literal['info', 'io', 'warning', 'error', 'pass', 'debug'] | str = 'info', timestamp: bool = True, **kwarg) -> None: """ Formatting print with different colors based on verbose type :param msgs: print message :param vtype: verbose type :param timestamp: If add time info """ prefix = f'[{vtype.upper()}]' match vtype: case 'error': color = 'RED' case 'warning': color = 'YELLOW' case 'io': color = 'MAGENTA' case 'info': color = 'CYAN' case 'pass': color = 'GREEN' case _: color = 'WHITE' try: fg_color = getattr(Fore, color) except AttributeError: fg_color = Fore.WHITE msg = fg_color + prefix if timestamp: msg += f"[{datetime.today().strftime('%y-%m-%d %H:%M:%S')}] - " try: out = ''.join(msgs) + "\n" except TypeError: out = f'{msgs}' msg += out msg += Style.RESET_ALL print(msg, **kwarg)
[docs] def printdf(df: DataFrame, nrows: int | None = None, ncols: int | None = None, do_print: bool = True, **kwargs) -> str: """ print dataframe with given row numbers (polars) if isinstance pandas dataframe, print all. :param df: polars or pandas dataframe :param nrows: number of rows (applicable in polars case) :param ncols: number of columns :param do_print: do print otherwise, only return the str :param kwargs: additional arguments pass the ``pl.Config()`` :return: """ if isinstance(df, pl.DataFrame): with pl.Config(**kwargs) as cfg: rows = df.shape[0] if nrows is None else nrows cols = df.shape[1] if ncols is None else ncols cfg.set_tbl_rows(rows) cfg.set_tbl_cols(cols) if do_print: print(df) return repr(df) elif isinstance(df, pd.DataFrame): ret = df.to_markdown() or '' print(ret) return ret else: raise TypeError('')
[docs] def publish_annotation(level: Literal['main', 'sup', 'appendix', 'test'], *, project: str | list[str] | None = None, figure: str | list[str] | None = None, caption: str | None = None, as_doc: bool = False, as_attributes: bool = True): """ Annotation for knowing the class/function using scenario in paper publication :param level: {'main', 'sup', 'appendix', 'test'} :param project: Project name or list of project name :param figure: Figure number or list of figure name :param caption: Other caption :param as_doc: As documents, be able to parser the `.. note::` block by ``Sphinx`` :param as_attributes: If set info as attributes :return: """ valid_levels = ('main', 'sup', 'appendix', 'test') if level not in valid_levels: raise ValueError(f'must be one of the {valid_levels}') def decorator(target: type | Callable): doc = '' if target.__doc__ is None else target.__doc__ if as_doc: doc += '\n\n' + '\n\n'.join([ '.. note:: ', '\t**Publish Annotation**', f'\tProject: {project}', f'\tFigure: {figure}', f'\tLevel: {level} ', f'\tCaption: {caption}', ]) target.__doc__ = doc if as_attributes: attrs = ['__publish_level__', '__publish_project__', '__publish_figure__', '__publish_caption__'] for attr in attrs: if hasattr(target, attr): raise AttributeError(f"Class {target.__name__} already has an attribute named '{attr}'.") target.__publish_level__ = level target.__publish_project__ = project target.__publish_figure__ = figure target.__publish_caption__ = caption return target return decorator