You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

CS50 Finance项目:lookup()未返回字典致buy()函数报错

解决CS50 Finance中lookup()返回None导致的TypeError问题

问题核心

报错TypeError: 'NoneType' object is not subscriptable是因为lookup(symbol)返回了None,代码直接尝试访问result["price"]未做任何边界处理。同时buy函数和lookup函数还存在其他潜在问题,以下是分步修复方案:

修复步骤

1. 处理lookup返回None的边界情况

在buy函数调用lookup后,立即检查返回值有效性,无效则提示用户输入正确股票代码:

result = lookup(symbol)
if not result:
    return apology("无效的股票代码", 400)

2. 验证IEX Cloud API配置

  • 确保环境变量API_KEY已正确设置,且是IEX Cloud的有效密钥(注意区分测试密钥和生产密钥)。
  • 替换lookup函数中的API端点:旧的cloud-sse.iexapis.com已不再适用,更新为当前有效端点:
    response = requests.get(f"https://cloud.iexapis.com/v1/stock/{urllib.parse.quote_plus(symbol)}/quote?token={api_key}")
    

3. 修正buy函数中的其他错误

  • cash值获取错误:db.execute返回列表,需提取具体数值:
    cash_row = db.execute("SELECT cash FROM users WHERE id = ?", session["user_id"])
    cash = cash_row[0]["cash"]
    
  • shares类型转换与验证:表单获取的shares是字符串,需转为正整数:
    try:
        shares = int(request.form.get("share_num"))
        if shares <= 0:
            return apology("购买数量必须为正整数", 400)
    except ValueError:
        return apology("请输入有效的购买数量", 400)
    
  • SQL语句语法错误:
    • INSERT语句不能加WHERE子句,正确插入关联用户的股票记录:
      db.execute("INSERT INTO stock(user_id, symbol, name, quantity, price) VALUES (?, ?, ?, ?, ?)",
                 session["user_id"], result["symbol"], result["name"], shares, result["price"])
      
    • UPDATE语句语法修正:
      db.execute("UPDATE users SET cash = ? WHERE id = ?",
                 cash - result["price"] * shares, session["user_id"])
      

完整修正后的代码片段

helpers.py(调整API端点)

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

    # Contact API
    try:
        api_key = os.environ.get("API_KEY")
        # 更新为IEX Cloud当前有效端点
        response = requests.get(f"https://cloud.iexapis.com/v1/stock/{urllib.parse.quote_plus(symbol)}/quote?token={api_key}")
        response.raise_for_status()
    except requests.RequestException:
        return None

    # Parse response
    try:
        quote = response.json()
        return {
            "name": quote["companyName"],
            "price": float(quote["latestPrice"]),
            "symbol": quote["symbol"]
        }
    except (KeyError, TypeError, ValueError):
        return None

app.py(修正buy函数)

def buy():
    if request.method == "GET":
        return render_template("buy.html")

    else:
        symbol = request.form.get("symbol").strip()
        if not symbol:
            return apology("请输入股票代码", 400)
        
        # 处理购买数量
        try:
            shares = int(request.form.get("share_num"))
            if shares <= 0:
                return apology("购买数量必须为正整数", 400)
        except (ValueError, TypeError):
            return apology("请输入有效的购买数量", 400)
        
        # 调用lookup并检查结果
        result = lookup(symbol)
        if not result:
            return apology("无效的股票代码", 400)
        
        # 获取用户当前现金
        cash_row = db.execute("SELECT cash FROM users WHERE id = ?", session["user_id"])
        cash = cash_row[0]["cash"]
        
        # 检查余额是否足够
        total_cost = result["price"] * shares
        if cash < total_cost:
            return apology("余额不足", 403)
        
        # 插入股票记录
        db.execute("INSERT INTO stock(user_id, symbol, name, quantity, price) VALUES (?, ?, ?, ?, ?)",
                   session["user_id"], result["symbol"], result["name"], shares, result["price"])
        
        # 更新用户现金
        db.execute("UPDATE users SET cash = ? WHERE id = ?",
                   cash - total_cost, session["user_id"])
        
        return redirect("/")

额外注意事项

  • 确保stock表包含user_id字段,用于关联用户和股票记录。
  • 测试时优先使用IEX Cloud的测试密钥(以pk_开头),避免产生不必要的费用。

内容的提问来源于stack exchange,提问作者abdul

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 12:12:47