1

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

2
  • 1
    because you are using 'w' when you open your file instead of 'a' to append the data Commented Oct 19, 2022 at 18:42
  • Don't call close() on a work manager managed file handle. That's what the work manager is there for. Try opening your file outside the outer for loop Commented Oct 19, 2022 at 18:58

2 Answers 2

1

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:
            result = "Fail"
            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 ========================")

Edit:
Wanted to add a note that if you want to use dictionaries to write to CSV, DictWriter is an apt choice for this.

https://docs.python.org/3/library/csv.html#csv.DictWriter

Sign up to request clarification or add additional context in comments.

Comments

0

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/

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.