I have completed pset7 and all functionality appears to be working as intended. However, check50 produces the following error:
Since I am unable to find an issues through testing, I am having trouble debugging this error. Any help would be greatly appreciated! My application.py and check50 link is below. Thanks!
check50: https://cs50.me/checks/ab1841b7dca40708a42e32b93fc7f3087666c8a1
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
from werkzeug.security import check_password_hash, generate_password_hash
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")
@app.route("/")
@login_required
def index():
"""Show portfolio of stocks"""
#update table with current price and value
rows = db.execute("SELECT * from Transactions")
for i in range(len(rows)):
transid = i
share = lookup(rows[i]["SYMBOL"])
numshares = rows[i]["NUMSHARES"]
db.execute("UPDATE Transactions SET CURRPRICE = :currprice, CURRTOTAL = :currtotal WHERE TRANSID = :transid AND id = :user", currprice=round(share["price"],2), currtotal=round((int(numshares) * float(share["price"])),2), transid=transid, user=session["user_id"])
#Select Stock data
stocks = db.execute("SELECT SYMBOL,SUM(NUMSHARES) AS sum1,CURRPRICE,SUM(CURRTOTAL) AS sum2 FROM Transactions WHERE id= :user GROUP BY SYMBOL HAVING SUM(NUMSHARES) >0", user=session["user_id"])
#Select Cash Balance
cash = db.execute("SELECT cash FROM users WHERE id = :user", user=session["user_id"])
#Select Total Balance
total = cash[0]["cash"]
for t in range(len(stocks)):
total = total + stocks[t]["sum2"]
total = round(total,2)
#render template
return render_template("index.html", stocks=stocks, cash=cash, total=total)
@app.route("/buy", methods=["GET", "POST"])
@login_required
def buy():
"""Buy shares of stock"""
# User reached route via POST (as by submitting a form via POST)
if request.method == "POST":
# Ensure symbol was submitted
if not request.form.get("symbol"):
return apology("must provide symbol", 403)
# Ensure # of shares was submitted
try:
int(request.form.get("shares"))
except ValueError:
return apology("must provide shares as a positive integer", 403)
if int(request.form.get("shares")) < 1:
return apology("must provide shares as a positive integer", 403)
#ensure valid symbol
shares = lookup(request.form.get("symbol"))
if shares is None:
return apology("invalid symbol", 403)
#lookup stock price
buyprice = shares["price"] * int(request.form.get("shares"))
#lookup available cash
cash = db.execute("SELECT cash FROM users WHERE id = :user", user=session["user_id"])
#determine if sufficient funds
if buyprice > cash[0]["cash"]:
return apology("insufficent funds", 403)
#document transaction
db.execute("INSERT INTO Transactions (id, SYMBOL, PRICE, NUMSHARES, TRANSPRICE, BUYSELL) VALUES (:user,:symbol,:price,:numshares,:transprice, 'Buy')", user=session["user_id"], symbol=request.form.get("symbol"), price=shares["price"], numshares=request.form.get("shares"),transprice=buyprice)
#reduce cash value in users
newcash = cash[0]["cash"] - buyprice
db.execute("UPDATE users SET cash = :newcash WHERE id = :user", newcash=newcash, user=session["user_id"])
#return to buy
return render_template("buy.html")
# User reached route via GET (as by clicking a link or via redirect)
else:
return render_template("buy.html")
@app.route("/history")
@login_required
def history():
"""Show history of transactions"""
#Select Stock data
stocks = db.execute("SELECT BUYSELL, SYMBOL, PRICE, NUMSHARES, TIME FROM Transactions WHERE id= :user", user=session["user_id"])
#render template
return render_template("history.html", stocks=stocks)
@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 = :username",
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"]
# 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."""
# User reached route via POST (as by submitting a form via POST)
if request.method == "POST":
# Ensure symbol was submitted
if not request.form.get("symbol"):
return apology("must provide symbol", 403)
quote = lookup(request.form.get("symbol"))
if quote is None:
return apology("invalid symbol", 403)
#return quote
return render_template("quoted.html", quote=quote)
# User reached route via GET (as by clicking a link or via redirect)
else:
return render_template("quote.html")
@app.route("/register", methods=["GET", "POST"])
def register():
"""Register user"""
# 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", 400)
# Ensure password was submitted
elif not request.form.get("password"):
return apology("must provide password", 400)
# Ensure password was submitted twice
elif not request.form.get("confirmation"):
return apology("must provide password twice", 400)
# Ensure passwords match
elif not request.form.get("password") == request.form.get("confirmation"):
return apology("passwords must match", 400)
# Query database for username
rows = db.execute("SELECT * FROM users WHERE username = :username", username=request.form.get("username"))
# Ensure username exists and password is correct
if len(rows) == 1:
return apology("username already exists", 400)
db.execute("INSERT INTO users (username,hash) VALUES (:username,:hashed)", username=request.form.get("username"), hashed = generate_password_hash(request.form.get("password"), method='pbkdf2:sha256', salt_length=8))
return render_template("login.html")
# User reached route via GET (as by clicking a link or via redirect)
else:
return render_template("register.html")
@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":
# Ensure symbol was submitted
if not request.form.get("symbol"):
return apology("must provide symbol", 403)
# Ensure # of shares was submitted
try:
int(request.form.get("shares"))
except ValueError:
return apology("must provide shares as a positive integer", 403)
if int(request.form.get("shares")) < 1:
return apology("must provide shares as a positive integer", 403)
if not request.form.get("shares"):
return apology("must provide shares", 403)
#ensure valid symbol
shares = lookup(request.form.get("symbol"))
if shares is None:
return apology("invalid symbol", 403)
#ensure user owns stock
#Select Stock data
stocks = db.execute("SELECT SYMBOL,SUM(NUMSHARES) AS sum1 FROM Transactions WHERE id= :user GROUP BY SYMBOL HAVING SUM(NUMSHARES) >0", user=session["user_id"])
check = 0
line = 0
for s in range(len(stocks)):
if request.form.get("symbol") == stocks[s]["SYMBOL"]:
check = 1
line = s
if check == 0:
return apology("Stock is not owned", 403)
#ensure user owns enough shares to sell
if int(request.form.get("shares")) > stocks[int(line)]["sum1"]:
return apology("Not enough shares to sell", 403)
#lookup stock price
sellprice = shares["price"] * int(request.form.get("shares"))
#document transaction
db.execute("INSERT INTO Transactions (id, SYMBOL, PRICE, NUMSHARES, TRANSPRICE, BUYSELL) VALUES (:user,:symbol,:price,:numshares,:transprice, 'Sell')", user=session["user_id"], symbol=request.form.get("symbol"), price=shares["price"], numshares=request.form.get("shares"),transprice=sellprice)
#lookup available cash
cash = db.execute("SELECT cash FROM users WHERE id = :user", user=session["user_id"])
#increse cash value in users
newcash = cash[0]["cash"] + sellprice
db.execute("UPDATE users SET cash = :newcash WHERE id = :user", newcash=newcash, user=session["user_id"])
#return to sell
return render_template("sell.html")
# User reached route via GET (as by clicking a link or via redirect)
else:
return render_template("sell.html")
@app.route("/deposit", methods=["GET", "POST"])
@login_required
def deposit():
"""Deposit Cash"""
# User reached route via POST (as by submitting a form via POST)
if request.method == "POST":
# Ensure symbol was submitted
if not request.form.get("deposit"):
return apology("must provide deposit", 403)
#Select Cash Balance
oldcash = db.execute("SELECT cash FROM users WHERE id = :user", user=session["user_id"])
#Find New Balance
newcash = int(oldcash[0]["cash"]) + int(request.form.get("deposit"))
#Update Table
db.execute("UPDATE users SET cash = :newcash WHERE id = :user", newcash=newcash, user=session["user_id"])
#Return
return render_template("deposit.html")
# User reached route via GET (as by clicking a link or via redirect)
else:
return render_template("deposit.html")
def errorhandler(e):
"""Handle error"""
return apology(e.name, e.code)
# listen for errors
for code in default_exceptions:
app.errorhandler(code)(errorhandler)
check50 cs50/2018/x/finance
from the CS50 IDE v157 on this application.py and did not receive an error onlogging in as registered user
. I checked the cs50 status page; there is no indication there has been any recent problems with check50. Maybe a check50 hiccup? I avoid this advice whenever possible, but I think "try again" is the next thing to do. If the problem "goes away" Yay! If the problem persists, I believe you can email[email protected]
(however it is a holiday in US....)lookup
sometimes returns aNone
if the API does not work for whichever reason (like busy or call quota exceeded), more likely to hit people doing more calls than necessary. You could for example refactor your code inindex
to do a lookup per symbol, not per transaction. Also, current value is nothing one needs to store in the transaction table. If you need to pass the extra info to your template, the result of a database query is mutable (both the list and the dicts within), so you can augment it in between. That last part won't affectlookup
problems, though.