Good day,
The purpose of my script is to create a small dictionary that is saved to a file using pickle and print the entire contents of the dictionary for the user. My script prompts the user to make 1 of 3 choices:
Selection 1 is intended to print all contents of a dictionary loaded using pickle. Selection 2 appends to the existing dictionary and prints what was appended. Selection 3 creates a file and adds an entry into it.
When I select option 1, only the first entry prints.
When I use select option 2, I can add an entry and I can see that entry in the file that is in the same folder as the script. I am unsure what type of file it is. I can open with notepad though. The new entry also prints.
I only select option 3 once, to create the file. It adds the first entry and prints it successfully.
I need help getting the entire contents of the dictionary to print.
print("""\n
1- View codes
2- Add code
3- Create file/add first""")
while True:
choice = input("What is your choice?")
DC_Message = {}
if choice == "1":
filename = "dcoutput"
infile = open(filename, 'rb')
DC_Message2 = pickle.load(infile)
infile.close()
for key, value in DC_Message2.items():
print(key, ' : ', value)
elif choice == "2":
DCcode = str(input("What is the new DCcode?"))
Message = str(input("What is the new message"))
DC_Message[DCcode] = Message
print(DC_Message)
for key, value in DC_Message.items():
outfile = open("dcoutput", 'ab')
pickle.dump(DC_Message, outfile)
outfile.close()
print(key, ' : ', value)
elif choice == "3":
DCcode = str(input("What is the new DCcode?"))
Message = str(input("What is the new message"))
DC_Message[DCcode] = Message
print(DC_Message)
for key, value in DC_Message.items():
outfile = open("dcoutput", 'wb')
pickle.dump(DC_Message, outfile)
outfile.close()
print(key, ' : ', value)
CodePudding user response:
Trying to read between the lines here since it's not 100% clear what you are trying to do.
- Because there is just one object in the pickle (a dictionary) you can only read the pickle into a dictionary object or write the dictionary to the pickle.
- I think you are confusing appending to the dictionary with reading/writing (loading/dumping) to the pickle.
- You loop through every entry in the dictionary and then in that loop you dump the dictionary to the pickle file over and over and over again. No need for a loop here, just dump the dictionary to the pickle file.
Consider the following code change:
import pickle
print("""\n
1- Load Codes from File
2- Add code
3- Save Codes to file
4- Exit program""")
#initialize dictionary outside of the loop.
DC_Message = {}
filename = "dcoutput"
while True:
choice = input("What is your choice?")
#LOAD dictionary from pickle file
if choice == "1":
print("Loading DC info from file")
#open the pickle file, and load it to our dictionary
infile = open(filename, 'rb')
DC_Message = pickle.load(infile)
infile.close()
for key, value in DC_Message.items():
print(key, ' : ', value)
#ADD to the dictionary (but don't save to pickle)
elif choice == "2":
#get input from user
DCcode = str(input("What is the new DCcode?"))
Message = str(input("What is the new message"))
#Add input to dictionary
DC_Message[DCcode] = Message
#print out each entry in the dictionary
for key, value in DC_Message.items():
print(key, ' : ', value)
#SAVE the dictionary to pickle file
elif choice == "3":
print("Writing to pickle file", DC_Message)
#open pickle file for writing and dump the dictionary
outfile = open(filename, 'wb')
pickle.dump(DC_Message, outfile)
outfile.close()
print("Pickle file written")
#exit program
elif choice =="4":
print("leaving program, hope you saved (option 3)")
break
Option 1 loads the dictionary from the pickle. I changed this to use your DC_Message
dictionary since that's the dictionary this code is working with.
Option 2 appends new entries to the dictionary (not the pickle).
Option 3 merely saves the dictionary to the pickle.
CodePudding user response:
Pickle does not save just dict data. It saves whole objects and one file should be used to store one pickle's dump. You cannot just append to it, like with simple text files, that's why you get only one item.
To make the code work as you described it, you should:
-Use pickle to dump dict.
-Use pickle to load dict from pickle file
-Append to dict using just dict[key] = value
-Save modified dict again using pickle.dump.
I have modified your code and I think it works the way you wanted:
import pickle
print("""\n
1- View codes
2- Add code
3- Create file/add first""")
FILENAME = "dcoutput"
while True:
choice = input("What is your choice?")
DC_Message = {}
if choice == "1":
try:
infile = open(FILENAME, 'rb')
DC_dict = pickle.load(infile)
print(DC_dict) # Printout whole dict
infile.close()
for key, value in DC_dict.items(): # Your custom printout loop
print(key, ' : ', value)
except FileNotFoundError:
print(f"Make {FILENAME} file before reading! (choice: 2)")
elif choice == "2":
DCcode = str(input("What is the new DCcode?"))
Message = str(input("What is the new message"))
# Try to load old dict, if FileNotFound, make new empty one.
try:
with open(FILENAME, 'rb') as file:
old_dict = pickle.load(file)
except FileNotFoundError:
old_dict = {}
old_dict[DCcode] = Message # Append new data
print(old_dict) # Print all data to check if all working properly.
# Overwrite file with new data
with open(FILENAME, "wb") as file:
pickle.dump(old_dict, file)
elif choice == "3":
DCcode = str(input("What is the new DCcode?"))
Message = str(input("What is the new message"))
new_dict = {DCcode: Message}
# Create (or overwrite if already exist) pickle file.
with open(FILENAME, "wb") as file:
pickle.dump(new_dict, file)