Reputation: 53
In the final days of my intro comp sci class, we got to creating dictionaries. A homework program in our book asks us to create something that can look up, add, change, and delete a set of names and email addresses. It asks us to pickle the dictionary, but the kicker for me is that it stipulates that each time the program starts, it should retrieve the dictionary from the file and unpickle it. I don't know if I coded myself into a corner, but I can't figure out how to do this with what I've done so far.
My code:
import mMyUtils
import pickle
LOOK_UP = 1
ADD = 2
CHANGE = 3
DELETE = 4
QUIT = 5
def main():
emails = {}
choice = 0
while choice != QUIT:
choice = getMenuChoice()
if choice == LOOK_UP:
lookUp(emails)
elif choice == ADD:
add(emails)
elif choice == CHANGE:
change(emails)
elif choice == DELETE:
delete(emails)
else:
exit
def getMenuChoice():
print()
print('Name and Email Address Catalog')
print('------------------------------')
print('1. Look up an email address')
print('2. Add a new email address')
print('3. Change an email address')
print('4. Delete an email address')
print('5. Quit the program')
print()
choice = int(input('Enter the choice: '))
while choice < LOOK_UP or choice > QUIT:
choice = int(input('Enter a valid choice: '))
return choice
def lookUp(emails):
name = input('Enter a name: ')
print(emails.get(name, 'Not found.'))
def add(emails):
name = input('Enter a name: ')
address = input('Enter an email address: ')
if name not in emails:
emails[name] = address
pickle.dump(emails, open("emails.dat", "wb"))
else:
print('That entry already exists.')
def change(emails):
name = input('Enter a name: ')
if name in emails:
address = input('Enter the new address: ')
emails[name] = address
pickle.dump(emails, open("emails.dat", "wb"))
else:
print('That name is not found.')
def delete(emails):
name = input('Enter a name: ')
if name in emails:
del emails[name]
else:
print('That name is not found.')
main()
I know I should set my emails variable to be some form of pickle.load, but I can't figure it out for the life of me. mMyUtils is a library I made for try/except logic, I'll put that in once I get the new stuff working.
Upvotes: 2
Views: 8213
Reputation: 616
Consider yourself using ast.literal_eval instead of pickle: http://docs.python.org/2/library/ast.html#ast.literal_eval
>>>import ast
>>> print mydict
{'bob': 1, 'danny': 3, 'alan': 2, 'carl': 40}
>>> string="{'bob': 1, 'danny': 3, 'alan': 2, 'carl': 40}"
>>> type(string)
<type 'str'>
>>> type( ast.literal_eval(string) )
<type 'dict'>
To save/read dict from file, you can do it like with normal string.
Upvotes: 1
Reputation: 53
The problem was, and I guess I didn't emphasis it enough, was what I was supposed to do if the dictionary didn't exist in the first place. The design doc states that you should load the dictionary every time you run the program. Well if you're running the program for the first time, you don't have a dictionary to load, leading to an error. I got around this by basically doing the function twice using try/except.
My code:
import mMyUtils
import pickle
import dictionaryGenerator
LOOK_UP = 1
ADD = 2
CHANGE = 3
DELETE = 4
QUIT = 5
def main():
hasError = False
try:
emails = pickle.load(open('emails.dat', 'rb'))
choice = 0
while choice != QUIT:
choice = getMenuChoice()
if choice == LOOK_UP:
lookUp(emails)
elif choice == ADD:
add(emails)
elif choice == CHANGE:
change(emails)
elif choice == DELETE:
delete(emails)
else:
print("Good-bye!")
exit
except Exception as err:
hasError = True
mMyUtils.printError("Error: no such file",err)
mMyUtils.writeToErrorLog()
finally:
if hasError:
emails = {}
choice = 0
while choice != QUIT:
choice = getMenuChoice()
if choice == LOOK_UP:
lookUp(emails)
elif choice == ADD:
add(emails)
elif choice == CHANGE:
change(emails)
elif choice == DELETE:
delete(emails)
else:
print("Good-bye!")
exit
def getMenuChoice():
print()
print('Name and Email Address Catalog')
print('------------------------------')
print('1. Look up an email address')
print('2. Add a new email address')
print('3. Change an email address')
print('4. Delete an email address')
print('5. Quit the program')
print()
choice = int(input('Enter the choice: '))
while choice < LOOK_UP or choice > QUIT:
choice = int(input('Enter a valid choice: '))
return choice
def lookUp(emails):
name = input('Enter a name: ')
print(emails.get(name, 'Not found.'))
def add(emails):
name = input('Enter a name: ')
address = input('Enter an email address: ')
if name not in emails:
emails[name] = address
with open("emails.dat", "wb") as infile:
pickle.dump(emails, infile)
else:
print('That entry already exists.')
def change(emails):
name = input('Enter a name: ')
if name in emails:
address = input('Enter the new address: ')
emails[name] = address
with open("emails.dat", "wb") as infile:
pickle.dump(emails, infile)
else:
print('That name is not found.')
def delete(emails):
name = input('Enter a name: ')
if name in emails:
del emails[name]
else:
print('That name is not found.')
main()
Upvotes: 0
Reputation: 4348
You must load the file and unpickle the data before you can access it, change lookUp()
to this:
def lookUp(emails):
with open("emails.dat", "rb") as fo:
emails = pickle.load(fo)
name = input('Enter a name: ')
print(emails.get(name, 'Not found.'))
Upvotes: 1
Reputation: 500317
If you're saving the dictionary like so:
pickle.dump(emails, open('emails.dat', 'wb'))
The following will load it back:
emails = pickle.load(open('emails.dat', 'rb'))
Upvotes: 2