PLearn 0.1
|
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 :