0

I'm having 2 problemas with my check50:

  • :( buy handles fractional, negative, and non-numeric shares
  • :( sell handles invalid number of shares

As shown in the code below, my input in buy and sell is type="number", so I can put only integer values.

In my sell.html, I managed to limit the number of stocks I was able to sell to the current limit in thedatabase.

That said, the code as it is should be able to address these issues (I think).

Here is my code:

Buy

@app.route("/buy", methods=["GET", "POST"])
@login_required
def buy():
    """Buy shares of stock"""
    if request.method == "POST":
        user_id = session["user_id"]

        stock = lookup(request.form.get("symbol"))
        if stock:
            shares = int(request.form.get("shares"))
            purchase = shares * stock["price"]
            cash = db.execute("SELECT cash FROM users WHERE id = ?", user_id)

            if purchase > cash[0]['cash']:

                flash("You don't have enough Cash")
                return redirect("/buy")

            else:

                db.execute("UPDATE users SET cash = cash - ? WHERE id = ?", purchase, user_id)

                dt = db.execute("SELECT datetime()")
                db.execute(
                    "INSERT INTO portfolio (symbol, shares, price, user_id, operation, operation_time) VALUES(?, ?, ?, ?, ?, ?)",
                    stock["symbol"], shares, stock["price"], user_id, "b", dt[0]["datetime()"])

                flash("Bought!")

                return redirect("/")
        else:
            return apology("invalid stock", 400)

    else:
        return render_template("buy.html")

Html part:

{% extends "layout.html" %}

{% block title %}
    Buy
{% endblock %}

{% block main %}
    <form action="/buy" method="POST">
        <div class="form-group">
            <input autocomplete="off" autofocus class="form-control" name="symbol" placeholder="Symbol" type="text">
        </div>
        <div class="form-group">
            <input autocomplete="off" autofocus class="form-control" name="shares" placeholder="Shares" type="number" min="0">
        </div>
        <button class="btn btn-primary" type="submit">Buy</button>
        <p style="padding:10px">
            {{ stock_text }}
        </p>
    </form>
{% endblock %}

Sell

@app.route("/sell", methods=["GET", "POST"])
@login_required
def sell():
    """Sell shares of stock"""
    user_id = session["user_id"]

    if request.method == "POST":

        stock = lookup(request.form.get("symbol"))
        shares = int(request.form.get("shares")) * (-1)
        purchase = shares * stock["price"]

        db.execute("UPDATE users SET cash = cash - ? WHERE id = ?", purchase, user_id)

        dt = db.execute("SELECT datetime()")
        db.execute(
            "INSERT INTO portfolio (symbol, shares, price, user_id, operation, operation_time) VALUES(?, ?, ?, ?, ?, ?)",
            stock["symbol"], shares, stock["price"], user_id, "s", dt[0]["datetime()"])

        flash("Sold!")

        return redirect("/")

    else:

        stocks_list = db.execute("SELECT symbol, SUM(shares) AS shares FROM portfolio WHERE user_id = ? GROUP BY symbol", user_id)

        return render_template("sell.html", stocks_list=stocks_list)

Html part:

{% extends "layout.html" %}

{% block title %}
    Sell
{% endblock %}

{% block main %}
    <form action="/sell" method="POST">
        <div class="form-group">
            <select name="symbol">
                <option disabled selected value="">Symbol</option>
                {% for stocks in stocks_list %}
                    <option value="{{ stocks.symbol }}" data-max="{{ stocks.shares }}">{{ stocks.symbol }}</option>
                {% endfor %}
            </select>
        </div>
        <div class="form-group">
            <input autocomplete="off" autofocus class="form-control" name="shares" placeholder="Shares" type="number" min="0" max="10">
        </div>
        <button class="btn btn-primary" type="submit">Sell</button>
        <p style="padding:10px">
            {{ stock_text }}
        </p>
    </form>
    <script>
        // https://stackoverflow.com/questions/30787931/max-value-of-input-from-selected-data-attribute
        // https://www.w3schools.com/jquery/jquery_dom_get.asp

        $('select').change(function () {
            $('input[type=number]').attr('max', $('option:selected',this).data('max'));
            $("input[type=number]").val("0");
        });
    </script>
{% endblock %}

I'm not sure how to fix this. I'd appreciate any help. Thanks!

1

It is much better UI/UX to add the constraints to the front end. Alas, check50 is verifying that the code performs as instructed in the spec.

The same directive is given for buy and sell routes. From the spec:

Require that a user input a number of shares, implemented as a text field whose name is shares. Render an apology if the input is not a positive integer.

check50 does not use the front end to verify the routes. You'll need to add the appropriate code to application.py.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .