CS50 scourgify作业无法通过check50检测求助
问题:scourgify.py本地运行正常但无法通过check50测试
check50测试输出
:( scourgify.py cleans short CSV file Cause scourgify.py does not produce CSV with specified format Log running python3 scourgify.py before.csv after.csv... checking that program exited with status 0... checking that after.csv exists... :| scourgify.py cleans long CSV file Cause can't check until a frown turns upside down
我的代码
import sys import csv def main(): check_command_line_arguments() try: with open(sys.argv[2], "r") as check_file: check_reader = csv.reader(check_file) for row in check_reader: pass except FileNotFoundError: try: with open(sys.argv[2], "a") as new_file: header = True with open(sys.argv[1]) as old_file: old_file = csv.DictReader(old_file) for row in old_file: name = row["name"].replace(" ", "") house = row["house"] first, last = name.split(",") writer = csv.DictWriter(new_file, fieldnames=["first", "last", "house"]) if header == True: writer.writeheader() header = False writer.writerow({"first": first, "last": last, "house": house}) except FileNotFoundError: sys.exit(f"Could not read {sys.argv[1]}") def check_command_line_arguments(): if len(sys.argv) < 3: sys.exit("To few command-line arguments") if len(sys.argv) > 3: sys.exit("To many command-line arguments") if not sys.argv[2].endswith(".csv"): sys.exit("The new file is not a CSV file") if __name__ == "__main__": main()
生成的after.csv内容
first,last,house Abbott,Hannah,Hufflepuff Bell,Katie,Gryffindor Bones,Susan,Hufflepuff Boot,Terry,Ravenclaw Brown,Lavender,Gryffindor Bulstrode,Millicent,Slytherin Chang,Cho,Ravenclaw Clearwater,Penelope,Ravenclaw Crabbe,Vincent,Slytherin Creevey,Colin,Gryffindor Creevey,Dennis,Gryffindor Diggory,Cedric,Hufflepuff Edgecombe,Marietta,Ravenclaw Finch-Fletchley,Justin,Hufflepuff Finnigan,Seamus,Gryffindor Goldstein,Anthony,Ravenclaw Goyle,Gregory,Slytherin Granger,Hermione,Gryffindor Johnson,Angelina,Gryffindor Jordan,Lee,Gryffindor Longbottom,Neville,Gryffindor Lovegood,Luna,Ravenclaw Lupin,Remus,Gryffindor Malfoy,Draco,Slytherin Malfoy,Scorpius,Slytherin Macmillan,Ernie,Hufflepuff McGonagall,Minerva,Gryffindor Midgen,Eloise,Gryffindor McLaggen,Cormac,Gryffindor Montague,Graham,Slytherin Nott,Theodore,Slytherin Parkinson,Pansy,Slytherin Patil,Padma,Gryffindor Patil,Parvati,Gryffindor Potter,Harry,Gryffindor Riddle,Tom,Slytherin Robins,Demelza,Gryffindor Scamander,Newt,Hufflepuff Slughorn,Horace,Slytherin Smith,Zacharias,Hufflepuff Snape,Severus,Slytherin Spinnet,Alicia,Gryffindor Sprout,Pomona,Hufflepuff Thomas,Dean,Gryffindor Vane,Romilda,Gryffindor Warren,Myrtle,Ravenclaw Weasley,Fred,Gryffindor Weasley,George,Gryffindor Weasley,Ginny,Gryffindor Weasley,Percy,Gryffindor Weasley,Ron,Gryffindor Wood,Oliver,Gryffindor Zabini,Blaise,Slytherin
问题分析与修复方案
核心问题点
- 输出文件模式错误:使用
"a"追加模式而非"w"写入模式,若after.csv已存在,会在原有内容后追加新数据,导致CSV格式混乱(重复表头、多余行),这是check50检测到格式错误的主要原因。 - 输入文件后缀未校验:仅检查输出文件为
.csv,未校验输入文件格式,不符合题目要求。 - 名字处理逻辑错误:用
replace(" ", "")移除所有空格,会破坏包含空格的合法名字(如"van der Sar, Edwin"会变成"vanderSar,Edwin"),正确做法应该是分割后去除前后空格。 - 循环内重复创建Writer对象:每次循环都实例化
DictWriter,冗余且可能引发潜在问题。 - 命令行参数提示拼写错误:
To few和To many应为Too few和Too many。
修复后的代码
import sys import csv def main(): check_command_line_arguments() # 直接以写入模式打开输出文件,覆盖原有内容 try: with open(sys.argv[1], "r") as old_file, open(sys.argv[2], "w") as new_file: reader = csv.DictReader(old_file) # 提前创建Writer对象,指定字段名 writer = csv.DictWriter(new_file, fieldnames=["first", "last", "house"]) writer.writeheader() for row in reader: # 分割名字,去除前后空格而非所有空格 last, first = row["name"].split(",") first = first.strip() last = last.strip() writer.writerow({ "first": first, "last": last, "house": row["house"] }) except FileNotFoundError: sys.exit(f"Could not read {sys.argv[1]}") def check_command_line_arguments(): if len(sys.argv) != 3: sys.exit("Too few or too many command-line arguments") # 同时校验输入和输出文件的后缀 if not sys.argv[1].endswith(".csv") or not sys.argv[2].endswith(".csv"): sys.exit("Both files must be CSV files") if __name__ == "__main__": main()
修复说明
- 改用
"w"模式打开输出文件,确保每次运行都生成全新的正确格式CSV。 - 同时校验输入和输出文件的
.csv后缀,符合题目要求。 - 调整名字处理逻辑:通过
split(",")分割后用strip()去除前后空格,保留名字内部的合法空格。 - 将
DictWriter的创建移至循环外,提升效率并避免冗余。 - 修正命令行参数提示的拼写错误,使提示更规范。
内容的提问来源于stack exchange,提问作者Matt
相关产品推荐
相关产品推荐

