capcode.gms : Test Connect agent PythonCode

Description

This test ensures the correctness of the Connect agent PythonCode.

Contributor: Clemens Westphal, March 2022


Small Model of Type : GAMS


Category : GAMS Test library


Main file : capcode.gms

$title 'Test Connect agent PythonCode' (CAPCODE,SEQ=894)

$ontext
This test ensures the correctness of the Connect agent PythonCode.

Contributor: Clemens Westphal, March 2022
$offtext


* On the major platforms (Windows, Linux, Mac), GMSPYTHONLIB gets automatically set
* to use the internal Python installation in sysdir/GMSPython.
$if not setEnv GMSPYTHONLIB $abort.noError Embedded code Python not ready to be used
$log --- Using Python library %sysEnv.GMSPYTHONLIB%

set i / i1*i10 /;
set j / j1*j10 /;
parameter p0(i);
parameter p1(i);
parameter p2(i,j);

p0(i) = uniform(0,10);
p2(i,j) = uniform(0,10);


* write a file using PythonCode
embeddedCode Connect:
- GAMSReader:
    readAll: True
- PythonCode:
    code: |
      with open('pythoncode_file.txt', 'w') as f:
        f.write('written with a PythonCode agent')
endEmbeddedCode
embeddedCode Python:
with open('pythoncode_file.txt') as f:
  str = f.read()
if str != 'written with a PythonCode agent':
  raise Exception("Problems reading 'pythoncode_file.txt'")
endEmbeddedCode


* create a new symbol in connect.container with the same records as another symbol
embeddedCode Connect:
- GAMSReader:
    symbols:
      - name: p0
- PythonCode:
    code: |
      connect.container.addParameter("p1", ["i"], records=connect.container.data["p0"].records)
- GAMSWriter:
    symbols:
      - name: p1
endEmbeddedCode
embeddedCode Python:
if list(gams.get('p0')) != list(gams.get('p1')):
  raise Exception("Unexpected Data in p1")
endEmbeddedCode

* generate instructions using PythonCode
embeddedCode Connect:
- GAMSReader:
    readAll: True
- PythonCode:
    code: |
      symbols = [ 'p0', 'p1', 'p2' ]
      for s in symbols:
        instructions.append(
        {
          'PandasExcelWriter':
          {
            'file': 'data_{}.xlsx'.format(s),
            'symbols': [{'name': s, 'rowDimension': connect.container.data[s].dimension, 'range': s+'!A1'}]
          }
        })
endEmbeddedCode

embeddedCode Connect:
- GAMSReader:
    symbols:
      - name: p0
        newName: g0
      - name: p1
        newName: g1
      - name: p2
        newName: g2
- PandasExcelReader:
    file: 'data_p0.xlsx'
    symbols:
      - name: p0
        range: 'p0!A1'
        rowDimension: 1
        columnDimension: 0
- PandasExcelReader:
    file: 'data_p1.xlsx'
    symbols:
      - name: p1
        range: 'p1!A1'
        rowDimension: 1
        columnDimension: 0
- PandasExcelReader:
    file: 'data_p2.xlsx'
    symbols:
      - name: p2
        range: 'p2!A1'
        rowDimension: 2
        columnDimension: 0
- PythonCode:
    code: |
      def different(a,b):
         import copy
         df_a = copy.deepcopy(a.records)
         df_b = copy.deepcopy(b.records)
         df_a.columns = df_b.columns
         df_a['value'] = round(df_a['value'], 5)
         df_b['value'] = round(df_b['value'], 5)
         return not df_a.compare(df_b).empty

      if different(connect.container.data['g0'], connect.container.data['p0']):
         raise Exception("g0 <> p0")
      if different(connect.container.data['g1'], connect.container.data['p1']):
         raise Exception("g1 <> p1")
      if different(connect.container.data['g2'], connect.container.data['p2']):
         raise Exception("g2 <> p2")
endEmbeddedCode

* raise exception from PythonCode
embeddedCode Connect:
- PythonCode:
    code: |
      try:
        got_exception = False
        raise Exception("Exception from PythonCode")
      except:
        got_exception = True
      if not got_exception:
        raise Exception("Expected an exception to be caught")
endEmbeddedCode