Home > Software design >  How can I prevent my JSON file from getting overwritten in Python?
How can I prevent my JSON file from getting overwritten in Python?

Time:09-01

I am currently building a school homework project - a contact manager, using classes in Python.

I was able to assemble all the needed parts to make my code work, yet upon exiting the program with Terminal, the data inside of my JSON file keep being overwritten.

I've tried changing the with open attribute to "w" and "a", sadly nothing works.

Main Code:

from colorama import Fore, Style
from LoadAndSave import load_file, save_file
from ContactBook import ContactBook

contacts = []
DATA_FILE = "contactbook.json"

def menu():
    print(Fore.RED   "Welcome to Contacts Manager v2.0.0!"   Style.RESET_ALL)
    print(Fore.LIGHTCYAN_EX   "Please enter your selection according to the menu."   Style.RESET_ALL)
    print("a - Add a contact")
    print("r - Remove a contact")
    print("s - Search for a contact")
    print("p - Print a list of all contacts")
    print("x - Exit")
    user_selection = input(Fore.GREEN   "Your selection: "   Style.RESET_ALL)
    return user_selection

def main():
    load_file(DATA_FILE)
    contactbook = ContactBook()
    user_selection = ""
    while user_selection != "x":
        user_selection = menu() # As long as user did not select "x", program will always run. 
        if user_selection == "a":
            contactbook.add_contact(input("Please enter contact's name: "), int(input("Please enter contact's number: ")))
        if user_selection == "r":
            contactbook.remove_contact(contactbook.search_contact(input("Contact's Name? ")))
        if user_selection == "s": 
            contactbook.search_contact(input("Contact's name?"))
            print(Fore.GREEN   "Success!"   Style.RESET_ALL)
        if user_selection == "p":
            print(contactbook)
            print(Fore.GREEN   "Success!"   Style.RESET_ALL)
    print(Fore.MAGENTA   "Thank you for using my software. Bye!")
    save_file(contactbook.make_contact_json(), DATA_FILE)
            

if __name__ == "__main__":
    main()

Load and save:

import json

def load_file(DATA_FILE): # Loading JSON file with all information
    with open (DATA_FILE) as file:
        return json.load(file)

def save_file(json_list, DATA_FILE): 
    with open (DATA_FILE, "w") as file: 
        json.dump(json_list, file, indent = 4)

Contact & ContactBook classes:

import json

class Contact:
    name = ""
    tel = 0

    def __init__(self, name = "", tel = 0):
        self.name = name
        self.tel = tel

    def __str__(self):
        return json.dumps({"contact_info":[{"name": self.name, "tel": self.tel}]})
from colorama import Fore, Style, Back
from Contact import Contact
import json

class ContactBook:
    contacts = []

    def __init__(self):
        pass

    def add_contact(self, name = "", tel = 0):
        self.contacts.append(Contact(name, tel))
        print(Fore.GREEN   "Success!"   Style.RESET_ALL)

    def remove_contact(self, contact_name):
        self.contacts.remove(contact_name)
        print(Fore.RED   "Removed.\n"   Style.RESET_ALL)

    def search_contact(self, contact_name):
        for contact in self.contacts:
            if type(contact) is Contact:
                if contact.name == contact_name:
                    return contact
        return (Back.RED   "\nThere is no contact with that name."   Style.RESET_ALL   "\n")
    
    def make_contact_json(self):
        result = []
        for contact in self.contacts:
            result.append(json.loads(contact.__str__()))
        return result

    def __str__(self) -> str:
        result = ""
        for contact in self.contacts:
            result  = contact.__str__()
        return result

JSON File:

[
    [
        {
            "name": "sdfgh",
            "tel": 654321
        }
    ]
]

Thanks in advance to all helpers!

CodePudding user response:

Your contacts are getting overwritten because every time you run your program, you are creating a fresh ContactBook

contactbook = ContactBook() # In your Main Code

This in turn initializes an empty contacts list

contacts = [] # Inside Class ContactBook

I suggest that you add an __init__ logic to you ContactBook Class that initialises your contacts list with the existing ones

Something Like

class ContactBook:

   def __init__(self, existing_contacts=None):
      self.contacts = [] if existing_contacts is None else existing_contacts

Also while creating the ContactBook object in you main code please pass the existing contacts.

try:
   existing_contacts = load_file(DATA_FILE)
except FileNotFoundError:
   existing_contacts = None
contactbook = ContactBook(existing_contacts)

Also please make sure that you are saving the contacts correctly. It seems to currently be a list of list of objects where as it should ideally be a list of objects

Hope you get good grades. Peace out.

  • Related