While all the checks work, (empty symbol, invalid number of shares…), the function fails to actually purchase the stocks. It returns an internal server error. Following is the log output:
File “/usr/local/lib/python3.9/site-packages/cs50/sql.py”, line 71, in _execute raise RuntimeError(exc.orig) from None RuntimeError: incomplete input
Following is my buy function:
def buy():
    """Buy shares of stock"""
    if request.method == "POST":
        # access symbol and stock
        symbol = request.form.get("symbol")
        stock = lookup(symbol)
        # ensure valid symbol
        if not symbol:
            return apology("Please enter a valid symbol")
        elif not stock: #if symbol is invalid then none will get allocated to stock, which we dont want
            return apology("Invalid symbol")
        # access the number of shares and check for an integer
        try:
            shares = int(request.form.get("shares"))
        except:
            return apology("Shares must be an integer")
        # if shares are negative
        if shares <= 0:
            return apology("Shares must be a positive integer")
        user_id = session["user_id"]
        cash = db.execute("SELECT cash FROM users WHERE id = ?", user_id)[0]["cash"]
        stock_name = stock["name"]
        stock_price = stock["price"]
        total_price = stock_price * shares
        # check for sufficient funds
        if total_price > cash:
            return apology("Insufficient funds.")
        else:
            db.execute("UPDATE users SET cash = ? WHERE id = ?", cash - total_price, user_id)
            db.execute("INSERT INTO transactions (user_id, name, shares, price, type, symbol) VALUES ( ?, ?, ?, ?, ?, ?",
                        user_id, stock_name, shares, stock_price, 'buy', symbol)
        flash("Bought!")
        return redirect('/')
    else:
        return render_template("buy.html")
Following is my HTML code:
{% 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 class="form-control" name="shares" placeholder="shares" type="text">
        </div>
        <button class="btn btn-primary" type="submit">Buy</button>
    </form>
{% endblock %}
Following is my SQL table:
| field | type | 
|---|---|
| id | INTEGER PRIMARY KEY AUTOINCREMENT, | 
| user_id | INTEGER NOT NULL, | 
| name | TEXT NOT NULL, | 
| shares | INTEGER NOT NULL, | 
| price | NUMERIC NOT NULL, | 
| type | TEXT NOT NULL, | 
| symbol | TEXT NOT NULL, | 
| time | TIMESTAMP DEFAULT CURRENT_TIMESTAMP | 
| FOREIGN KEY(user_id) REFERENCES users(id) | 
Advertisement
Answer
 db.execute("INSERT INTO transactions (user_id, name, shares, price, type, symbol) VALUES ( ?, ?, ?, ?, ?, ?", 
user_id, stock_name, shares, stock_price, 'buy', symbol)
Could it be that this statement needs to have a closing round bracket in VALUES?
 db.execute("INSERT INTO transactions (user_id, name, shares, price, type, symbol) VALUES ( ?, ?, ?, ?, ?, ?);", 
user_id, stock_name, shares, stock_price, 'buy', symbol)
