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!