Search code examples
pythonpython-3.xsavepicklesaving-data

Issues with pickling in python - items not saving to file once program exits


I am trying to create a python program to save my friends' birthdays and access them easily and check for birthdays each day(I am not great at remembering dates and I never use facebook), but when I add a new birthday it is only accessible until I end the program - it then disappears again. I have been struggling with this for a while now and would really appreciate help fixing the error. Thanks!

import time
import pickle
def main():
        birthday_file = open('birthdays_dict.dat','ab')
        birthday_doc = open('birthdays_dict.dat','rb')
        birthdays = pickle.load(birthday_doc)
        date = time.strftime("%m/%d")
        again = 'y'
        while again.lower() == 'y' or again.lower() == 'yes':
                choice = menu_choice()
                if choice == 1:
                        name = add_name()
                        birthday = add_birthday()
                        birthdays[name] = birthday
                        print(name)
                        print(birthday)
                        pickle.dump(birthdays,birthday_file)
                elif choice == 2:
                        print('Birthdays today(' + date + '):')
                        birth_today = {}
                        for key, value in birthdays.items():
                                if value == date:
                                        print(key)
                elif choice == 3:
                        search_name = input('Enter name to search: ')
                        print()
                        if search_name in birthdays:
                                print(birthdays[search_name])
                                if birthdays[search_name] == date:
                                        print('Their birthday is today!')
                        else:
                                print('Not found')
                else:
                        print('Not a valid selection!')
                print()
                again = go_again()
        birthday_file.close()
        birthday_doc.close()

Solution

  • Your problem is that you keep appending new dicts onto the file instead of replacing the old one, but then at startup you only load the very first one instead of all of them.


    To fix this, you need to change this:

    birthday_file = open('birthdays_dict.dat','ab')
    

    … to this:

    birthday_file = open('birthdays_dict.dat','wb')
    

    But don't do that change on its own, because that will erase the file before you've read the old version!


    You probably want to do something like this at the top of the function:

    with open('birthdays_dict.dat', 'rb') as birthday_doc:
        birthdays = pickle.load(birthday_doc)
    

    I used a with statement so the file will automatically get closed right after the load, so it's definitely safe for us to overwrite it later.

    Then later, when you want to write to the file, that's when you open it in w mode to erase the file and overwrite it with the new version—at which point you might as well close it immediately, because if you ever do write to it again, you're going to want to erase it again first, so let's use with again:

    with open('birthdays_dict.dat', 'wb') as birthday_doc:
        pickle.dump(birthdays, birthday_doc)