def gen_batch_index(N_all, batch_size):
    """
    return list of index lists, which can be used to access each batch

    ---------------
    inputs:
        N_all: # of all elements
        batch_size: # of elements in each batch
    outputs:
        batch_index_list[i] is the indexes of batch i.

    ---------------
    notes:
        Python don't have out range check, the simpliest version could be:
        for _i in range(0, N_all, batch_size):
            yield range(_i, _i + batch_size)
    ---------------
    examples:
    >>> gen_batch_index(6,3) == [[0,1,2],[3,4,5]]
    True
    >>> gen_batch_index(7,3) == [[0,1,2],[3,4,5],[6]]
    True
    >>> gen_batch_index(8,3) == [[0,1,2],[3,4,5],[6,7]]
    True
    """
    batch_index_list = []
    for _batch_start_indx in range(0, N_all, batch_size):
        _batch_end_indx = int(min(_batch_start_indx + batch_size, N_all))
        batch_index_list.append(range(_batch_start_indx, _batch_end_indx))
    return batch_index_list