PLearn 0.1
InterfunctionXchgTest.cc
Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00003 // InterfunctionXchgTest.cc
00004 //
00005 // Copyright (C) 2005 Nicolas Chapados 
00006 // Copyright (C) 2005-2006 Olivier Delalleau 
00007 // 
00008 // Redistribution and use in source and binary forms, with or without
00009 // modification, are permitted provided that the following conditions are met:
00010 // 
00011 //  1. Redistributions of source code must retain the above copyright
00012 //     notice, this list of conditions and the following disclaimer.
00013 // 
00014 //  2. Redistributions in binary form must reproduce the above copyright
00015 //     notice, this list of conditions and the following disclaimer in the
00016 //     documentation and/or other materials provided with the distribution.
00017 // 
00018 //  3. The name of the authors may not be used to endorse or promote
00019 //     products derived from this software without specific prior written
00020 //     permission.
00021 // 
00022 // THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
00023 // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00024 // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
00025 // NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00026 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
00027 // TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00028 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00029 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00030 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00031 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00032 // 
00033 // This file is part of the PLearn library. For more information on the PLearn
00034 // library, go to the PLearn Web site at www.plearn.org
00035 
00036 /* *******************************************************      
00037    * $Id: .pyskeleton_header 544 2003-09-01 00:05:31Z plearner $ 
00038    ******************************************************* */
00039 
00040 // Authors: Nicolas Chapados, Olivier Delalleau
00041 
00045 #include <plearn/python/PythonCodeSnippet.h>
00046 #include <boost/regex.hpp>
00047 #include <iostream>
00048 
00049 #include "InterfunctionXchgTest.h"
00050 
00051 namespace PLearn {
00052 using namespace std;
00053 
00054 PLEARN_IMPLEMENT_OBJECT(
00055     InterfunctionXchgTest,
00056     "Test data exchange within a single snippet and exception mapping",
00057     ""
00058 );
00059 
00061 // InterfunctionXchgTest //
00063 InterfunctionXchgTest::InterfunctionXchgTest() 
00064     /* ### Initialize all fields to their default value */
00065 {
00066     // ...
00067 
00068     // ### You may (or not) want to call build_() to finish building the object
00069     // ### (doing so assumes the parent classes' build_() have been called too
00070     // ### in the parent classes' constructors, something that you must ensure)
00071 }
00072 
00074 // build //
00076 void InterfunctionXchgTest::build()
00077 {
00078     inherited::build();
00079     build_();
00080 }
00081 
00083 // makeDeepCopyFromShallowCopy //
00085 void InterfunctionXchgTest::makeDeepCopyFromShallowCopy(CopiesMap& copies)
00086 {
00087     inherited::makeDeepCopyFromShallowCopy(copies);
00088 
00089     // ### Call deepCopyField on all "pointer-like" fields 
00090     // ### that you wish to be deepCopied rather than 
00091     // ### shallow-copied.
00092     // ### ex:
00093     // deepCopyField(trainvec, copies);
00094 
00095     // ### Remove this line when you have fully implemented this method.
00096     PLERROR("InterfunctionXchgTest::makeDeepCopyFromShallowCopy not fully (correctly) implemented yet!");
00097 }
00098 
00100 // declareOptions //
00102 void InterfunctionXchgTest::declareOptions(OptionList& ol)
00103 {
00104     // ### Declare all of this object's options here
00105     // ### For the "flags" of each option, you should typically specify  
00106     // ### one of OptionBase::buildoption, OptionBase::learntoption or 
00107     // ### OptionBase::tuningoption. Another possible flag to be combined with
00108     // ### is OptionBase::nosave
00109 
00110     // ### ex:
00111     // declareOption(ol, "myoption", &InterfunctionXchgTest::myoption, OptionBase::buildoption,
00112     //               "Help text describing this option");
00113     // ...
00114 
00115     // Now call the parent class' declareOptions
00116     inherited::declareOptions(ol);
00117 }
00118 
00120 // build_ //
00122 void InterfunctionXchgTest::build_()
00123 {
00124     // ### This method should do the real building of the object,
00125     // ### according to set 'options', in *any* situation. 
00126     // ### Typical situations include:
00127     // ###  - Initial building of an object from a few user-specified options
00128     // ###  - Building of a "reloaded" object: i.e. from the complete set of all serialised options.
00129     // ###  - Updating or "re-building" of an object after a few "tuning" options have been modified.
00130     // ### You should assume that the parent class' build_() has already been called.
00131 }
00132 
00133 string InterfunctionXchgTest::python_code =
00134 "import sys\n"
00135 "\n"
00136 "def set_value(x):\n"
00137 "    global buf\n"
00138 "    buf = x\n"
00139 "\n"
00140 "def get_value():\n"
00141 "    global buf\n"
00142 "    return buf\n"
00143 "\n"
00144 "def print_global_map():\n"
00145 "    print 'Printing some_global_map within Python:', some_global_map\n"
00146 "    sys.stdout.flush()\n"
00147 ;
00148 
00149 
00151 // perform //
00153 void InterfunctionXchgTest::perform()
00154 {
00155     cout << "Python code to be executed: " << endl
00156          << ">>>" << python_code << "<<<" << endl;
00157     
00158     PP<PythonCodeSnippet> python       = new PythonCodeSnippet(python_code);
00159     PP<PythonCodeSnippet> python_other = new PythonCodeSnippet(python_code, true);
00160     python->build();
00161     python_other->build();
00162     
00163     string survivor = "This string should survive within the Python environment";
00164     cout << "Setting the string:   '" << survivor << "'" << endl;
00165     python->invoke("set_value", survivor);
00166     cout << "Read back the string: '"
00167          << python->invoke("get_value").as<string>()
00168          << "'" << endl;
00169 
00170     cout << "Trying to read back from second snippet:" << endl;
00171     try {
00172         string s = python_other->invoke("get_value").as<string>();
00173         cout << "Read back the string: '" << s << "'" << endl;
00174     }
00175     catch (const PythonException& e) {
00176         string exception_msg = e.message();
00177         // Remove system dependent strings from the error message.
00178         boost::regex memory_adr("0x[abcdef0123456789]{6,}",
00179                                 boost::regex::perl|boost::regex::icase);
00180         string msg_without_sys_dependent_data =
00181             regex_replace(exception_msg, memory_adr,
00182                     "0x[memory_address]");
00183 
00184         boost::regex python_ver("Python 2\\.[0-9](\\.[0-9])?",
00185                                 boost::regex::perl|boost::regex::icase);
00186         msg_without_sys_dependent_data =
00187             regex_replace(msg_without_sys_dependent_data, python_ver,
00188                     "Python 2.X.Y");
00189 
00190         boost::regex python_path(": /(.)+/python",
00191                                  boost::regex::perl|boost::regex::icase);
00192         msg_without_sys_dependent_data =
00193             regex_replace(msg_without_sys_dependent_data, python_path,
00194                     ": /path/python");
00195 
00196         boost::regex except_display("<type 'exceptions.([a-z]+)'>",
00197                                     boost::regex::perl|boost::regex::icase);
00198         msg_without_sys_dependent_data =
00199             regex_replace(msg_without_sys_dependent_data, except_display,
00200                     "\\1");
00201 
00202         boost::regex extra_info("__class__(.)*message = [^\\n]+$\\n",
00203                 boost::regex::perl|boost::regex::icase);
00204 
00205         msg_without_sys_dependent_data =
00206             regex_replace(msg_without_sys_dependent_data, extra_info, "");
00207 
00208         boost::regex blank_line("^( )+$", boost::regex::perl);
00209         msg_without_sys_dependent_data =
00210             regex_replace(msg_without_sys_dependent_data, blank_line, "");
00211 
00212         cout << "Caught Python Exception: '" << msg_without_sys_dependent_data
00213              << "'" << endl;
00214     }
00215     catch (const PLearnError& e) {
00216         cout << "Caught PLearn Exception: '" << e.message() << "'" << endl;
00217     }
00218     catch (...) {
00219         cout << "Caught unknown exception..." << endl;
00220     }
00221 
00222 
00223     try {
00224         map<string,int> mapsd;
00225         string str_mapsd = "{ Oui:16 il:32 est:64 juste:128 et:256 bon:512 }";
00226         PStream is_mapsd = openString(str_mapsd, PStream::plearn_ascii);
00227         is_mapsd >> mapsd;
00228 
00229         python_other->setGlobalObject("some_global_map", PythonObjectWrapper(mapsd));
00230         cout << "Associated 'some_global_map' with: " << tostring(mapsd) << endl;
00231         cout << "Read back from Python environment: "
00232              << tostring(python_other->getGlobalObject("some_global_map").as< map<string,int> >())
00233              << endl;
00234         python_other->invoke("print_global_map");
00235 
00236         cout << "Dump of the 'python_other' compiled environment" << endl;
00237     }
00238     catch(const PLearnError& e)
00239     {
00240         cerr << "FATAL ERROR: " << e.message() << endl;
00241     }
00242     catch (...) 
00243     {
00244         cerr << "FATAL ERROR: uncaught unknown exception "
00245              << "(ex: out-of-memory when allocating a matrix)" << endl;
00246     }
00247 }
00248 
00249 } // end of namespace PLearn
00250 
00251 
00252 /*
00253   Local Variables:
00254   mode:c++
00255   c-basic-offset:4
00256   c-file-style:"stroustrup"
00257   c-file-offsets:((innamespace . 0)(inline-open . 0))
00258   indent-tabs-mode:nil
00259   fill-column:79
00260   End:
00261 */
00262 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=79 :
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines