I did a project for a programming class this fall in Python, with a 20-questions style game that will learn from user responses. It uses a tree based on yes/no responses to questions, and pickles the unique questions for each decision along with the animals to ask about once it reaches the end of a “branch”.
Towards the end of the class, we did some work in C++ (but I’m still very much new at it), and I would like to make a C++ version of the project over my break – That will make it much easier to run as, for example, an executable. However, I have found that C++ does not have many options for pickle-style data storage, and I don’t think that Boost.serialization or Boost.Python would work particularly well for this situation.
Are there other alternatives, or do you have suggestions for how to deal with the data in another way in C++?
The original, Python code includes this:
def check(self):
correct, lastnode = self.ask(self.root) #lastnode is the closest guess to the new animal
if correct =='n':
print("Rats! I didn't get it. Please help me improve.")
newanimal = AnTreeNode(input("What is your animal? "))
oldanimal = lastnode
newquestion = input("Please enter a yes/no question that would\n select between a(n) %s \
and a(n) %s: " %(newanimal,lastnode.data))+" "
direction = input("What would be the correct answer for a(n) %s? " %newanimal)
newnode = AnTreeNode(newquestion, parent = lastnode.parent)
if lastnode.parent == None:
self.root = newnode
elif lastnode.parent.yes == lastnode:
newnode.parent.yes = newnode
else:
newnode.parent.no = newnode
if direction == 'y':
newnode.yes, newnode.no = newanimal, oldanimal
elif direction == 'n':
newnode.yes, newnode.no = oldanimal, newanimal
newanimal.parent = newnode
oldanimal.parent = newnode
self.dumpTree()
elif correct == 'y':
print("I am soooo smart!")
def loadTree(self):
try:
f = open(self.treefile, "rb")
self.root = pickle.load(f)
except:
self.root = AnTreeNode("frog")
def dumpTree(self):
pickle.dump(self.root, open(self.treefile, 'wb'))
I can’t think of a way to make the tree work if I saved the data to a file or an array (and I don’t particularly want to make a dynamic array, although I can figure it out if storing things in an array ended up working.) The problem with those is that I’m not sure how to reference a particular node. Any other options, or thoughts on how to work with those? Thanks! (And Merry Christmas!)
Actually boost::serialization works quite well, and learning the basics is not that difficult.
However, you might consider some slightly higher level library like protocol buffers. This way you can have the database that will work both for your python and C++ version.
EDIT : boost::python is not the right solution as it only allows to make bindings. It would be a real pain to use it for saving data.
Boost serialize allows to serialize (and then easily save on the disk) C++ structures. Just try the examples from the documentation.
Protocol buffers is a serialization format that allows to exchange data in a binary format. The format is well defined, so you can read/write from different languages and exchange data.
It is easier to manipulate inside the code as for instance XML : http://code.google.com/p/protobuf/
However, I think it will require a little bit more efforts than boost::serialize. Any ways, both are worth learning, and will be useful for further projects.