<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def fancy_group_by(df, grouping_level=0, aggregate_level=1, method='last', max_=None, min_=None, within=None):
 """ Dataframe group-by operation that supports aggregating by different methods on the index. Parameters df: ``DataFrame`` Pandas dataframe with a MultiIndex grouping_level: ``int`` or ``str`` or ``list`` of ``str`` Index level to group by. Defaults to 0. aggregate_level: ``int`` or ``str`` Index level to aggregate by. Defaults to 1. method: ``str`` Aggregation method. One of last: Use the last (lexicographically) value from each group first: Use the first value from each group max_: <any> If set, will limit results to those having aggregate level values <= this value min_: <any> If set, will limit results to those having aggregate level values >= this value within: Any type supported by the index, or ``DateOffset``/timedelta-like for ``DatetimeIndex``. If set, will limit results to those having aggregate level values within this range of the group value. Note that this is currently unsupported for Multi-index of depth > 2 """

    if method not in ('first', 'last'):
        raise ValueError('Invalid method')

    if isinstance(aggregate_level, six.string_types):
        aggregate_level = df.index.names.index(aggregate_level)

    # Trim any rows outside the aggregate value bounds
    if max_ is not None or min_ is not None or within is not None:
        agg_idx = df.index.get_level_values(aggregate_level)
        mask = np.full(len(agg_idx), True, dtype='b1')
        if max_ is not None:
            mask &= (agg_idx <= max_)
        if min_ is not None:
            mask &= (agg_idx >= min_)
        if within is not None:
            group_idx = df.index.get_level_values(grouping_level)
            if isinstance(agg_idx, pd.DatetimeIndex):
                mask &= (group_idx >= agg_idx.shift(-1, freq=within))
            else:
                mask &= (group_idx >= (agg_idx - within))
        df = df.loc[mask]

    # The sort order must be correct in order of grouping_level -> aggregate_level for the aggregation methods
    # to work properly. We can check the sortdepth to see if this is in fact the case and resort if necessary.
    # TODO: this might need tweaking if the levels are around the wrong way
    if df.index.lexsort_depth < (aggregate_level + 1):
        df = df.sort_index(level=grouping_level)

    gb = df.groupby(level=grouping_level)
    if method == 'last':
        return gb.last()
    return gb.first()