def order_df(df, first=None, last=None):
    """
    Order a dataframe that the 'first' columns are first and 'last' are last. It is not necessary to provide
    all the columns, if a subset of the columns is supplied, the columns not supplied columns will stay inplace.
    :param df: Dataframe to order
    :type df: pd.DataFrame
    :param first: List of columns to put first
    :type first: list
    :param last: List of columns to put last
    :type last: list
    :return: Ordered dataframe
    :rtype pd.DataFrame
    """
    if not first:
        first = []
    if not last:
        last = []
    first.extend(list(set(df.columns) - set(first) - set(last)))
    if last:
        first.extend(last)
    return df[first]
