DataLab is a compact statistics package aiming at exploratory data analysis. Please visit the DataLab Web site for more information....


ExecutePyScript

Declaration: ExecutePyScript (PyScript: string; IOChannel: TCustomMemo; WriteProtectData: boolean; const Params: TDoubleArray; const MatX, MatY: TDouble2DArray; var ResMat: TDouble2DArray; var errmsg: string): integer;
The function ExecutePyScript allows to call a Python script from within DLabPascal. The parameter PyScript contains the Python program code (lines have to be separated by <LF> (ASCII 10) or <CR><LF> (ASCII 13,10).

The parameter IOChannel points to a TMemo component which serves as output channel for text messages issued by the Python script. The predeclared MMOutPut should be used to output the messages on the output pannel of the script editor. In order to suppress any text output you could set the parameter IOChannel to nil.

Sometimes it is helpful to write-protect the entire data structure of DataLab by setting the parameter WriteProtectData to TRUE. If WriteProtectData is active, changes of the Python variables provided by the module datalab will be ignored. Further, the call to ExecutePyScript will be at least twice as fast if WriteProtectData is TRUE (because no information has to be passed back from Python to DLabPascal).

Please note that an active write protection does not prevent you from changing the variables of the module "datalab" in the Python script, however these changes will have no effect on the original data of DataLab, as the variables in the "datalab" module are copies of the original data and are only copied back to the original data if WriteProtectData is FALSE.

The array Params contains a list of numeric parameters to be transfered to the Python script. All values are floating point numbers. In order to pass non-numeric parameters you have to encode them as a floating point numbers (for example, a boolean parameter can be encoded as 0.0 and 1.0 for TRUE and FALSE, respectively). If you do not want to pass any parameters, pass a nil value for the parameter array.

The arrays MatX and MatY are user-defined readonly matrices which can be used to pass special data to the Python script. Set them to nil if you do not want to pass any extra data to the Python script (note that the main data matrix of DataLab is always passed to the Python side and can be accessed by the variable "dstore" - see the section Python - Data and Parameters for further details).

The variable parameter ResMat is a two-dimensional array intended as result container which is used to pass back the results of the Python script to the DLabPascal script. The size of the ResMat array must not be changed by the Python script, thus you have to prepare the size of the ResMat array on the Pascal side. It can be filled by the Python script by using the identifier resmat. Please note that ResMat can be used as an input array to the Python script, as well (despite its name)

The variable parameter errmsg returns the error message(s) from the Python engine (if any).

The function returns the following error codes:

 0 ... everything is OK
-1 ... the Python script caused an exception (details are returned in the variable parameter errmsg)

Sample
Program 1:
The following sample code shows how to call a python script from within DLabPascal. It simply prepares the parameter list (four floating point numbers, the second one is set to 11.11) and the result matrix (a two-dimensional matrix of 6 columns and 8 rows, the cell [3,5] is set on the DLabPascal side, the cell [2,5] is set on the Python side).

Please note that for demo purposes the Python script is encoded as a constant string in the DLabPascal script. In most "real" application cases the Python script should be read from a file (use ReadStringFromTextFile to read the file into a string).


program CallPythonScript;

const
  CRLF = #13#10;
  PyScr = 'import datalab as dl'+CRLF+
          'from datalab import *'+CRLF+
          'import numpy as np'+CRLF+
          'print ("params: ",params)'+CRLF+
          'print ("resmat received from DLabPascal: ",resmat)'+CRLF+
          'resmat[2,5] = 55.5'+CRLF+
          'print ("resmat after manipulation in the Python script", resmat)';

var
  resmat  : TDouble2DArray;
  errmsg  : string;
  Params  : TDoubleArray;

begin
setLength (Params, 4);           // set the parameters
Params[1] := 11.11;
Resize2DArray (resmat, 6, 8);     // prepare resmat
resmat [3][5] := 88;
couts ('now start the Python script....');
ExecutePyScript (PyScr,          // script code
                 MMOutPut,       // output channel
                 false,          // write protection of DataLab data
                 Params,         // parameter list
                 nil, nil,       // no user-defined matrices
                 resmat,         // results from Python script
                 errmsg);        // error message (if any)
couts ('back from Python, now the DLabPascal script executes again...');
cout ('ResMat: ', resmat);
end.

Sample
Program 2:
The following sample code shows how to transfer used-defined data to the Python script by using the arrays MatX and MatY. The script loads a demo dataset, copies part of the data into MatX and MatY and executes the Python script, which simply adds the two arrays and returns the sum in the array resmat.

Please note that for demo purposes the Python script is encoded as a constant string in the DLabPascal script. In most "real" application cases the Python script should be read from a file (use ReadStringFromTextFile to read the file into a string).


program PyMatXY;

const
  TRNDATA = 'boilpts_500.idt';   // sample data
  CRLF = #13#10;
  PyScr = 'import datalab as dl'+CRLF+
          'from datalab import *'+CRLF+
          'import numpy as np'+CRLF+
          'print ("matx received from DLabPascal: ",matx)'+CRLF+
          'print ("maty received from DLabPascal: ",maty)'+CRLF+
          'resmat = maty + matx';

var
  resmat  : TDouble2DArray;
  errmsg  : string;
  FVers   : integer;
  MatX    : TDouble2DArray;
  MatY    : TDouble2DArray;

begin
LoadDlabFile (GetDLabDir(ddWork)+TRNDATA, FVers, true);
Resize2DArray (resmat, 2, 10);// prepare resmat
Resize2DArray (matX, 2, 10);
DStore.CopyDataTo2DArray (matX, 1, 0, 2, 0, 0, 0); // copy col 1&2
Resize2DArray (matY, 2, 10);
DStore.CopyDataTo2DArray (matY, 4, 0, 5, 0, 0, 0); // copy col 4&5
couts ('now start the Python script....');
ExecutePyScript (PyScr,       // Python script code
                 MMOutPut,    // output channel
                 false,       // write protection of DataLab data
                 nil,         // no parameters
                 MatX,        // user-defined matrix
                 MatY,        // user-defined matrix
                 resmat,      // results from Python script
                 errmsg);     // error message (if any)
couts ('back from Python, now the DLabPascal script executes again...');
cout ('ResMat: ', resmat);
end.