<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def portfolio_lp( weights, latest_prices, min_allocation=0.01, total_portfolio_value=10000 ):
 """ For a long only portfolio, convert the continuous weights to a discrete allocation using Mixed Integer Linear Programming. This can be thought of as a clever way to round the continuous weights to an integer number of shares :param weights: continuous weights generated from the ``efficient_frontier`` module :type weights: dict :param latest_prices: the most recent price for each asset :type latest_prices: pd.Series or dict :param min_allocation: any weights less than this number are considered negligible, defaults to 0.01 :type min_allocation: float, optional :param total_portfolio_value: the desired total value of the portfolio, defaults to 10000 :type total_portfolio_value: int/float, optional :raises TypeError: if ``weights`` is not a dict :raises TypeError: if ``latest_prices`` isn't a series :raises ValueError: if not ``0 < min_allocation < 0.3`` :return: the number of shares of each ticker that should be purchased, along with the amount of funds leftover. :rtype: (dict, float) """

    import pulp

    if not isinstance(weights, dict):
        raise TypeError("weights should be a dictionary of {ticker: weight}")
    if not isinstance(latest_prices, (pd.Series, dict)):
        raise TypeError("latest_prices should be a pd.Series")
    if min_allocation > 0.3:
        raise ValueError("min_allocation should be a small float")
    if total_portfolio_value <= 0:
        raise ValueError("total_portfolio_value must be greater than zero")

    m = pulp.LpProblem("PfAlloc", pulp.LpMinimize)
    vals = {}
    realvals = {}
    etas = {}
    abss = {}
    remaining = pulp.LpVariable("remaining", 0)
    for k, w in weights.items():
        if w < min_allocation:
            continue
        vals[k] = pulp.LpVariable("x_%s" % k, 0, cat="Integer")
        realvals[k] = latest_prices[k] * vals[k]
        etas[k] = w * total_portfolio_value - realvals[k]
        abss[k] = pulp.LpVariable("u_%s" % k, 0)
        m += etas[k] <= abss[k]
        m += -etas[k] <= abss[k]
    m += remaining == total_portfolio_value - pulp.lpSum(realvals.values())
    m += pulp.lpSum(abss.values()) + remaining
    m.solve()
    results = {k: val.varValue for k, val in vals.items()}
    return results, remaining.varValue