0

I am working on sell and I am getting an error: "TypeError: 'NoneType' object is not subscriptable" on the variable "price". I am not sure why as this is more or less the exact same code I have in buy which is working fine (thus, I don't think it is a problem with the lookup function). I do have "symbol" in sell.html so I think it is finding a symbol but I'm guessing it has to be related to the way I've implemented the drop down. It doesn't seem to have any problem pulling the number of shares from the form. Any guidance on where to look would be appreciated, I can't really do anything to move forward on sell until I figure this out and I just started.

application.py - sell function

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

# User reached route via POST (as by submitting a form via POST)
if request.method == "POST":

    # Make sure user chose a stock from the dropdown menu.
    if not request.form.get("symbol"):

        # return apology (relevant error message, e.g., "Missing username!")
        return apology("please choose a stock from the drop down menu", 403)

    # Ensure user specified number of shares:
    elif not request.form.get("shares"):

        # return apology (relevant error message, e.g., "Missing username!")
        return apology("please enter the number of shares you would like to sell", 403)

    else:
        # Look up current stock price.
        sellquote = lookup(request.form.get("symbol"))

        # Placeholder for how much cash the user currently has.
        usercash = db.execute("SELECT cash FROM users WHERE id = :id", id = session["user_id"])

        # Pull out the aggregate number of shares that the user owns by stock symbol.
        holdings = db.execute("SELECT SUM(shares) as sumshares FROM transactions WHERE userid = :userid GROUP BY symbol", userid = session["user_id"])

        # Define variables
        sharestosell = float(request.form.get("shares"))
        price = sellquote["price"]
        sharesowned = holdings[0]['sumshares']
        transactioncost = sharestosell * price
        cashleft = float(usercash[0]['cash'] + transactioncost)

        # Once we know which stock the user wants to sell and how many shares we need to know if they actually have that many to sell.

        # If you have enough shares of a given stock (aggregated) to sell...
        if sharestosell >= sharesowned:

            #then sell that stock
            selltransaction = db.execute("INSERT INTO transactions (userid, symbol, price, shares, timestamp) VALUES(:userid, :symbol, :price, :shares, datetime('now'))",
                        userid=session["user_id"], symbol=sellquote["symbol"], price=price, shares=sharestosell)

            # Update the cash to reflect the purchase they just made.
            updatecash = db.execute("UPDATE users SET cash = :cashleft WHERE id = :id", cashleft=cashleft, id=session["user_id"])

            return redirect("/")

        # If cash is less than the total value of the attempted purchase
        else:

            # Tell user they don't have enough shares
            return apology("enter a number of shares less than or equal to the number you own", 403)

# User reached route via GET (as by clicking hhhha link or via redirect)
else:

    sales = db.execute("SELECT symbol FROM transactions WHERE userid = :userid GROUP BY symbol ORDER BY symbol ASC", userid = session["user_id"])

    for sale in sales:
        symbol = sale["symbol"]
    return render_template("sell.html", stocks=sales)

sell.html

{% extends "layout.html" %}

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

{% block main %}
<form action="/sell" method="post">
    <div class="form-group">
        <select autocomplete="off" autofocus class="form-control" name="symbol" placeholder="e.g., AMZN" type="text"/>
        {% for stock in stocks %}
        <option value = "Symbol">{{ stock.symbol }}</option></option>
        {% endfor %}
        </select>
    </div>
    <div class="form-group">
        <input class="form-control" name="shares" placeholder="Number of Shares (e.g., 50)" type="number"/>
    </div>
    <button class="btn btn-primary" type="submit">Submit</button>
</form>
{% endblock %}

2 Answers 2

1

Your guess is correct: the lookup function isn't finding symbol. The problem is here
<option value = "Symbol">{{ stock.symbol }}</option></option>.
"symbol" will always have the value "Symbol". (And it looks like it will create invalid html because of </option></option>, which can also cause problems.)

Any print statements in application.py will render in the flask terminal.

0

Does your error message give the exact line that your error is occuring? Or do you know roughly where your code is failing?

This section uses the price keyword:

# Define variables
    sharestosell = float(request.form.get("shares"))
    price = sellquote["price"]
    sharesowned = holdings[0]['sumshares']
    transactioncost = sharestosell * price
    cashleft = float(usercash[0]['cash'] + transactioncost)

You might put in a try / except clause and print your variables one by one to console when the code in try section fails. TypeError implies you're treating one sort of variable as another, for example if sellquote is not a dictionary object, but you're trying to look up the key "price".

sellquote["price"]

Read more here...

https://docs.python.org/3/tutorial/errors.html#handling-exceptions

1
  • The line where the error is occurring is where the price = sellquote["price"] variable is. It is line 312 in application.py. Any tips on how to print the variables to the console? I feel like it's probably a stupid question but I've tried a few different ways and can't get anything to print. I'm guessing the problem is the lookup function isn't finding a symbol and is returning an empty object. I just can't figure out why.
    – CM23
    Commented Jul 12, 2018 at 21:58

You must log in to answer this question.

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