<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def positions(weights, period, freq=None):
 """ Builds net position values time series, the portfolio percentage invested in each position. Parameters weights: pd.Series pd.Series containing factor weights, the index contains timestamps at which the trades are computed and the values correspond to assets weights - see factor_weights for more details period: pandas.Timedelta or string Assets holding period (1 day, 2 mins, 3 hours etc). It can be a Timedelta or a string in the format accepted by Timedelta constructor ('1 days', '1D', '30m', '3h', '1D1h', etc) freq : pandas DateOffset, optional Used to specify a particular trading calendar. If not present weights.index.freq will be used Returns ------- pd.DataFrame Assets positions series, datetime on index, assets on columns. Example: index 'AAPL' 'MSFT' cash 2004-01-09 10:30:00 13939.3800 -14012.9930 711.5585 2004-01-09 15:30:00 0.00 -16012.9930 411.5585 2004-01-12 10:30:00 14492.6300 -14624.8700 0.0 2004-01-12 15:30:00 14874.5400 -15841.2500 0.0 2004-01-13 10:30:00 -13853.2800 13653.6400 -43.6375 """


    weights = weights.unstack()

    if not isinstance(period, pd.Timedelta):
        period = pd.Timedelta(period)

    if freq is None:
        freq = weights.index.freq

    if freq is None:
        freq = BDay()
        warnings.warn("'freq' not set, using business day calendar",
                      UserWarning)

    #
    # weights index contains factor computation timestamps, then add returns
    # timestamps too (factor timestamps + period) and save them to 'full_idx'
    # 'full_idx' index will contain an entry for each point in time the weights
    # change and hence they have to be re-computed
    #
    trades_idx = weights.index.copy()
    returns_idx = utils.add_custom_calendar_timedelta(trades_idx, period, freq)
    weights_idx = trades_idx.union(returns_idx)

    #
    # Compute portfolio weights for each point in time contained in the index
    #
    portfolio_weights = pd.DataFrame(index=weights_idx,
                                     columns=weights.columns)
    active_weights = []

    for curr_time in weights_idx:

        #
        # fetch new weights that become available at curr_time and store them
        # in active weights
        #
        if curr_time in weights.index:
            assets_weights = weights.loc[curr_time]
            expire_ts = utils.add_custom_calendar_timedelta(curr_time,
                                                            period, freq)
            active_weights.append((expire_ts, assets_weights))

        #
        # remove expired entry in active_weights (older than 'period')
        #
        if active_weights:
            expire_ts, assets_weights = active_weights[0]
            if expire_ts <= curr_time:
                active_weights.pop(0)

        if not active_weights:
            continue
        #
        # Compute total weights for curr_time and store them
        #
        tot_weights = [w for (ts, w) in active_weights]
        tot_weights = pd.concat(tot_weights, axis=1)
        tot_weights = tot_weights.sum(axis=1)
        tot_weights /= tot_weights.abs().sum()

        portfolio_weights.loc[curr_time] = tot_weights

    return portfolio_weights.fillna(0)