-1

I'm basically creating a contact book, and I want to do it storing data on JSON to practice it. I have sort a code that allows it from a dictionary, but the problem is that when I rerun the script, another dictionary is appended into the existing one, creating a couple of extra braces which throws the error "End of file expected."

This is the code:

import json


new_contacts = {}


def contacts():
    while True:
        name = input("Contact's name: ")
        email = input("Email: ")
        number = input("Phone number: ")
        new_contacts[name] = {"email": email, "number": number}
        
        """cursor.execute(
            'INSERT INTO contacts VALUES (?, ?, ?)',
            (name, email, number)
            )"""
        restart_or_not = input("Continue? y/n ").lower()

        if restart_or_not == "y":
            print(new_contacts)
            continue
        else:
            with open('contact_book.json', 'a') as file:
                json.dump(new_contacts, file, indent=4)
            break


contacts()

And this is a sample of a JSON that comes out from it:

{
    "d": {
        "email": "e",
        "number": "3"
    },
    "h": {
        "email": "y",
        "number": "6"
    },
    "f": {
        "email": "r",
        "number": "3"
    },
    "n": {
        "email": "j",
        "number": "9"
    }
}{
    "g": {
        "email": "j",
        "number": "0"
    }
}

The first four entries don't create any problem because they are appended in the same run, but if I quit the program and rerun it (example "g") then the new dictionary creates the conflict. Any tips?

  • 3
    the issue is that you're appending data to the JSON file, instead of appending data to the JSON structure. One suggestion would be to: 1. when program starts read json file to a variable `new_contacts` 2. append given data to `new_contacts` 3. overwrite the file `contact_book.json` and replace data in file with updated `new_contacts` – Rhymond Mar 07 '22 at 10:54
  • Does this answer your question? [How to add multiple objects into a single array in a json file using Python?](https://stackoverflow.com/questions/60908930/how-to-add-multiple-objects-into-a-single-array-in-a-json-file-using-python) – Gino Mempin Mar 07 '22 at 11:05

2 Answers2

1

One way of doing it, is before adding to the file, you delete the last closing bracket } and before dumping, you cast your dict into a string and remove the first bracket using this your_string[1:].

The other way which I coded for you, is you load the json into a variable, add the new inputs and then re dump it into the file

import json

from os import path # it helps to check if file exists


new_contacts = {}

def contacts():
    while True:
        name = input("Contact's name: ")
        email = input("Email: ")
        number = input("Phone number: ")
        new_contacts[name] = {"email": email, "number": number}
        
        """cursor.execute(
            'INSERT INTO contacts VALUES (?, ?, ?)',
            (name, email, number)
            )"""
        restart_or_not = input("Continue? y/n ").lower()

        if restart_or_not == "y":
            print(new_contacts)
            continue
        else:
            # if the file doesn't exist, write an empty json object into it
            # which will make it easier later to load data from
            if not path.exists('contact_book.json'):
                with open('contact_book.json', 'w+') as file:
                    json.dump({}, file)
            # This loads the data into the variable dict called loaded_data
            with open('contact_book.json', 'r') as file:
                loaded_data = json.load(file)
                for k, v in new_contacts.items():
                    loaded_data[k] = v
            # redumps your data into the json file
            with open('contact_book.json', 'w') as file:
                json.dump(loaded_data, file, indent=4)
            break

contacts()
0

Just updated a bit of the else part of your code. It checks whether a file exists or not. If it exists, the contents of the file is read and updated and then dumped into the file. If it doesn't exist, your old code will be executing.

if os.stat("contact_book.json").st_size != 0:
    with open('contact_book.json', 'r+') as file:
        contents = json.loads(file.read())
        contents.update(new_contacts)
        file.seek(0)
        json.dump(contents, file, indent=4)
else:
        with open('contact_book.json', 'a') as file:
        json.dump(new_contacts, file, indent=4)
        break

Honestly, not an efficient solution. But this should be able to invoke an idea.