cs50financestockedx

cs50 finance doesn't run


So far, I have finished buy, quote, and the register functions, currently working on the index. I finished writing my index and tried to run the program to check, but I get a 500 internal server error.

This is my error message. enter image description here

I am following Devin Finley's guide, and although I am not done with it so far, my program should still be running. I don't know why I am getting these errors, so ANY help would be appreciated!

Helpers function (left untouched from when I downloaded the folder):

import csv
import datetime
import pytz
import requests
import subprocess
import urllib
import uuid

from flask import redirect, render_template, session
from functools import wraps


def apology(message, code=400):
    """Render message as an apology to user."""
    def escape(s):
        """
        Escape special characters.

        https://github.com/jacebrowning/memegen#special-characters
        """
        for old, new in [("-", "--"), (" ", "-"), ("_", "__"), ("?", "~q"),
                     ("%", "~p"), ("#", "~h"), ("/", "~s"), ("\"", "''")]:
            s = s.replace(old, new)
        return s
    return render_template("apology.html", top=code, bottom=escape(message)), code


def login_required(f):
    """
    Decorate routes to require login.

    http://flask.pocoo.org/docs/0.12/patterns/viewdecorators/
    """
    @wraps(f)
    def decorated_function(*args, **kwargs):
        if session.get("user_id") is None:
            return redirect("/login")
        return f(*args, **kwargs)
    return decorated_function

def lookup(symbol):
    """Look up quote for symbol."""

    # Prepare API request
    symbol = symbol.upper()
    end = datetime.datetime.now(pytz.timezone("US/Eastern"))
    start = end - datetime.timedelta(days=7)

    # Yahoo Finance API
    url = (f"https://query1.finance.yahoo.com/v7/finance/download/{urllib.parse.quote_plus(symbol)}"
        f"?period1={int(start.timestamp())}"
        f"&period2={int(end.timestamp())}"
        f"&interval=1d&events=history&includeAdjustedClose=true"
)

# Query API
try:
    response = requests.get(url, cookies={"session": str(uuid.uuid4())}, headers={"User-Agent": "python-requests", "Accept": "*/*"})
    response.raise_for_status()

    # CSV header: Date,Open,High,Low,Close,Adj Close,Volume
    quotes = list(csv.DictReader(response.content.decode("utf-8").splitlines()))
    quotes.reverse()
    price = round(float(quotes[0]["Adj Close"]), 2)
    return {
        "name": symbol,
        "price": price,
        "symbol": symbol
    }
except (requests.RequestException, ValueError, KeyError, IndexError):
    return None

def usd(value):
    """Format value as USD."""
    return f"${value:,.2f}"

This is my index function in app.py:

@app.route("/")
@login_required
def index():
    """Show portfolio of stocks"""
    #Get user's stocks and shares
     stocks = db.execute("SELECT symbol, SUM (shares) as total_shares FROM transactions WHERE user_id = :user_id GROUP BY symbol HAVING total_shares > 0",
                    user_id=session["user_id"])

#Get user's cash balance
cash = db.execute("SELECT cash FROM users WHERE id = :user_id", user_id=session["user_id"])[0]["cash"]

#Initialize variables for total values
total_value = cash
grand_total = cash

#Iterate over stocks and add price and total value
for stock in stocks:
    quote = lookup(stock["symbol"])
    stock["name"] = quote["name"]
    stock["price"] = quote["price"]
    stock["value"] = stock["price"] * stock["total_shares"]
    total_value += stock["value"]
    grand_total += stock["value"]

return render_template("index.html", stocks=stocks, cash=cash, total_value=total_value, grand_total=grand_total)

This is my index.html:

{% extends "layout.html" %}

{% block title %}
    Portfolio
{% endblock %}

{% block main %}
    <h2>Portfolio</h2>

    <table class="table table-bordered table-striped">
        <thead class="thead-light">
            <tr>
                <th>Symbol</th>
                <th>Name</th>
                <th>Shares</th>
                <th>Price</th>
                <th>Total Value</th>
            </tr>
        </thead>
        <tbody>
            {% for stock in stocks %}
                <tr>
                    <td>{{ stock.symbol }}</td>
                    <td>{{ stock.name }}</td>
                    <td>{{ stock.total_shares }}</td>
                    <td>{{ stock.price }}</td>
                    <td>{{ stock * stock.total_shares }}</td>
                </tr>
            {% endfor %}
            <tr>
                <td colspan="4" align="right">Cash</td>
                <td>{{ cash }}</td>
            </tr>
            <tr>
                <td colspan="4" align="right">Total Value</td>
                <td>{{ total_value }}</td>
            </tr>
        </tbody>
    </table>
{% endblock %}

This is my layout.html:

<head>

    <meta charset="utf-8">
    <meta name="viewport" content="initial-scale=1, width=device-width">

    <!-- http://getbootstrap.com/docs/5.1/ -->
    <link crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" rel="stylesheet">
    <script crossorigin="anonymous" src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p"></script>

    <!-- https://favicon.io/emoji-favicons/money-bag/ -->
    <link href="/static/favicon.ico" rel="icon">

    <link href="/static/styles.css" rel="stylesheet">

    <title>C$50 Finance: {% block title %}{% endblock %}</title>

</head>

<body>

    <nav class="bg-light border navbar navbar-expand-md navbar-light">
        <div class="container-fluid">
            <a class="navbar-brand" href="/"><span class="blue">C</span><span class="red">$</span><span class="yellow">5</span><span class="green">0</span> <span class="red">Finance</span></a>
            <button aria-controls="navbar" aria-expanded="false" aria-label="Toggle navigation" class="navbar-toggler" data-bs-target="#navbar" data-bs-toggle="collapse" type="button">
                <span class="navbar-toggler-icon"></span>
            </button>
            <div class="collapse navbar-collapse" id="navbar">
                {% if session["user_id"] %}
                    <ul class="navbar-nav me-auto mt-2">
                        <li class="nav-item"><a class="nav-link" href="/quote">Quote</a></li>
                        <li class="nav-item"><a class="nav-link" href="/buy">Buy</a></li>
                        <li class="nav-item"><a class="nav-link" href="/sell">Sell</a></li>
                        <li class="nav-item"><a class="nav-link" href="/history">History</a></li>
                    </ul>
                    <ul class="navbar-nav ms-auto mt-2">
                        <li class="nav-item"><a class="nav-link" href="/logout">Log Out</a></li>
                    </ul>
                {% else %}
                    <ul class="navbar-nav ms-auto mt-2">
                        <li class="nav-item"><a class="nav-link" href="/register">Register</a></li>
                        <li class="nav-item"><a class="nav-link" href="/login">Log In</a></li>
                    </ul>
                {% endif %}
            </div>
        </div>
    </nav>

    {% if get_flashed_messages() %}
        <header>
            <div class="alert alert-primary mb-0 text-center" role="alert">
                {{ get_flashed_messages() | join(" ") }}
            </div>
        </header>
    {% endif %}

    <main class="container-fluid py-5 text-center">
        {% block main %}
        {% endblock %}
    </main>

    <footer class="mb-5 small text-center text-muted">
        Data provided by <a href="https://iexcloud.io/">IEX</a>
    </footer>

</body>

Solution

  • Typo in index.html here <td>{{ stock * stock.total_shares }}</td>1 stock is a dict in the list stocks.