def calculate_boundaries(dist_args1, dist_args2, dist_type, shift):
    """
    Calculate minimum and maximum reward possible for certain distribution types.
    For normal distribution take 3 times standard deviation. These minimum and maximum
    are used to determine the bin sizes.
    :param dist_args1: parameter of the distribution
    :param dist_args2: parameter of the distribution
    :param dist_type: string indicating which distribution type
    :param shift: shift of the multi-modal distribution
    :return: Minimum and maximum reward
    """
    if dist_type == 'uniform' or dist_type == 'uniform_wide':
        low_1, high_1 = dist_args1[0], dist_args1[1]
        low_2, high_2 = dist_args2[0], dist_args2[1]
        min_r = min(low_1, low_2)
        max_r = max(high_1, high_2)
    elif dist_type == 'normal' or dist_type == 'normal2':
        mean_1, std_1 = dist_args1[0], dist_args1[1]
        mean_2, std_2 = dist_args2[0], dist_args2[1]
        min_r = min(mean_1 - 3 * std_1, mean_2 - 3 * std_2)
        max_r = max(mean_1 + 3 * std_1, mean_2 + 3 * std_2)
    elif dist_type == 'multi-modal':
        min_r, max_r = dist_args2[0] - shift, dist_args2[0] + 0.5 + 0.5 + shift
    elif dist_type == 'categorical':
        min_r = min(dist_args1[0] + dist_args2[0])
        max_r = max(dist_args1[0] + dist_args2[0])
    else:
        print('invalid dist type choose: uniform, normal, multi-modal, categorical')
        min_r = None
        max_r = None
    return min_r, max_r