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


$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:
    symbols: all
- 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:
    symbols: all
- PythonCode:
    code: |
      symbols = [ 'p0', 'p1', 'p2' ]
      for s in symbols:
        instructions.append(
        {
          'ExcelWriter':
          {
            'file': 'data_{}.xlsx'.format(s),
            'symbols': [{'name': s, 'columnDimension': 0, 'range': s+'!A1'}]
          }
        })
endEmbeddedCode

embeddedCode Connect:
- GAMSReader:
    symbols:
      - name: p0
        newName: g0
      - name: p1
        newName: g1
      - name: p2
        newName: g2
- ExcelReader:
    file: 'data_p0.xlsx'
    symbols:
      - name: p0
        range: 'p0!A1'
        rowDimension: 1
        columnDimension: 0
- ExcelReader:
    file: 'data_p1.xlsx'
    symbols:
      - name: p1
        range: 'p1!A1'
        rowDimension: 1
        columnDimension: 0
- ExcelReader:
    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

* test scope behavior
$onEmbeddedCode Connect:
- PythonCode:
    code: |
      import gams.transfer as gt
      m = gt.Container(system_directory=r"%gams.sysdir% ".strip())
      m.addParameter('p', domain=['*'], records= [['i1', 1], ['i2', 2]])
      values = [ v for v in m['p'].records['value']]
      if values != [1.0, 2.0]:
        raise Exception("Exception from PythonCode scope test")

      if 'm' not in locals():
        raise Exception("Expected 'm' to be in locals()")
      if 'm' not in globals():
        raise Exception("Expected 'm' to be in globals()")

      def f():
        if 'm' in locals():
          raise Exception("Expected 'm' not to be in locals() of f()")
        if 'm' not in globals():
          raise Exception("Expected 'm' to be in globals() of f()")
      f()
      connect.keep = {'m': m}
- PythonCode:
    code: |
      import gams.transfer as gt
      if 'm' in locals() or 'm' in globals():
        raise Exception("Expected 'm' to be inaccessible in a subsequent PythonCode instance")
      if 'm' not in connect.keep or not isinstance(connect.keep['m'], gt.Container):
        raise Exception("'m' not found in 'connect.keep' or not an instance of gt.Container")
$offEmbeddedCode