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

基于姓名生日CSV文件查找下一个过生日者的Python函数报错排查

问题:排查Python生日查询函数的局部未绑定错误并修正

我们需要实现一个Python函数,基于包含姓名与生日的CSV文件,找出指定日期后下一个过生日的人。但当前编写的函数持续出现局部未绑定错误,无法正常运行。

提供的信息

  1. 示例birthdates.csv数据
Draven Brock,01/21/1952
Easton Mclean,09/02/1954
Destiny Pacheco,10/10/1958
Ariella Wood,12/20/1961
Keely Sanders,08/03/1985
Bryan Sloan,04/06/1986
Shannon Brewer,05/11/1986
Julianne Farrell,01/29/2000
Makhi Weeks,03/20/2000
Lucian Fields,08/02/2010
  1. 函数调用示例:nextBirthdate("birthdates.csv", "01/01/2022")
  2. 预期输出:Draven Brock
  3. 当前出错的函数代码:
def nextBirthdate(filename, date):
    f = open(filename, 'r')
    lines = f.readlines()
    f.close()

    for i in range(len(lines)):
        lines[i] = lines[i].strip()

    # split for the target date
    date = line.split('/')
    month = date[0]
    day = date[1]
    diff = 365
    diffDays = 0
    bName = None
        
    bDays = []
    for line in lines:
        items = line.split(",")
        names = items[0]
        # split the date apart between month, day, and year
        bDay = items[1].split("/")
        bDays.append(bDay)

        for d in bDays:
            if bDay[0] == month:
                if bDay[1] > day:
                    diffDays = int(bDay[0]) - int(day)
                if diffdays < diff:
                    diff = diffDays
                    bName = name
            elif bDay[0] > month:
                diffDays = ((int(bDay[0]) - 1) * 31) + int(day)
                if diffDays < diff:
                    diff = diffDays
                    bName = name

    if bName == None:
        return nextBirthdate(filename, "01/01/2022")

    return bName

if __name__ == "__main__":
    filename = "birthdates.csv"
    date = "12/31/2022"
    print(nextBirthdate(filename, date))

错误排查

局部未绑定错误的核心原因:

  1. 未定义变量提前使用:第12行date = line.split('/')中的line变量还未进入循环定义,直接调用会触发NameError。
  2. 变量名拼写错误:第27行diffdays应为diffDays(Python大小写敏感),未定义的diffdays引发NameError。
  3. 变量名不一致:第28行bName = name,但前面定义的是names = items[0],name未定义引发NameError。

此外还有逻辑缺陷:

  • 手动计算天数差忽略了不同月份天数、闰年的差异,结果不准确。
  • 嵌套循环遍历bDays列表,重复计算已处理过的生日,逻辑冗余。
  • 递归调用硬编码年份,无法适配任意目标日期的跨年场景。

修正后的代码

from datetime import datetime

def nextBirthdate(filename, date):
    # 解析目标日期,提取月日信息
    target_date = datetime.strptime(date, "%m/%d/%Y")
    target_month = target_date.month
    target_day = target_date.day
    
    next_person = None
    min_days_diff = float('inf')
    
    # 自动管理文件资源
    with open(filename, 'r') as f:
        for line in f:
            line = line.strip()
            if not line:
                continue
            # 分割姓名与生日,避免姓名含逗号的情况
            name, birth_str = line.split(',', 1)
            birth_date = datetime.strptime(birth_str, "%m/%d/%Y")
            
            # 构造当年的生日日期
            current_year_birth = datetime(target_date.year, birth_date.month, birth_date.day)
            
            # 计算距离目标日期的天数差
            if current_year_birth >= target_date:
                days_diff = (current_year_birth - target_date).days
            else:
                # 当年生日已过,计算下一年的生日差
                next_year_birth = datetime(target_date.year + 1, birth_date.month, birth_date.day)
                days_diff = (next_year_birth - target_date).days
            
            # 更新最近的生日记录
            if days_diff < min_days_diff:
                min_days_diff = days_diff
                next_person = name
    
    return next_person

if __name__ == "__main__":
    filename = "birthdates.csv"
    date = "12/31/2022"
    print(nextBirthdate(filename, date))  # 输出:Draven Brock

代码说明

  • 使用datetime模块处理日期,自动解决闰年、不同月份天数差异问题,计算更准确。
  • 用with语句自动管理文件,无需手动关闭,避免资源泄漏。
  • 遍历每行直接处理,去除冗余嵌套循环,逻辑更清晰。
  • 分别处理生日在目标日期前后的情况,自动适配跨年场景,无需硬编码年份。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 10:01:24