Home > Software design >  Printing Values to CSV (Python)
Printing Values to CSV (Python)

Time:10-20

I am trying to send the failed values to a CSV file but it's only giving me the last failed value in the list.

print(("Folder\t"  "Expected\t"  "Actual\t" "Result").expandtabs(20))

for key in expected:
    expectedCount = str(expected[key])
    actualCount = "0"
    if key in newDictionary:
         actualCount = str(newDictionary[key])

    elif expectedCount == actualCount:
        result = "Pass"

    else:
        result = "Fail"
        with open('XML Output.csv', 'w',encoding='utf-8', newline="") as csvfile:

            header = ['Folder', 'Expected', 'Actual','Result']
            my_writer = csv.writer(csvfile)
            my_writer.writerow(header)
            my_writer.writerow([key, expectedCount, actualCount, result])

        csvfile.close()

    print((key   "\t" expectedCount   "\t" actualCount   "\t" result).expandtabs(20))

print("======================== Data Exported to CSV file ========================")

Output:

Folder Expected Actual Result

D 2 1 Fail

Here is what the output should be:

Folder Expected Actual Result

A 2 1 Fail

B 2 1 Fail

C 2 1 Fail

D 2 1 Fail

CodePudding user response:

This is because each iteration of with open using w is overwriting the file, leaving only the last iteration at the end of it. You could use a for append.

A better method may be to create a data structure to hold the failures and write to the file simultaneously. Give the below a try. I couldn't test it without initial data, but I think you'll get what I was going for.

print(("Folder\t"  "Expected\t"  "Actual\t" "Result").expandtabs(20))
    
    failures = []
    for key in expected:
        expectedCount = str(expected[key])
        actualCount = "0"
        if key in newDictionary:
            actualCount = str(newDictionary[key])
    
        elif expectedCount == actualCount:
            result = "Pass"
    
        else:
            csv_row = {
                "Folder":key,
                "Expected":expectedCount,
                "Actual":actualCount,
                "Result":"Fail"
            }

            failures.append(csv_row)
    
        print((key   "\t" expectedCount   "\t" actualCount   "\t" result).expandtabs(20))

    try:
        with open('XML Output.csv', 'w') as csvfile:
            writer = csv.DictWriter(csvfile, fieldnames=failures[0].keys())
            writer.writeheader()
            for data in failures:
                    writer.writerow(data)
    except IOError:
        print('I/O Error on CSV export')
    
    print("======================== Data Exported to CSV file ========================")

CodePudding user response:

you're recreating the csv file upon every iteration that hits the else branch. You need to move the with statement out of your loop:

import csv

expected = {"a": 1, "b": 2}
newDictionary = {"a": 2, "c": 2}

with open('XML Output2.csv', 'w', encoding='utf-8', newline="") as csvfile:
    header = ['Folder', 'Expected', 'Actual', 'Result']
    my_writer = csv.writer(csvfile)
    my_writer.writerow(header)

    for key in expected:
        expectedCount = str(expected[key])
        actualCount = "0"
        if key in newDictionary:
            actualCount = str(newDictionary[key])
        if expectedCount == actualCount:
            result = "Pass"
        else:
            result = "Fail"
            my_writer.writerow([key, expectedCount, actualCount, result])

    print((key   "\t"   expectedCount   "\t"   actualCount   "\t"   result).expandtabs(20))

print("======================== Data Exported to CSV file ========================")

Also, note that you do not need to invoke close() explicitly on a file that was created using a context manager (with). See this article for more on the matter: https://realpython.com/python-with-statement/

  • Related