Reading and writing a csv file with header

I am trying to complete a task to read a csv file which is a list of a dictionary of names and houses, then write it to another csv file with first name and last name placed in correct order. I am also trying to place a header at the top of the written csv file. I think my problem is knowing when DictWriter is open or closed. Please help and thank you.

#(before.csv)
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
# (Scourgify.py)
import sys
import csv

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

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

if (sys.argv[1]).endswith(".csv") == False:
    sys.exit("Not a csv file")

try:
    file = open (sys.argv[1], "r")
    file.close()
except FileNotFoundError:
    sys.exit(f"Could not read {sys.argv[1]}")
else:
    with open(sys.argv[1], newline='')as csvfile:
        reader = csv.DictReader(csvfile)
        for student in reader:
            last_name, first_name = student['name'].split(",")
            house = student['house']

            with open("after.csv", "a", newline='') as file:
                writer = csv.DictWriter(file, fieldnames = ["first name", "last name", "house"])
                writer.writerow({"first name": first_name, "last name": last_name, "house": house})

            with open("after.csv", "a", newline='') as file:
                writer = csv.DictWriter(file, fieldnames = ["first name", "last name", "house"])
                writer.writeheader()

Skipping to your output step:

with open(sys.argv[1], newline='')as csvfile:
    reader = csv.DictReader(csvfile)
    for student in reader:
        last_name, first_name = student['name'].split(",")
        house = student['house']

        with open("after.csv", "a", newline='') as file:
            writer = csv.DictWriter(file, fieldnames = ["first ame", 
            last name", "house"])
            writer.writerow({"first name": first_name, "last name": last_name, "house": house})

        with open("after.csv", "a", newline='') as file:
            writer = csv.DictWriter(file, fieldnames = ["first name", "last name", "house"])
            writer.writeheader()

Two thing immediately come to mind: you’re writing the header after the
data line, and in fact writing it every time. Have you looked at the
output data file in something as simple as a text editor?

I would be opening the output only once, myself. Example structure,
untested:

with open(sys.argv[1], newline='')as csvfile:
    reader = csv.DictReader(csvfile)
    with open("after.csv", "a", newline='') as file:
        writer = csv.DictWriter(file, fieldnames = ["first name", "last name", "house"])
        writer.writeheader()
        for student in reader:
            last_name, first_name = student['name'].split(",")
            house = student['house']
            writer.writerow({"first name": first_name, "last name": last_name, "house": house})

So in the above you do these steps exactly once before writing any data
lines:

  • open the output file
  • make a DictWriter
  • write the header line

Then you can just loop over the input data and write output data rows,
one for each.

Cheers,
Cameron Simpson cs@cskk.id.au

Thank you for your help. Much appreciated. It works now.