from functools import reduce


def number_convertor_to_milion(number, decimal_number: int = 2, suffix_lang: str = 'en', separate_after_suffix=False):
    """
    convert number to string with suffix.
    :param number: the value will be converted
    :param decimal_number: digits want to be round . example number...(2.1111,decimal_number=2) => 2.11
    :param suffix_lang: type of suffix. options is ['en','fa']
    :return: number is converted to string with suffix.
    """
    result_format = '{:,}'
    result_number = number
    if number >= 1000000000 or number <= -1000000000:
        result_format = '{:,}B'
        if suffix_lang == 'fa':
            result_format = '{:,}میلیارد'
            if separate_after_suffix:
                result_format = '{:,} میلیارد'
        result_number = number / 1000000000.0
    elif number >= 1000000 or number <= -1000000:
        result_number = number / 1000000.0
        result_format = '{:,}M'
        if suffix_lang == 'fa':
            result_format = '{:,}میلیون'
            if separate_after_suffix:
                result_format = '{:,} میلیون'
    elif number > 1000 or number <= -1000:
        result_number = number / 1000.0
        result_format = '{:,}k'
        if suffix_lang == 'fa':
            result_format = '{:,}هزار'
            if separate_after_suffix:
                result_format = '{:,} هزار'
    if round(result_number, decimal_number) - int(round(result_number, decimal_number)) in [0, 0.0, 0.00]:
        return result_format.format(int(result_number))
    return result_format.format(round(result_number, decimal_number))


def deep_get(dictionary, keys, default=None):
    """
    this function search in related dict and return value if find key else return default
    :param dictionary: dict item want to search in keys
    :param keys: related keys want to search in dict. keys separate with '.' .
     example 'data.items.price' for {'data':{'items:{'price':'10'}}}
    :param default: value will return if not found
    :return:
    """
    return reduce(lambda d, key: d.get(key, default) if isinstance(d, dict) else default, keys.split("."), dictionary)


def get_or_default(list_object: list, index: int, default=None):
    """
    :param list_object:list want to get index
    :param index: index of list want to return
    :param default: default value if index not found. default is None
    :return:
    """
    return list_object[index] if index < len(list_object) else default


def version_tuple(v):
    return tuple(map(int, (v.split("."))))