Monday, January 14, 2013

Boost::python::dict to std::map conversion

In this post there are code listings for std::map wraper to python. All files can be easily downloaded from https://sites.google.com/site/ppiotrowblog/home/files file: map.zip.

First listing is for code, which converts boost::python::dict into std::map.

 #include <map>  
 #include <boost/python.hpp>  
 #include <string>  
   
 #ifndef MAPHOLDER_HPP  
 #define     MAPHOLDER_HPP  
 typedef std::map<std::string,std::string> StringMap;  
 class MapHolder{  
 public:  
      /*Constructors*/  
      MapHolder();  
      MapHolder(boost::python::dict& py_dict);  
        
      /*Modifiers*/  
      void update_map(boost::python::dict& py_dict);  
      void clear();  
   
      boost::python::dict get_dict();  
      size_t size();  
 protected:  
      StringMap map_;  
        
 };  
 #endif  
It allows to create empty map or map with values from python dict. It also allows to clear map or add some elements with update_map method. Here comes methods implementation
 #include "MapHolder.hpp"  
 #include <iostream>  
 MapHolder::MapHolder(){  
   
 };  
   
   
 MapHolder::MapHolder(boost::python::dict& py_dict){  
      update_map(py_dict);  
 }  
   
   
 void MapHolder::update_map(boost::python::dict& py_dict){  
      boost::python::list keys = py_dict.keys();  
        for (int i = 0; i < len(keys); ++i) {  
           boost::python::extract<std::string> extracted_key(keys[i]);  
           if(!extracted_key.check()){  
                std::cout<<"Key invalid, map might be incomplete"<<std::endl;  
                continue;                 
           }  
           std::string key = extracted_key;  
           boost::python::extract<std::string> extracted_val(py_dict[key]);  
           if(!extracted_val.check()){  
           std::cout<<"Value invalid, map might be incomplete"<<std::endl;  
                continue;                 
           }  
           std::string value = extracted_val;  
           map_[key] = value;  
      }  
 }  
   
   
 boost::python::dict MapHolder::get_dict(){  
      boost::python::dict py_dict;  
      for(StringMap::const_iterator it = map_.begin(); it != map_.end(); ++it)   
           py_dict[it->first]=it->second;        
      return py_dict;  
 }  
   
   
 void MapHolder::clear(){  
      map_.clear();  
 }  
After implementation lets expose that in Python.
 #include <algorithm>  
 #include <boost/python.hpp>  
 #include "MapHolder.hpp"  
 #include "FooTicTacToe.hpp"  
   
 BOOST_PYTHON_MODULE(cpp_collections)  
 {  
   using namespace boost::python;  
    class_<MapHolder> ("map", init<>())  
       .def(init<boost::python::dict&>())  
        .def("update_map", &MapHolder::update_map)  
       .def("clear", &MapHolder::clear)  
       .def("size", &MapHolder::size)  
        .def("to_dict",&MapHolder::get_dict);  
   
    class_<FooTicTacToe, bases<MapHolder> >("FooTicTacToe", init<>())  
        .def(init<boost::python::dict&>())  
        .def("is_winner", &FooTicTacToe::FooIsWinner);  
 }  
At this moment ignore FooTicTacToe class. Compile module with sconstruct file
 # Przemek  -*- mode: Python; -*-  
 ##Linux Parameters  
 boost_path='/usr/include/boost/'  
 python_path='/usr/include/python2.7/'  
 ##End  
   
 import platform, os  
   
 boost_libs=['boost_python']  
 env = Environment()  
 if(platform.system() == "Linux"):  
   env.Append(CPPPATH=[boost_path,python_path])  
 #modul pythona  
   env.SharedLibrary(target='cpp_collections.so',source=['python_wraper.cpp', 'MapHolder.cpp', 'FooTicTacToe.cpp'], LIBS=boost_libs, SHLIBPREFIX='')  
 else:  
   print platform.system() + ' not supported'  
If You invoke that Python script:
 import cpp_collections  
   
 sample_dict = {'EUR':'European','USD':'United States Dolar','RON':'Romanian leu','PLN':'Polish Zloty','HUF':'Hungarian forint', '1':'Number as a text'}  
 sample_map = cpp_collections.map(sample_dict)  
 print sample_map.size()  
 print sample_map.to_dict()  
   
 sample_map.update_map({'UKC':'Unknown Currency'})  
 print sample_map.size()  
 print sample_map.to_dict()  
   
 sample_map.clear();  
 print sample_map.size()  
 print sample_map.to_dict()  
   
   
 sample_map.update_map({2:'Number as a number'});  
 print sample_map.size()  
 print sample_map.to_dict()  
You will see result
 6  
 {'HUF': 'Hungarian forint', 'USD': 'United States Dolar', 'RON': 'Romanian leu', '1': 'Number as a text', 'PLN': 'Polish Zloty', 'EUR': 'European'}  
 7  
 {'HUF': 'Hungarian forint', 'USD': 'United States Dolar', 'RON': 'Romanian leu', '1': 'Number as a text', 'PLN': 'Polish Zloty', 'UKC': 'Unknown Currency', 'EUR': 'European'}  
 0  
 {}  
 Key invalid, map might be incomplete  
 0  
 {}  
   
So we created working boost::python::dict to std::map converter. Lets use it to create Foo TicTacToe game.
 #include "MapHolder.hpp"  
 #include <boost/python.hpp>  
   
 #ifndef FooTicTacToe_HPP  
 #define     FooTicTacToe_HPP  
   
 class FooTicTacToe: public MapHolder{  
 public:  
      FooTicTacToe();  
      FooTicTacToe(boost::python::dict& py_dict);  
      bool FooIsWinner();  
 };  
   
 #endif  
and method implementation
 #include "FooTicTacToe.hpp"  
   
 FooTicTacToe::FooTicTacToe():  
      MapHolder()  
      {}  
   
   
 FooTicTacToe::FooTicTacToe(boost::python::dict& py_dict):  
      MapHolder(py_dict)  
      {}  
   
 bool FooTicTacToe::FooIsWinner(){  
 //TODO that method is realy stupid  
   
 return map_["a1"]=="x" && map_["a2"]=="x" && map_["a3"] =="x";  
   
 }  
Because we used boost python classes inheritance, we have ready methods to simulate moves. Bellow is Python script to simulate really foo game.
   
 #TicTacToe game  
 ttt_game = cpp_collections.FooTicTacToe({'a1':'x'})  
   
 #make moves  
 ttt_game.update_map({'b1':'o'})  
 ttt_game.update_map({'a2':'x'})  
 print 'Is winner?',ttt_game.is_winner()  
 ttt_game.update_map({'b2':'0'})  
 ttt_game.update_map({'a3':'x'})  
 print 'Is winner?',ttt_game.is_winner()  
 ttt_game.clear()  
It produces output
 Is winner? False  
 Is winner? True  

1 comment:

  1. Programmer'S Blog: Boost::Python::Dict To Std::Map Conversion >>>>> Download Now

    >>>>> Download Full

    Programmer'S Blog: Boost::Python::Dict To Std::Map Conversion >>>>> Download LINK

    >>>>> Download Now

    Programmer'S Blog: Boost::Python::Dict To Std::Map Conversion >>>>> Download Full

    >>>>> Download LINK Qn

    ReplyDelete