$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