1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

using a dictionary after it's been unpickled (in Python)

Discussion in 'Python' started by Noodle, Jul 26, 2006.

  1. Noodle

    Noodle New Member

    Jul 26, 2006
    Likes Received:
    Trophy Points:
    This is actually a homework assingment, so I'm not looking for a direct answer, but maybe a point in the right direction. The assingment is make this program not "forget" all the information the user entered everytime it ends. (using pickle). I added the nodePickle() and nodeUnpickle() and a few other things (I noted the things I added in the comments, the rest is the orginal program)

    The problem I have, is that when I try to send the var ('item') holding the dictionary to the Qnode class (after I've loaded it from the file) , I get this error: "cannot concatenate 'str' and 'instance' objects." So, I'm not really sure what is going on here. The lesson plan really doesn't go into detail about this, so I'm kinda lost.
    # questor.py		
    import cPickle as p
    # define some constants for future use
    kQuestion = 'question'
    kGuess = 'guess'
    nodeFile = 'questFile.txt' # jason added
    # define a function for asking yes/no questions
    def yesno(prompt):
    	ans = raw_input(prompt)
    	return (ans[0]=='y' or ans[0]=='Y')
    # I added; dump dictionary to file for future use
    def nodePickle(nodes):
            f = file(nodeFile, 'w')
            p.dump(nodes, f)
            f = file(nodeFile)
            theNode = p.load(f)
    # I added; load dictionary from file
    def nodeUnpickle():
            f = file(nodeFile)
            nodes = p.load(f)
            return nodes
    # define a node in the question tree (either question or guess)
    class Qnode:
    	# initialization method
    	def __init__(self,guess):
    		self.nodetype = kGuess
    		self.desc = guess
    	# get the question to ask	
    	def query(self):
    		if (self.nodetype == kQuestion):
    			return self.desc + " "
    		elif (self.nodetype == kGuess):
    			return "Is it a " + self.desc + "? "
    			return "Error: invalid node type!"
    	# return new node, given a boolean response
    	def nextnode(self,answer):
    		return self.nodes[answer]
    	# turn a guess node into a question node and add new item
    	# give a question, the new item, and the answer for that item
    	def makeQuest( self, question, newitem, newanswer ):
    		# create new nodes for the new answer and old answer
    		newAnsNode = Qnode(newitem)
    		oldAnsNode = Qnode(self.desc)
                    print ("newAns: ", newAnsNode)
                    print ("oldAns: ", oldAnsNode)
    		# turn this node into a question node
    		self.nodetype = kQuestion
    		self.desc = question
    		# assign the yes and no nodes appropriately
    		self.nodes = {newanswer:newAnsNode, not newanswer:oldAnsNode}
                    nodePickle(self.nodes) # I added
    def traverse(fromNode):
    	# ask the question
    	yes = yesno( fromNode.query() )
    	# if this is a guess node, then did we get it right?
    	if (fromNode.nodetype == kGuess):
    		if (yes):
    			print "I'm a genius!!!"
    		# if we didn't get it right, return the node
    		return fromNode
    	# if it's a question node, then ask another question
    	return traverse( fromNode.nextnode(yes) )
    def run(item):   
            # start with a single guess node
    	topNode = Qnode(item[0]) # orignal program read 'topNode = Qnode('python')
    	done = 0
    	while not done:
    		# ask questions till we get to the end
    		result = traverse( topNode )
    		# if result is a node, we need to add a question
    		if (result):
    			item = raw_input("OK, what were you thinking of? ")
    			print "Enter a question that distinguishes a",
    			print item, "from a", result.desc + ":"
    			q = raw_input()
    			ans = yesno("What is the answer for " + item + "? ")
    			result.makeQuest( q, item, ans )
    			print "Got it."
    		# repeat until done
    		done = not yesno("Do another? ")
    # immediate-mode commands, for drag-and-drop or execfile() execution
    if __name__ == '__main__':
            item = nodeUnpickle()# I added; get dictionary from file
    	raw_input("press Return>")
    	print "Module questor imported."
    	print "To run, type: questor.run()"
    	print "To reload after changes to the source, type: reload(questor)"
    # end of questor.py

    Also, as a side question.... how come when I load the dictionary into a var and try to "print" it... it gives me the memory address instead of the dictionary. I.E....

    >>> item = p.load(f)
    >>> item
    {False: <__main__.Qnode instance at 0x016E8080>, True: <__main__.Qnode instance at 0x016E8058>}


    >>> item[0]
    <__main__.Qnode instance at 0x016E8080>

    Any help on these issue are appreciated, thanks in advance!


Share This Page