0

I tried my solution multiple times and compared it to the staff's solution as well but there is an check 50 error saying ":( sell handles valid sale expected to find "56.00" in page, but it wasn't found". What do you think is wrong.

here is the sell function:

def sell():
    """Sell shares of stock"""
    if request.method == "POST":
        profile = db.execute("SELECT Shares FROM ? WHERE Symbol = ?", session["username"], request.form.get("symbol"))
        # Ensure stock name was submitted
        if not request.form.get("symbol"):
            return apology("must provide stock name")

        # Ensure number of stocks was submitted
        elif not request.form.get("shares"):
            return apology("must provide nummber of stocks")
        elif int(request.form.get("shares")) > int(profile[0]['Shares']):
            return apology("you don't have that many stocks")

        # getting the stock details

        stock = request.form.get("symbol")
        number = request.form.get("shares")
        stock_desc = lookup(stock)
        sell_number = 0 - int(number)

        total = int(number)*stock_desc['price']
        value = total
        tot = f"{value:.2f}"
        buyer_desc = db.execute("SELECT cash FROM users WHERE id=?", session["user_id"])

        result = db.execute("SELECT Symbol FROM ? WHERE Symbol=?", session["username"], stock_desc['symbol'])
        # updating the stock if it is already bought
        if result[0]['Symbol'] == stock_desc['symbol']:
            previous_holding = db.execute("SELECT Shares FROM ? WHERE Symbol = ?", session["username"], stock_desc['symbol'])
            stock_num = int(previous_holding[0]['Shares']) - int(number)
            total_pri = (stock_num)*stock_desc['price']
            db.execute("UPDATE ? SET Shares = ?, Price = ?, Total = ?  WHERE Symbol = ?",
                       session["username"], stock_num, stock_desc["price"], total_pri, stock_desc['symbol'])
            if stock_num == 0:
                db.execute("DELETE FROM ? WHERE Symbol = ?", session["username"], stock_desc['symbol'])
            db.execute("INSERT INTO ? (symbol,shares,price,transacted) VALUES (?,?,?,?)",
                       session["username"] + 'his', stock, sell_number, usd(stock_desc['price']), datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
        # deducting the cash
        db.execute("UPDATE users SET cash = cash + ? WHERE id = ?", tot, session["user_id"])
        return redirect("/")

    else:
        profile = db.execute("SELECT * FROM ?", session["username"])
        return render_template("sell.html", profile_desc=profile)

Here is the entire code:

import os

from cs50 import SQL
from flask import Flask, flash, redirect, render_template, request, session
from flask_session import Session
from tempfile import mkdtemp
from werkzeug.exceptions import default_exceptions, HTTPException, InternalServerError
from werkzeug.security import check_password_hash, generate_password_hash
from datetime import datetime

from helpers import apology, login_required, lookup, usd

# Configure application
app = Flask(__name__)

# Ensure templates are auto-reloaded
app.config["TEMPLATES_AUTO_RELOAD"] = True


# Ensure responses aren't cached
@app.after_request
def after_request(response):
    response.headers["Cache-Control"] = "no-cache, no-store, must-revalidate"
    response.headers["Expires"] = 0
    response.headers["Pragma"] = "no-cache"
    return response


# Custom filter
app.jinja_env.filters["usd"] = usd

# Configure session to use filesystem (instead of signed cookies)
app.config["SESSION_FILE_DIR"] = mkdtemp()
app.config["SESSION_PERMANENT"] = False
app.config["SESSION_TYPE"] = "filesystem"
Session(app)

# Configure CS50 Library to use SQLite database
db = SQL("sqlite:///finance.db")

# Make sure API key is set
if not os.environ.get("API_KEY"):
    raise RuntimeError("API_KEY not set")


@app.route("/", methods=["GET", "POST"])
@login_required
def index():
    """Show portfolio of stocks"""
    # create table for the user
    db.execute("CREATE TABLE IF NOT EXISTS ? (Symbol TEXT, Name TEXT, Shares int, Price FLOAT, Total FLOAT)", session["username"])
    db.execute("CREATE TABLE IF NOT EXISTS ? (symbol TEXT,shares TEXT,price FLOAT,transacted TEXT)", session["username"] + 'his')
    # getting user details
    profile_det = db.execute("SELECT * FROM ? ORDER BY Symbol", session["username"])
    portfolio = db.execute("SELECT Symbol, Shares FROM ?", session["username"])
    buyer_cash = db.execute("SELECT cash FROM users WHERE id=?", session["user_id"])
    tot_cash = float(buyer_cash[0]['cash'])
    if not portfolio:
        grandtotofp = 0
    # adding all asset values
    for stock in portfolio:
        price = lookup(stock['Symbol'])['price']
        total = stock['Shares'] * price
        stock.update({'price': price, 'total': total})
        tot_cash += total

    return render_template("index.html", profile_desc=profile_det, cash_value=usd(buyer_cash[0]['cash']), tot_cash=usd(tot_cash))


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

        shares = request.form.get("shares")
        # Ensure stock name was submitted
        if not request.form.get("symbol"):
            return apology("must provide stock name")

        # Ensure number of stocks was submitted
        elif not request.form.get("shares"):
            return apology("must provide nummber of stocks")
        elif shares.isalpha() == True:
            return apology("Please provide an appropriate number")
        elif float(shares).is_integer() == False:
            return apology("Please provide an appropriate number")
        elif float(request.form.get("shares")) <= 0:
            return apology("must provide appropriate number of stocks")

        # getting the stock details

        stock = request.form.get("symbol")
        number = request.form.get("shares")
        stock_desc = lookup(stock)
        # making sure the stock name is valid
        if stock_desc == None:
            return apology("Stock name is invalid")

        total = int(number)*stock_desc['price']
        buyer_desc = db.execute("SELECT cash FROM users WHERE id=?", session["user_id"])
        # checking whether the buyer can afford the stock
        if buyer_desc[0]["cash"] < total:
            return apology("You can't afford the stock")

        result = db.execute("SELECT COUNT(Symbol) FROM ? WHERE Symbol=?", session["username"], stock)
        # updating the stock if it is already bought
        if result[0]['COUNT(Symbol)'] > 0:
            previous_holding = db.execute("SELECT Shares FROM ?", session["username"])
            previous_tot = db.execute("SELECT Total FROM ?", session["username"])
            stock_num = int(previous_holding[0]['Shares']) + int(number)
            total_pri = float(previous_tot[0]['Total']) + float(total)
            db.execute("UPDATE ? SET Shares = ? , Price = ? , Total = ? WHERE Symbol = ?",
                       session["username"], stock_num, usd(stock_desc['price']), usd(total_pri), stock)
            db.execute("INSERT INTO ? (symbol,shares,price,transacted) VALUES (?,?,?,?)",
                       session["username"] + 'his', stock, number, usd(stock_desc['price']), datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
        # adding the stock to the users profile
        else:
            db.execute("INSERT INTO ? (Symbol,Name,Shares,Price,Total) VALUES (?,?,?,?,?)",
                       session["username"], stock_desc['symbol'], stock_desc['name'], number, usd(stock_desc['price']), usd(total))
            db.execute("INSERT INTO ? (symbol,shares,price,transacted) VALUES (?,?,?,?)",
                       session["username"] + 'his', stock, number, usd(stock_desc['price']), datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
        # deducting the cash
        db.execute("UPDATE users SET cash = cash - ? WHERE id = ?", total, session["user_id"])
        return redirect("/")
    else:
        return render_template("buy.html")


@app.route("/history")
@login_required
def history():
    """Show history of transactions"""
    history = db.execute("SELECT * FROM ? ORDER BY transacted DESC", session["username"] + 'his')
    if history == None:
        return apology("No transactions were made yet")

    return render_template("history.html", history_desc=history)


@app.route("/login", methods=["GET", "POST"])
def login():
    """Log user in"""

    # Forget any user_id
    session.clear()

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

        # Ensure username was submitted
        if not request.form.get("username"):
            return apology("must provide username", 403)

        # Ensure password was submitted
        elif not request.form.get("password"):
            return apology("must provide password", 403)

        # Query database for username
        rows = db.execute("SELECT * FROM users WHERE username = ?", request.form.get("username"))

        # Ensure username exists and password is correct
        if len(rows) != 1 or not check_password_hash(rows[0]["hash"], request.form.get("password")):
            return apology("invalid username and/or password", 403)

        # Remember which user has logged in
        session["user_id"] = rows[0]["id"]
        session["username"] = rows[0]["username"]

        # Redirect user to home page
        return redirect("/")

    # User reached route via GET (as by clicking a link or via redirect)
    else:
        return render_template("login.html")


@app.route("/logout")
def logout():
    """Log user out"""

    # Forget any user_id
    session.clear()

    # Redirect user to login form
    return redirect("/")


@app.route("/quote", methods=["GET", "POST"])
@login_required
def quote():
    """Get stock quote."""
    # getting the stock value if method is post
    if request.method == "POST":
        stock = lookup(request.form.get("symbol"))
        # making sure stock name is entered and is a valid name
        if stock == None:
            return apology("Invalid stock name")
        price = stock['price']
        return render_template("quoted.html", stock=stock, price=usd(price))

    else:
        return render_template("quote.html")


@app.route("/register", methods=["GET", "POST"])
def register():
    """Register user"""
    if request.method == "GET":
        return render_template("register.html")

    else:
        # getting the informatio from the form
        password = request.form.get("password")
        username = request.form.get("username")
        rows = db.execute("SELECT * FROM users WHERE username = ?", username)
        # error handling
        if not request.form.get("username"):
            return apology("must provide username")
        elif not request.form.get("password"):
            return apology("must provide password")
        elif request.form.get("password") != request.form.get("confirmation"):
            return apology("must provide the same password")
        elif len(rows) >= 1:
            return apology("username already taken")
        # adding the user to the table
        db.execute("INSERT INTO users (username,hash) VALUES (?,?)", request.form.get("username"), generate_password_hash(password))
        return redirect("/")


@app.route("/sell", methods=["GET", "POST"])
@login_required
def sell():
    """Sell shares of stock"""
    if request.method == "POST":
        profile = db.execute("SELECT Shares FROM ? WHERE Symbol = ?", session["username"], request.form.get("symbol"))
        # Ensure stock name was submitted
        if not request.form.get("symbol"):
            return apology("must provide stock name")

        # Ensure number of stocks was submitted
        elif not request.form.get("shares"):
            return apology("must provide nummber of stocks")
        elif int(request.form.get("shares")) > int(profile[0]['Shares']):
            return apology("you don't have that many stocks")

        # getting the stock details

        stock = request.form.get("symbol")
        number = request.form.get("shares")
        stock_desc = lookup(stock)
        sell_number = 0 - int(number)

        total = int(number)*stock_desc['price']
        value = total
        tot = f"{value:.2f}"
        buyer_desc = db.execute("SELECT cash FROM users WHERE id=?", session["user_id"])

        result = db.execute("SELECT Symbol FROM ? WHERE Symbol=?", session["username"], stock_desc['symbol'])
        # updating the stock if it is already bought
        if result[0]['Symbol'] == stock_desc['symbol']:
            previous_holding = db.execute("SELECT Shares FROM ? WHERE Symbol = ?", session["username"], stock_desc['symbol'])
            stock_num = int(previous_holding[0]['Shares']) - int(number)
            total_pri = (stock_num)*stock_desc['price']
            db.execute("UPDATE ? SET Shares = ?, Price = ?, Total = ?  WHERE Symbol = ?",
                       session["username"], stock_num, stock_desc["price"], total_pri, stock_desc['symbol'])
            if stock_num == 0:
                db.execute("DELETE FROM ? WHERE Symbol = ?", session["username"], stock_desc['symbol'])
            db.execute("INSERT INTO ? (symbol,shares,price,transacted) VALUES (?,?,?,?)",
                       session["username"] + 'his', stock, sell_number, usd(stock_desc['price']), datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
        # deducting the cash
        db.execute("UPDATE users SET cash = cash + ? WHERE id = ?", tot, session["user_id"])
        return redirect("/")

    else:
        profile = db.execute("SELECT * FROM ?", session["username"])
        return render_template("sell.html", profile_desc=profile)


def errorhandler(e):
    """Handle error"""
    if not isinstance(e, HTTPException):
        e = InternalServerError()
    return apology(e.name, e.code)


# Listen for errors
for code in default_exceptions:
    app.errorhandler(code)(errorhandler)
1

The issue is that once you sell some stock, your profile_det (that you display on your index page) price values no longer have 2 decimal places.

For example, if I buy 4 shares of a stock worth $28.00 each, your profile_det will be:

[{'Symbol': 'AAAA', 'Name': 'AAAA Test', 'Shares': 4, 'Price': '$28.00', 'Total': '$112.00'}]

But if I then sell 2 of those shares, it shows:

[{'Symbol': 'AAAA', 'Name': 'AAAA Test', 'Shares': 2, 'Price': 28.0, 'Total': 56.0}]

and check50 is looking for $56.00 and your page is displaying 56.0

You shouldn't try to format your actual database values with usd formatting. Save that formatting for the actual display in html page, using usd as a jinja filter per the hint. {{ value | usd }}

You must log in to answer this question.

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