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

CS50 Scourgify问题:程序输出符合预期却测试失败求助

CS50 Scourgify问题排查

问题描述

我正在解决CS50的scourgify问题,before.csv文件包含name和house两列,任务是将name列拆分为first和last独立列,然后生成包含first、last、house的新CSV文件。程序输出看起来符合预期,但测试时收到错误提示::( scourgify.py cleans short CSV file,原因是scourgify.py未生成指定格式的CSV,长CSV文件测试也无法进行。

我的代码实现

import sys
import csv


def main():
    if len(sys.argv) >= 4:
        print("Too many command-line arguments")
        sys.exit(1)

    if len(sys.argv) <= 2:
        print("Too few command-line arguments")
        sys.exit(1)

    filepath1 = sys.argv[1]
    filepath2 = sys.argv[2]
    if not filepath1.endswith(".csv") or not filepath2.endswith(".csv"):
        print("Not a CSV file")
        sys.exit(1)

    data = read_from_file(filepath1)
    writer = write_to_file(filepath2, data)

def read_from_file(filepath):
    updated_data = []
    try:
        with open(filepath, "r") as file:
            data = csv.DictReader(file)

            for i in data:
                name = i["name"]
                house = i["house"]
                first, last = name.split(", ")
                new_dict = {
                    "first": first,
                    "last": last,
                    "house": house,
                }
                updated_data.append(new_dict)

    except FileNotFoundError:
        print("File does not exist")
        sys.exit(1)

    return updated_data


def write_to_file(filepath, new_data):
    fieldnames = ["first", "last", "house"]
    try:
        with open(filepath, mode="w") as file:
            writer = csv.DictWriter(file, fieldnames=fieldnames)
            writer.writeheader()
            writer.writerows(new_data)

    except FileNotFoundError:
        print("File does not exist")
        sys.exit(1)


if __name__ == "__main__":
    main()

问题分析与解决

核心问题

测试失败的关键原因是姓名拆分逻辑不够稳健:
你使用name.split(", ")拆分姓名,但如果测试用例中存在没有逗号分隔的姓名(比如短CSV里的单个名字),或者姓名格式不符合Last, First的情况,split后得到的元素数量不足2个,会直接触发ValueError,导致程序提前退出,无法生成完整的输出文件,因此测试判定“未生成指定格式的CSV”。

另外,写入CSV时未指定newline=''参数,在Windows环境下可能会生成多余的空行,也可能影响测试结果。

修复方案

  1. 优化姓名拆分逻辑:使用split(", ", 1)限制最多拆分一次,同时处理拆分后元素不足的情况,避免触发异常。
  2. 添加异常捕获:处理CSV列名缺失、格式错误等潜在问题,避免程序意外崩溃。
  3. 优化命令行参数检查:简化判断逻辑,给出更清晰的使用提示。
  4. 修正CSV写入参数:添加newline=''避免多余空行。

修改后的代码

import sys
import csv


def main():
    # 简化命令行参数检查
    if len(sys.argv) != 3:
        print("Usage: python scourgify.py input.csv output.csv")
        sys.exit(1)

    input_path = sys.argv[1]
    output_path = sys.argv[2]

    if not input_path.endswith(".csv") or not output_path.endswith(".csv"):
        print("Not a CSV file")
        sys.exit(1)

    data = read_from_file(input_path)
    write_to_file(output_path, data)


def read_from_file(filepath):
    updated_data = []
    try:
        with open(filepath, "r") as file:
            reader = csv.DictReader(file)
            # 检查必要列是否存在
            required_columns = {"name", "house"}
            if not required_columns.issubset(reader.fieldnames):
                missing = required_columns - set(reader.fieldnames)
                print(f"Missing required columns: {', '.join(missing)}")
                sys.exit(1)

            for row in reader:
                name = row["name"].strip()
                house = row["house"].strip()
                # 稳健拆分姓名,最多拆分一次
                name_parts = name.split(", ", 1)
                if len(name_parts) == 2:
                    last_name, first_name = name_parts
                    first_name = first_name.strip()
                else:
                    # 处理无逗号的情况,默认将全名设为last_name
                    last_name = name_parts[0].strip()
                    first_name = ""

                updated_data.append({
                    "first": first_name,
                    "last": last_name,
                    "house": house
                })

    except FileNotFoundError:
        print("File does not exist")
        sys.exit(1)

    return updated_data


def write_to_file(filepath, new_data):
    fieldnames = ["first", "last", "house"]
    try:
        # 添加newline=''避免Windows下多余空行
        with open(filepath, mode="w", newline='') as file:
            writer = csv.DictWriter(file, fieldnames=fieldnames)
            writer.writeheader()
            writer.writerows(new_data)

    except Exception as e:
        print(f"Error writing file: {e}")
        sys.exit(1)


if __name__ == "__main__":
    main()

关键修改点说明

  • 用len(sys.argv) !=3替代原来的两次判断,直接提示正确的命令格式。
  • 检查CSV是否包含name和house列,提前报错避免后续KeyError。
  • 使用split(", ",1)限制拆分次数,确保即使姓名中包含多个逗号也只会拆分一次。
  • 处理无逗号的姓名情况,避免触发ValueError。
  • 写入CSV时添加newline='',符合csv模块的官方推荐用法,避免跨平台换行问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 19:40:12