import math


def format_amount(num: int, *, base: int = 1024, prefix: str = '', suffix: str = 'B') -> str:
    """
    Humanize any amount to string
    format_amount(0) == "0B"
    format_amount(1750) == "1.7KB"
    format_amount(1234567890) == "1.1GB"
    format_amount(2000, base=10, suffix='r') == "2Gr"

    :param num: numeric amount
    :param base: how much does the step takes (default 1024 as for bytes)
    :param prefix: type prefix (default '')
    :param suffix: type suffix (default B as for bytes)
    :return: Formatted amount string
    :raise TypeError:
    """
    if not num:
        return f'0{suffix}'

    if not isinstance(num, int):
        raise TypeError(f'Invalid num type = {type(num)}')

    if not isinstance(base, int):
        raise TypeError(f'Invalid base type = {type(base)}')

    sign = '-' if num < 0 else ''
    num = abs(num)

    magnitude = int(math.floor(math.log(num, base)))
    val = float(num / math.pow(base, magnitude))

    if magnitude > 7:
        val = f'{val:.0f}' if val.is_integer() else f'{val:.1f}'
        return f'{sign}{val}{"Y"}{prefix}{suffix}'

    val = f'{val:.0f}' if val.is_integer() else f'{val:3.1f}'
    return f'{sign}{val}{["", "K", "M", "G", "T", "P", "E", "Z"][magnitude]}{prefix}{suffix}'