Home > database >  Unable to pass CS50 check for scourgify problem set 6
Unable to pass CS50 check for scourgify problem set 6

Time:11-02

I am unable to pass the test even though, my code works perfectly When I checked,

Below is my code..

import sys
import csv

def main():
    n, m = passing_arg()
    read_file(n, m)

def passing_arg():
    if len(sys.argv) > 3:
        sys.exit("Too many command-line arguments")

    elif len(sys.argv) < 3:
        sys.exit("Too few command-line arguments")

    elif sys.argv[1].endswith(".csv") == False or sys.argv[2].endswith(".csv") == False:
        sys.exit("Not a CSV file")

    else:
        x = sys.argv[1]
        y = sys.argv[2]
        return x, y

def read_file(x, y):
    try:
        with open(x) as file:
            content = csv.DictReader(file)
            print(type(content))
            add_header = True
            for row in content:
                last, first = row["name"].split(", ")

            with open(y, "a") as f:
                fieldnames = ['First', 'Last', 'House']
                content1 = csv.DictWriter(f, fieldnames=fieldnames)
                if add_header:
                    content1.writeheader()
                    add_header = False
                 content1.writerow({fieldnames[0] : first, fieldnames[1] : last, fieldnames[2] : row["house"]})


    except FileNotFoundError:
        sys.exit(f"Could not read {x}")


if __name__ == "__main__":
    main()

I am not ignoring a whitespace as well. This is where my code fails: link

BEFORE:

name,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

AFTER:

First,Last,House
Hannah,Abbott,Hufflepuff
Katie,Bell,Gryffindor
Susan,Bones,Hufflepuff
Terry,Boot,Ravenclaw
Lavender,Brown,Gryffindor
Millicent,Bulstrode,Slytherin
Cho,Chang,Ravenclaw
Penelope,Clearwater,Ravenclaw
Vincent,Crabbe,Slytherin
Colin,Creevey,Gryffindor
Dennis,Creevey,Gryffindor
Cedric,Diggory,Hufflepuff
Marietta,Edgecombe,Ravenclaw
Justin,Finch-Fletchley,Hufflepuff
Seamus,Finnigan,Gryffindor
Anthony,Goldstein,Ravenclaw
Gregory,Goyle,Slytherin
Hermione,Granger,Gryffindor
Angelina,Johnson,Gryffindor
Lee,Jordan,Gryffindor
Neville,Longbottom,Gryffindor
Luna,Lovegood,Ravenclaw
Remus,Lupin,Gryffindor
Draco,Malfoy,Slytherin
Scorpius,Malfoy,Slytherin
Ernie,Macmillan,Hufflepuff
Minerva,McGonagall,Gryffindor
Eloise,Midgen,Gryffindor
Cormac,McLaggen,Gryffindor
Graham,Montague,Slytherin
Theodore,Nott,Slytherin
Pansy,Parkinson,Slytherin
Padma,Patil,Gryffindor
Parvati,Patil,Gryffindor
Harry,Potter,Gryffindor
Tom,Riddle,Slytherin
Demelza,Robins,Gryffindor
Newt,Scamander,Hufflepuff
Horace,Slughorn,Slytherin
Zacharias,Smith,Hufflepuff
Severus,Snape,Slytherin
Alicia,Spinnet,Gryffindor
Pomona,Sprout,Hufflepuff
Dean,Thomas,Gryffindor
Romilda,Vane,Gryffindor
Myrtle,Warren,Ravenclaw
Fred,Weasley,Gryffindor
George,Weasley,Gryffindor
Ginny,Weasley,Gryffindor
Percy,Weasley,Gryffindor
Ron,Weasley,Gryffindor
Oliver,Wood,Gryffindor
Blaise,Zabini,Slytherin

I noticed even the whitespaces between the names that are separated by commas in before.csv. but still unable to pass the test.

CodePudding user response:

I ran your code with before.csv and I get this in after.csv:

First,Last,House
Blaise,Zabini,Slytherin

I'm not sure if that's what the automatic checker is unhappy about, though:

:( 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...

Back to the issue of me only getting one line of output in the CSV, it could be that your copy-paste of the code introduced an indentation error that changes the meaning of your program and only one row is written to the output CSV. If you look back at the code you posted and the indentation matches what you expect, then you need to reconsider how you read, process, and write rows.

For my own daily use of the Python csv module, I like to read all my rows into one list, then process the rows, then write them out. Something like this:

all_rows = []
with open("before.csv", newline="") as f:
    reader = csv.DictReader(f)
    all_rows = list(reader)

processed_rows = []
for row in all_rows:
    pass  # Do something with row and build up processed_rows


with open("after.csv", "w", newline="") as f:
    writer = csv.DictWriter(f, fieldnames=processed_rows[0])
    writer.writeheader()
    writer.writerows(processed_rows)

Appending to a CSV can get messy, so I try to avoid that by making sure all my rows are ready before I write.

Good luck! :)

CodePudding user response:

There are 3 errors in the code you posted. Based on your "works perfectly" comment I think the first 1 might be a formatting error when you copied your code into the question. The other 2 errors need to be addressed for your code to pass. (FYI, when I fixed all 3 errors, check50 passed.) The errors are:

  1. Incorrect indention when opening file and writing
  2. Header line is incorrect (wrong case)
  3. Incorrect use of file mode "a" when opening write file

A detailed explanation for each is provided below.

1. Incorrect indention (see lines 32-38). @Zach Young's answer shows the error with your indentation (as posted). The "before" file is opened, all lines are read, THEN the "after" file is opened and only 2 lines are written (the header and last line).

for row in content:
    last, first = row["name"].split(", ")

    with open(y, "a") as f:
        fieldnames = ['First', 'Last', 'House']
        content1 = csv.DictWriter(f, fieldnames=fieldnames)
        if add_header:
            content1.writeheader()
            add_header = False
            content1.writerow({fieldnames[0] : first, fieldnames[1] : last, fieldnames[2] : row["house"]})

2. Header line case. This one is simple. Read the instructions to confirm.

fieldnames = ['First', 'Last', 'House']
should be:
fieldnames = ['first', 'last', 'house']

3. Using file mode "a" incorrectly. This is a subtle error. You won't detect the error if you only run your program once. Run it twice with the same command line filenames, and your "after" file will be twice as long. This happens because append mode keeps adding to an existing file.
There are multiple ways to address this. You could use a file mode variable like add_header, or you could use different open() lines depending on the value of add_header. However, the cleanest/simplest way to fix this is to switch your inside and outside loops. Currently you loop on the "before" file then have to open and write to the "after" file after reading each line. Reverse them: open the "after" file first (once), then open the "before" file to read lines from "before" and write to "after". Any of these approaches will work. The key is to NOT append lines to an existing file when you run the program more than once.

As I mentioned above, I fixed all 3 errors, ran check50 and it passed all tests. BTW, when testing says you have an error, you have an error. In other words, the code DOES NOT "work perfectly". It's the developer's responsibility to find and fix them. This requires diligent diagnosis and humility. Good luck.

  • Related