from typing import Union


def percentage(
    per: float, whole: float, *, operation: str = "", log: bool = False
) -> Union[float, str]:
    """
        This function will calculate a whole with a certain percentage value.

        >>> from snakypy.helpers.calcs import percentage
        >>> percentage(25, 500)
        125.0
        >>> percentage(25, 500, log=True)
        '>> 25% of 500 = 125.00'
        >>> percentage(25, 500, operation='+')
        625.0
        >>> percentage(25, 500, operation='-')
        375.0
        >>> percentage(25, 500, operation='+', log=True)
        '>> 500 + 25% = 625.00'
        >>> percentage(25, 500, operation='-', log=True)
        '>> 500 - 25% = 375.00'

    Args:
        per (float): Input argument that should receive a float representing a certain percentage value.

        whole (float): Input argument that should receive a float representing total value.

        operation: This named parameter must receive two types of string \
                           values. One is the plus sign ('+') that will add the total \
                           to the imposed percentage. The other is the minus sign ('-'), \
                           which subtracts the total value from the imposed percentage \
                           value. (default: "")

        log (bool):  If this parameter is of the value True, then the return will be \
                     a custom string with the percent signs and the operation. \
                     (default: {False})

    Returns:

    """
    try:
        option = {
            "+": lambda: whole + (whole * (per / 100)),
            "-": lambda: whole - (whole * (per / 100)),
        }.get(operation, lambda: whole * (per / 100))()

        if log:
            if operation == "+":
                return f">> {whole} + {per}% = {option:.2f}"
            elif operation == "-":
                return f">> {whole} - {per}% = {option:.2f}"
            return f">> {per}% of {whole} = {option:.2f}"
        return option
    except AttributeError:
        raise AttributeError("Invalid parameter passed")