<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def aggregate(table, metrics=None, by=None, having=None, **kwds):
 """ Aggregate a table with a given set of reductions, with grouping expressions, and post-aggregation filters. Parameters table : table expression metrics : expression or expression list by : optional, default None Grouping expressions having : optional, default None Post-aggregation filters Returns ------- agg_expr : TableExpr """

    if metrics is None:
        metrics = []

    for k, v in sorted(kwds.items()):
        v = table._ensure_expr(v)
        metrics.append(v.name(k))

    op = table.op().aggregate(table, metrics, by=by, having=having)
    return op.to_expr()