def bubble_sort(array, ascending=True):
    """Sort array using bubble sort algorithm.

    Parameters
    ----------
    array : list
        List to be sorted; Can contain any Python objects that can be compared
    ascending : bool, optional
        If True sort array from smallest to largest; False -> sort array from
        largest to smallest

    Returns
    -------
    list
        Input array sorted.
    """
    # Create copy to avoid modifying array inplace
    array = array.copy()

    # Use swap_count to keep track of number of swaps on each sweep
    swap_count = 1
    # Keep track of number of times array has been iterated over
    sweep_count = 0

    # Keep sweeping through array until no swaps need to occur
    while swap_count > 0:

        # Reset swap scount at beginning of sweep
        swap_count = 0

        for i in range(len(array) - sweep_count - 1):

            # Swap pair of elements being compared if out of order
            if array[i] > array[i+1]:
                # Perform swap
                temp = array[i+1]
                array[i+1] = array[i]
                array[i] = temp

                # Increment swap count
                swap_count += 1

        # Increment sweep_count, to avoid checking elements that are already in
        # correct order, at end of array
        sweep_count += 1

    if ascending:
        return array
    else:
        # Reverse array for descending order sort
        return array[::-1]