<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def markowitz_portfolio(cov_mat, exp_rets, target_ret, allow_short=False, market_neutral=False):
 """ Computes a Markowitz portfolio. Parameters cov_mat: pandas.DataFrame Covariance matrix of asset returns. exp_rets: pandas.Series Expected asset returns (often historical returns). target_ret: float Target return of portfolio. allow_short: bool, optional If 'False' construct a long-only portfolio. If 'True' allow shorting, i.e. negative weights. market_neutral: bool, optional If 'False' sum of weights equals one. If 'True' sum of weights equal zero, i.e. create a market neutral portfolio (implies allow_short=True). Returns ------- weights: pandas.Series Optimal asset weights. """

    if not isinstance(cov_mat, pd.DataFrame):
        raise ValueError("Covariance matrix is not a DataFrame")

    if not isinstance(exp_rets, pd.Series):
        raise ValueError("Expected returns is not a Series")

    if not isinstance(target_ret, float):
        raise ValueError("Target return is not a float")

    if not cov_mat.index.equals(exp_rets.index):
        raise ValueError("Indices do not match")

    if market_neutral and not allow_short:
        warnings.warn("A market neutral portfolio implies shorting")
        allow_short=True

    n = len(cov_mat)

    P = opt.matrix(cov_mat.values)
    q = opt.matrix(0.0, (n, 1))

    # Constraints Gx <= h
    if not allow_short:
        # exp_rets*x >= target_ret and x >= 0
        G = opt.matrix(np.vstack((-exp_rets.values,
                                  -np.identity(n))))
        h = opt.matrix(np.vstack((-target_ret,
                                  +np.zeros((n, 1)))))
    else:
        # exp_rets*x >= target_ret
        G = opt.matrix(-exp_rets.values).T
        h = opt.matrix(-target_ret)

    # Constraints Ax = b
    # sum(x) = 1
    A = opt.matrix(1.0, (1, n))

    if not market_neutral:
        b = opt.matrix(1.0)
    else:
        b = opt.matrix(0.0)

    # Solve
    optsolvers.options['show_progress'] = False
    sol = optsolvers.qp(P, q, G, h, A, b)

    if sol['status'] != 'optimal':
        warnings.warn("Convergence problem")

    # Put weights into a labeled series
    weights = pd.Series(sol['x'], index=cov_mat.index)
    return weights