Mark C
Mark C

Reputation: 635

When writing twice to a CSV it works only in a particular order

In the example below I make two objects from a class, then write the details passed in to the CSV file. The objects and CSV file are created just fine, but depending on when I do the write - it will or will not work.

The issue is in the block:

# Create > Write > Create > Write
dave = Character('PC', 'Dave', 'Warrior', 10, 2, 20)
dave.write_to_csv()
dan = Character('PC', 'Dan', 'Wizard', 5, 20, 5)
dan.write_to_csv()

In the above order 'dan' is never added to the CSV. However, if I change it to the below, both are written as desired:

# Create > Create > Write > Write
dave = Character('PC', 'Dave', 'Warrior', 10, 2, 20)
dan = Character('PC', 'Dan', 'Wizard', 5, 20, 5)
dave.write_to_csv()
dan.write_to_csv()

What is the problem here?

Full code:

import csv

class Character(object):
    def __init__(self, type, name, character_class, health, mana, strength):
        self.type = type
        self.name = name
        self.character_class = character_class
        self.health = health
        self.mana = mana
        self.strength = strength
        print('New character made')

        with open('character_file.csv', 'w') as character_file:
            character_writer = csv.writer(character_file)
            character_writer.writerow(['Type', 'Name', 'Class', 'Health', 'Mana', 'Strength'])

    def write_to_csv(self):
        with open('character_file.csv', 'a') as character_file:
            fields = [self.type, self.name, self.character_class, self.health, self.mana, self.strength]
            character_writer = csv.writer(character_file)
            character_writer.writerow(fields)
            print(f"{self.name} added to the Character Sheet.")
            # character_file.close() <-- shouldn't be needed as 'with' contains a finally > close?


# Create > Write > Create > Write
# Creating the Character then writing to the CSV works for Dave, but Dan is NOT written
dave = Character('PC', 'Dave', 'Warrior', 10, 2, 20)
dave.write_to_csv()
dan = Character('PC', 'Dan', 'Wizard', 5, 20, 5)
dan.write_to_csv()

# Create > Create > Write > Write
# Creating BOTH Characters then writing to the CSV works for BOTH
#dave = Character('PC', 'Dave', 'Warrior', 10, 2, 20)
#dan = Character('PC', 'Dan', 'Wizard', 5, 20, 5)
#dave.write_to_csv()
#dan.write_to_csv()

Upvotes: 0

Views: 167

Answers (1)

Sparkofska
Sparkofska

Reputation: 1320

Each time you call the constructor of Character, the header is written to the csv file and all contents of the file are discarded. Try to write header only once. In another answer of mine there is a write function, which writes the header only if not already written.

Try it like this:

class Character(object):
    def __init__(self, type, name, character_class, health, mana, strength):
        self.type = type
        ...
        print('New character made')

    def write_to_csv(self):
        filename = 'character_file.csv'
        # write header if not already written
        if not os.path.exists(filename) or os.stat(filename).st_size == 0:
            with open(filename, 'w') as character_file:
                character_writer = csv.writer(character_file)
                character_writer.writerow(['Type', 'Name', 'Class', 'Health', 'Mana', 'Strength'])

        # write character line
        with open(filename, 'a') as character_file:
            fields = [self.type, self.name, self.character_class, self.health, self.mana, self.strength]
            character_writer = csv.writer(character_file)
            character_writer.writerow(fields)
            print(f"{self.name} added to the Character Sheet.")

Upvotes: 1

Related Questions