<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def rebin(a, factor, func=None):
 u"""Aggregate data from the input array ``a`` into rectangular tiles. The output array results from tiling ``a`` and applying `func` to each tile. ``factor`` specifies the size of the tiles. More precisely, the returned array ``out`` is such that:: If ``factor`` is an integer-like scalar, then sequence of integer-like scalars, then ``f0 = factor[0]``, number of dimensions of ``a``. The reduction function ``func`` must accept an ``axis`` argument. Examples of such function are - ``numpy.mean`` (default), - ``numpy.sum``, - ``numpy.product``, The following example shows how a (4, 6) array is reduced to a (2, 2) array array([[ 24, 42], [ 96, 114]]) If the elements of `factor` are not integer multiples of the dimensions of `a`, the remainding cells are discarded. array([[16, 24, 32], [72, 80, 88]]) """

    a = np.asarray(a)
    dim = a.ndim
    if np.isscalar(factor):
        factor = dim*(factor,)
    elif len(factor) != dim:
        raise ValueError('length of factor must be {} (was {})'
                         .format(dim, len(factor)))
    if func is None:
        func = np.mean
    for f in factor:
        if f != int(f):
            raise ValueError('factor must be an int or a tuple of ints '
                             '(got {})'.format(f))

    new_shape = [n//f for n, f in zip(a.shape, factor)]+list(factor)
    new_strides = [s*f for s, f in zip(a.strides, factor)]+list(a.strides)
    aa = as_strided(a, shape=new_shape, strides=new_strides)
    return func(aa, axis=tuple(range(-dim, 0)))