capdxlsr.gms : Test Connect agent PandasExcelReader

Description

This test ensures the correctness of the Connect agent PandasExcelReader.

Contributor: Clemens Westphal, March 2022


Small Model of Type : GAMS


Category : GAMS Test library


Main file : capdxlsr.gms

$title 'Test Connect agent PandasExcelReader' (CAPDXLSR,SEQ=898)

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

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%


$log read a scalar and use valueSubstitutions
$onEmbeddedCode Connect:
- PandasExcelReader:
    file: capdxlsr.xlsx
    symbols:
      - name: p0
        range: scalar!B3
        rowDimension: 0
        columnDimension: 0
        valueSubstitutions: {5: 6}
- PythonCode:
    code: |
      expected = 6
      data = connect.container.data["p0"].records.values
      if data != expected:
        raise Exception("Unexpected Data")
$offEmbeddedCode

$log read 2-dim parameter from a full range (sparse)
$onEmbeddedCode Connect:
- PandasExcelReader:
    file: capdxlsr.xlsx
    symbols:
      - name: p2
        range: multi!B2:G6
        rowDimension: 1
        columnDimension: 1
- PythonCode:
    code: |
      expected = [
        ['i1', 'j1',  1.],
        ['i1', 'j2',  2.],
        ['i1', 'j3',  3.],
        ['i1', 'j4',  4.],
        ['i1', 'j5',  5.],
        ['i2', 'j1',  6.],
        ['i3', 'j2', 12.],
        ['i4', 'j1', 16.],
        ['i4', 'j3', 18.],
        ['i4', 'j5', 20.]
      ]
      sym = connect.container.data["p2"]
      sym.records.sort_values(sym.records.columns[:-1].tolist(), inplace=True)
      data = sym.records.values.tolist()
      if data != expected:
        raise Exception("Unexpected Data")
$offEmbeddedCode

$log read 2-dim parameter using NW corner with multiple symbols in spreadsheet
$onEmbeddedCode Connect:
- PandasExcelReader:
    file: capdxlsr.xlsx
    symbols:
      - name: p2
        range: multi!B2
        rowDimension: 1
        columnDimension: 1
        drop: 'Unnamed'
- PythonCode:
    code: |
      expected = [
        ['i1', 'j1',   1.],
        ['i1', 'j2',   2.],
        ['i1', 'j3',   3.],
        ['i1', 'j4',   4.],
        ['i1', 'j5',   5.],
        ['i1', 'j6',  21.],
        ['i1', 'j8',  23.],
        ['i2', 'j1',   6.],
        ['i2', 'j9',  29.],
        ['i3', 'j2',  12.],
        ['i3', 'j7',  32.],
        ['i3', 'j10', 35.],
        ['i4', 'j1',  16.],
        ['i4', 'j3',  18.],
        ['i4', 'j5',  20.],
        ['i4', 'j6',  36.],
        ['i4', 'j8',  38.]
      ]
      sym = connect.container.data["p2"]
      sym.records.sort_values(sym.records.columns[:-1].tolist(), inplace=True)
      data = sym.records.values.tolist()
      if data != expected:
        raise Exception("Unexpected Data")
$offEmbeddedCode


$log read 3-dim parameter from a full range and test case insensitivity of sheet names
$log test relaxed domain information
$onEmbeddedCode Connect:
- PandasExcelReader:
    file: capdxlsr.xlsx
    symbols:
      - name: p3
        range: MuLtI2!B2:I6
        rowDimension: 1
        columnDimension: 2
- PythonCode:
    code: |
      expected = [
        ['i1', 'j1', 'k1',   1.],
        ['i1', 'j1', 'k2',   2.],
        ['i1', 'j2', 'k1',   3.],
        ['i1', 'j3', 'k2',   5.],
        ['i1', 'j4', 'k1',   6.],
        ['i1', 'j5', 'k2',   7.],
        ['i2', 'j1', 'k1',   8.],
        ['i2', 'j4', 'k1',  13.]
      ]
      sym = connect.container.data["p3"]
      sym.records.sort_values(sym.records.columns[:-1].tolist(), inplace=True)
      data = sym.records.values.tolist()
      if data != expected:
        raise Exception("Unexpected Data")
    
      expected_domain = ['i', 'j', 'k']
      domain = connect.container.data["p3"].domain_names
      if domain != expected_domain:
        raise Exception("Unexpected Domain")
$offEmbeddedCode

$log read 3-dim parameter using NW corner with multiple symbols in spreadsheet
$onEmbeddedCode Connect:
- PandasExcelReader:
    file: capdxlsr.xlsx
    symbols:
      - name: p3
        range: multi2!B2
        rowDimension: 1
        columnDimension: 2
        drop: '\.'
- PythonCode:
    code: |
      expected = [
        ['i1', 'j1', 'k1',   1.],
        ['i1', 'j1', 'k2',   2.],
        ['i1', 'j2', 'k1',   3.],
        ['i1', 'j3', 'k2',   5.],
        ['i1', 'j4', 'k1',   6.],
        ['i1', 'j5', 'k2',   7.],
        ['i1', 'j6', 'k1',  15.],
        ['i1', 'j6', 'k2',  16.],
        ['i1', 'j6', 'k3',  17.],
        ['i2', 'j1', 'k1',   8.],
        ['i2', 'j4', 'k1',  13.],
        ['i2', 'j6', 'k1',  18.]
      ]
      sym = connect.container.data["p3"]
      sym.records.sort_values(sym.records.columns[:-1].tolist(), inplace=True)
      data = sym.records.values.tolist()
      if data != expected:
        raise Exception("Unexpected Data")
$offEmbeddedCode

$log read 2-dim set from a full range
$onEmbeddedCode Connect:
- PandasExcelReader:
    file: capdxlsr.xlsx
    symbols:
      - name: s2
        range: multi3!A2:E5
        rowDimension: 0
        columnDimension: 2
        type: set
- PythonCode:
    code: |
      expected = [
        ['i1', 'j1', 'text 1'],
        ['i2', 'j1', 'text 2']
      ]
      data = connect.container.data["s2"].records.values.tolist()
      if data != expected:
        raise Exception("Unexpected Data")
$offEmbeddedCode


$log read 2-dim set using NW corner with multiple symbols in spreadsheet
$onEmbeddedCode Connect:
- PandasExcelReader:
    file: capdxlsr.xlsx
    symbols:
      - name: s2
        range: multi3!A2
        rowDimension: 0
        columnDimension: 2
        type: set
        drop: '\.'
- PythonCode:
    code: |
      expected = [
        ['i1', 'j1', 'text 1'],
        ['i2', 'j1', 'text 2'],
        ['i3', 'j1', 'text 3']
      ]
      data = connect.container.data["s2"].records.values.tolist()
      if data != expected:
        raise Exception("Unexpected Data")
$offEmbeddedCode


$log read 3-dim parameter without data from a full range
$onEmbeddedCode Connect:
- PandasExcelReader:
    file: capdxlsr.xlsx
    symbols:
      - name: p3
        range: empty!A1:E5
        rowDimension: 1
        columnDimension: 2
- PythonCode:
    code: |
      expected = []
      data = connect.container.data["p3"].records.values.tolist()
      if data != expected:
        raise Exception("Unexpected Data")
$offEmbeddedCode


$log read 3-dim parameter without data using NW corner
$onEmbeddedCode Connect:
- PandasExcelReader:
    file: capdxlsr.xlsx
    symbols:
      - name: p3
        range: empty!A1
        rowDimension: 1
        columnDimension: 2
- PythonCode:
    code: |
      expected = []
      data = connect.container.data["p3"].records.values.tolist()
      if data != expected:
        raise Exception("Unexpected Data")
$offEmbeddedCode


$log read 3-dim set without data from a full (partial) range
$onEmbeddedCode Connect:
- PandasExcelReader:
    file: capdxlsr.xlsx
    type: set
    rowDimension: 1
    columnDimension: 2
    symbols:
      - name: s3
        range: empty!A1:D4
- PythonCode:
    code: |
      expected = []
      data = connect.container.data["s3"].records.values.tolist()
      if data != expected:
        raise Exception("Unexpected Data")
$offEmbeddedCode


$log read 2-dim parameter from a full range using valueSubstitutions
$onEmbeddedCode Connect:
- PandasExcelReader:
    file: capdxlsr.xlsx
    symbols:
      - name: p2
        range: multi!B2:G6
        rowDimension: 1
        columnDimension: 1
        valueSubstitutions: { .nan: eps }
- PythonCode:
    code: |
      from gams import GMS_SV_EPS
      expected = [
        ['i1', 'j1',  1.],
        ['i1', 'j2',  2.],
        ['i1', 'j3',  3.],
        ['i1', 'j4',  4.],
        ['i1', 'j5',  5.],
        ['i2', 'j1',  6.],
        ['i2', 'j2',  -0.0 ],
        ['i2', 'j3',  -0.0 ],
        ['i2', 'j4',  -0.0 ],
        ['i2', 'j5',  -0.0 ],
        ['i3', 'j1',  -0.0 ],
        ['i3', 'j2', 12.],
        ['i3', 'j3',  -0.0 ],
        ['i3', 'j4',  -0.0 ],
        ['i3', 'j5',  -0.0 ],
        ['i4', 'j1', 16.],
        ['i4', 'j2',  -0.0 ],
        ['i4', 'j3', 18.],
        ['i4', 'j4',  -0.0 ],
        ['i4', 'j5', 20.]
      ]
      sym = connect.container.data["p2"]
      sym.records.sort_values(sym.records.columns[:-1].tolist(), inplace=True)
      data = sym.records.values.tolist()
      if data != expected:
        raise Exception("Unexpected Data")
$offEmbeddedCode


$log read 2-dim parameter with integer labels
$onEmbeddedCode Connect:
- PandasExcelReader:
    file: capdxlsr.xlsx
    symbols:
      - name: p2
        range: int_labels!A1
- PythonCode:
    code: |
      expected = [
        ['1', '5', 1.],
        ['1', '6', 2.],
        ['2', '6', 5.],
        ['2', '7', 6.],
        ['3', '6', 8.],
        ['3', '7', 9.],
      ]
      sym = connect.container.data["p2"]
      sym.records.sort_values(sym.records.columns[:-1].tolist(), inplace=True)
      data = sym.records.values.tolist()
      if data != expected:
        raise Exception("Unexpected Data")
$offEmbeddedCode


$log read 2-dim set using excelReadArgs
$onEmbeddedCode Connect:
- PandasExcelReader:
    file: capdxlsr.xlsx
    symbols:
      - name: s2
        range: wrong_sheet!A2:E5
        rowDimension: 0
        columnDimension: 2
        type: set
        readExcelArguments: { sheet_name: multi3 }
- PythonCode:
    code: |
      expected = [
        ['i1', 'j1', 'text 1'],
        ['i2', 'j1', 'text 2']
      ]
      data = connect.container.data["s2"].records.values.tolist()
      if data != expected:
        raise Exception("Unexpected Data")
$offEmbeddedCode


$log read 3-dim parameter with rdim=dim
$onEmbeddedCode Connect:
- PandasExcelReader:
    file: capdxlsr.xlsx
    symbols:
      - name: p3
        range: rdim_only!B2
        rowDimension: 3
        columnDimension: 0
- PythonCode:
    code: |
      expected = [
        ['i1', 'j1', 'k1', 0.1],
        ['i1', 'j1', 'k3', 0.3],
        ['i1', 'j2', 'k3', 0.6],
        ['i2', 'j1', 'k2', 0.8],
        ['i2', 'j2', 'k3', 1.3]
      ]
      data = connect.container.data["p3"].records.values.tolist()
      if data != expected:
        raise Exception("Unexpected Data")
$offEmbeddedCode


$log read 3-dim parameter from a full range with rdim=dim
$onEmbeddedCode Connect:
- PandasExcelReader:
    file: capdxlsr.xlsx
    symbols:
      - name: p3
        range: rdim_only!B2:E5
        rowDimension: 3
        columnDimension: 0
- PythonCode:
    code: |
      expected = [
        ['i1', 'j1', 'k1', 0.1],
        ['i1', 'j1', 'k3', 0.3]
      ]
      data = connect.container.data["p3"].records.values.tolist()
      if data != expected:
        raise Exception("Unexpected Data")
$offEmbeddedCode

$log read 3-dim parameter with cdim=dim
$onEmbeddedCode Connect:
- PandasExcelReader:
    file: capdxlsr.xlsx
    symbols:
      - name: p3
        range: cdim_only!B2
        rowDimension: 0
        columnDimension: 3
        drop: '\.'
- PythonCode:
    code: |
      expected = [
        ['i1', 'j1', 'k1', 0.1],
        ['i1', 'j1', 'k3', 0.3],
        ['i2', 'j2', 'k3', 0.6]
      ]
      data = connect.container.data["p3"].records.values.tolist()
      if data != expected:
        raise Exception("Unexpected Data")
$offEmbeddedCode


$log read 3-dim parameter from a full range with cdim=dim
$onEmbeddedCode Connect:
- PandasExcelReader:
    file: capdxlsr.xlsx
    symbols:
      - name: p3
        range: cdim_only!B2:E6
        rowDimension: 0
        columnDimension: 3
- PythonCode:
    code: |
      expected = [
        ['i1', 'j1', 'k1', 0.1],
        ['i1', 'j1', 'k3', 0.3]
      ]
      data = connect.container.data["p3"].records.values.tolist()
      if data != expected:
        raise Exception("Unexpected Data")
$offEmbeddedCode


$log read 1-dimensional parameter from 2-dimensional data (rdim)
$onEmbeddedCode Connect:
- PandasExcelReader:
    file: capdxlsr.xlsx
    symbols:
      - name: p1
        range: multi!B2:C6
        rowDimension: 1
        columnDimension: 0
- PythonCode:
    code: |
      expected = [
        ['i1',  1.],
        ['i2',  6.],
        ['i4', 16.]
      ]
      data = connect.container.data["p1"].records.values.tolist()
      if data != expected:
        raise Exception("Unexpected Data")
$offEmbeddedCode


$log read 1-dimensional parameter from 2-dimensional data (cdim)
$onEmbeddedCode Connect:
- PandasExcelReader:
    file: capdxlsr.xlsx
    symbols:
      - name: p1
        range: multi!B2:G3
        rowDimension: 0
        columnDimension: 1
- PythonCode:
    code: |
      expected = [
        ['j1',  1.],
        ['j2',  2.],
        ['j3',  3.],
        ['j4',  4.],
        ['j5',  5.]
      ]
      data = connect.container.data["p1"].records.values.tolist()
      if data != expected:
        raise Exception("Unexpected Data")
$offEmbeddedCode


$log read 3-dim set from a data range with numerical values
$onEmbeddedCode Connect:
- PandasExcelReader:
    file: capdxlsr.xlsx
    type: set
    symbols:
      - name: s3
        range: rdim_only!B2:E5
        rowDimension: 3
        columnDimension: 0
- PythonCode:
    code: |
      expected = [
        ['i1', 'j1', 'k1', '0.1'],
        ['i1', 'j1', 'k3', '0.3']
      ]
      data = connect.container.data["s3"].records.values.tolist()
      if data != expected:
        raise Exception("Unexpected Data")
$offEmbeddedCode

$log read scalar, 1-dim with rdim=0, 1-dim with rdim=1 that are close together
$onEmbeddedCode Connect:
- PandasExcelReader:
    file: capdxlsr.xlsx
    symbols:
      - name: p0
        range: dim0!A1:B2
        rowDimension: 0
        columnDimension: 0
      - name: p1
        range: dim0!D1:E4
        rowDimension: 1
        columnDimension: 0
      - name: p1R
        range: dim0!G1:J2
        rowDimension: 0
        columnDimension: 1
- PythonCode:
    code: |
      expected_p0 = [[3.14,]]
      expected_p1 = [['i1', 1.0], ['i2', 2.0], ['i3', 3.0]]
      expected_p1R = [['i1', 1.0], ['i2', 2.0], ['i3', 3.0]]
      data = connect.container.data["p0"].records.values.tolist()
      if data != expected_p0:
        raise Exception("Unexpected Data p0")
      data = connect.container.data["p1"].records.values.tolist()
      if data != expected_p1:
        raise Exception("Unexpected Data p1")
      data = connect.container.data["p1R"].records.values.tolist()
      if data != expected_p1R:
        raise Exception("Unexpected Data p1R")
$offEmbeddedCode

$log read scalar, 1-dim with rdim=0, 1-dim with rdim=1 that are very close together
$onEmbeddedCode Connect:
- PandasExcelReader:
    file: capdxlsr.xlsx
    symbols:
      - name: p0
        range: dim0!A5:B7
        rowDimension: 0
        columnDimension: 0
      - name: p1
        range: dim0!C5:D8
        rowDimension: 1
        columnDimension: 0
      - name: p1R
        range: dim0!E5:H6
        rowDimension: 0
        columnDimension: 1
- PythonCode:
    code: |
      expected_p0 = [[3.14,]]
      expected_p1 = [['i1', 1.0], ['i2', 2.0], ['i3', 3.0]]
      expected_p1R = [['i1', 1.0], ['i2', 2.0], ['i3', 3.0]]
      data = connect.container.data["p0"].records.values.tolist()
      if data != expected_p0:
        raise Exception("Unexpected Data p0")
      data = connect.container.data["p1"].records.values.tolist()
      if data != expected_p1:
        raise Exception("Unexpected Data p1")
      data = connect.container.data["p1R"].records.values.tolist()
      if data != expected_p1R:
        raise Exception("Unexpected Data p1R")
$offEmbeddedCode


$log read parameter with NW:SE and garbage borders
$onEmbeddedCode Connect:
- PandasExcelReader:
    file: capdxlsr.xlsx
    symbols:
      - name: p1_1
        range: nwse!B2:E5
        rowDimension: 1
        columnDimension: 1
      - name: p1_0
        range: nwse!B8:C11
        rowDimension: 1
        columnDimension: 0
      - name: p0_1
        range: nwse!F8:I9
        rowDimension: 0
        columnDimension: 1
      - name: p2_0
        range: nwse!B14:D17
        rowDimension: 2
        columnDimension: 0
      - name: p3_0
        range: nwse!G14:J17
        rowDimension: 3
        columnDimension: 0
      - name: p0_2
        range: nwse!B21:E24
        rowDimension: 0
        columnDimension: 2
      - name: p0_3
        range: nwse!H21:K25
        rowDimension: 0
        columnDimension: 3
      - name: p2_3
        range: nwse!B28:F34
        rowDimension: 2
        columnDimension: 3
- PythonCode:
    code: |
      expected_p1_1 = [['i1', 'j1', 1.0], ['i1', 'j2', 2.0], ['i1', 'j3', 3.0],
                       ['i2', 'j1', 4.0], ['i2', 'j2', 5.0], ['i2', 'j3', 6.0],
                       ['i3', 'j1', 7.0], ['i3', 'j2', 8.0], ['i3', 'j3', 9.0]]

      expected_p1_0 = [['i1', 1.0], ['i2', 4.0], ['i3', 7.0]]
      expected_p0_1 = [['j1', 1.0], ['j2', 2.0], ['j3', 3.0]]
      expected_p2_0 = [['i1', 'i1', 1.0], ['i2', 'i2', 4.0], ['i3', 'i3', 7.0]]
      expected_p3_0 = [['i1', 'i1', 'i1', 1.0], ['i2', 'i2', 'i2', 4.0], ['i3', 'i3', 'i3', 7.0]]
      expected_p0_2 = [['j1', 'j1', 1.0], ['j2', 'j2', 2.0], ['j3', 'j3', 3.0]]
      expected_p0_3 = [['j1', 'j1', 'j1', 1.0], ['j2', 'j2', 'j2', 2.0], ['j3', 'j3', 'j3', 3.0]]
      expected_p2_3 = [['i1', 'i1', 'j1', 'j1', 'j1', 1.0], ['i2', 'i2', 'j2', 'j2', 'j2', 2.0], ['i3', 'i3', 'j3', 'j3', 'j3', 3.0]]
      sym = connect.container.data["p1_1"]
      sym.records.sort_values(sym.records.columns[:-1].tolist(), inplace=True)
      data = sym.records.values.tolist()
      if data != expected_p1_1:
        raise Exception("Unexpected Data p1_1")
      data = connect.container.data["p1_0"].records.values.tolist()
      if data != expected_p1_0:
        raise Exception("Unexpected Data p1_0")
      data = connect.container.data["p0_1"].records.values.tolist()
      if data != expected_p0_1:
        raise Exception("Unexpected Data p0_1")
      data = connect.container.data["p2_0"].records.values.tolist()
      if data != expected_p2_0:
        raise Exception("Unexpected Data p2_0")
      data = connect.container.data["p3_0"].records.values.tolist()
      if data != expected_p3_0:
        raise Exception("Unexpected Data p3_0")
      data = connect.container.data["p0_2"].records.values.tolist()
      if data != expected_p0_2:
        raise Exception("Unexpected Data p0_2")
      data = connect.container.data["p0_3"].records.values.tolist()
      if data != expected_p0_3:
        raise Exception("Unexpected Data p0_3")
      data = connect.container.data["p2_3"].records.values.tolist()
      if data != expected_p2_3:
        raise Exception("Unexpected Data p2_3")
$offEmbeddedCode

$log read parameter with some 0 dim with NW only and garbage border
$onEmbeddedCode Connect:
- PandasExcelReader:
    file: capdxlsr.xlsx
    symbols:
      - name: p1_0
        range: nw0cdim!B2
        rowDimension: 1
        columnDimension: 0
      - name: p0_1
        range: nw0rdim!B2
        rowDimension: 0
        columnDimension: 1
      - name: p2_0
        range: nw0cdim!F2
        rowDimension: 2
        columnDimension: 0
      - name: p3_0
        range: nw0cdim!K2
        rowDimension: 3
        columnDimension: 0
      - name: p0_2
        range: nw0rdim!B6
        rowDimension: 0
        columnDimension: 2
      - name: p0_3
        range: nw0rdim!B12
        rowDimension: 0
        columnDimension: 3
- PythonCode:
    code: |
      expected_p1_0 = [['i1', 1.0], ['i2', 4.0], ['i3', 7.0]]
      expected_p0_1 = [['j1', 1.0], ['j2', 2.0], ['j3', 3.0]]
      expected_p2_0 = [['i1', 'i1', 1.0], ['i2', 'i2', 4.0], ['i3', 'i3', 7.0]]
      expected_p3_0 = [['i1', 'i1', 'i1', 1.0], ['i2', 'i2', 'i2', 4.0], ['i3', 'i3', 'i3', 7.0]]
      expected_p0_2 = [['j1', 'j1', 1.0], ['j2', 'j2', 2.0], ['j3', 'j3', 3.0]]
      expected_p0_3 = [['j1', 'j1', 'j1', 1.0], ['j2', 'j2', 'j2', 2.0], ['j3', 'j3', 'j3', 3.0]]
      data = connect.container.data["p1_0"].records.values.tolist()
      if data != expected_p1_0:
        raise Exception("Unexpected Data p1_0")
      data = connect.container.data["p0_1"].records.values.tolist()
      if data != expected_p0_1:
        raise Exception("Unexpected Data p0_1")
      data = connect.container.data["p2_0"].records.values.tolist()
      if data != expected_p2_0:
        raise Exception("Unexpected Data p2_0")
      data = connect.container.data["p3_0"].records.values.tolist()
      if data != expected_p3_0:
        raise Exception("Unexpected Data p3_0")
      data = connect.container.data["p0_2"].records.values.tolist()
      if data != expected_p0_2:
        raise Exception("Unexpected Data p0_2")
      data = connect.container.data["p0_3"].records.values.tolist()
      if data != expected_p0_3:
        raise Exception("Unexpected Data p0_3")
$offEmbeddedCode

$log read parameter with cdim>1 but no extra blank link with NW:SE and NW (for rdim=0) and garbage borders
$onEmbeddedCode Connect:
- PandasExcelReader:
    file: capdxlsr.xlsx
    multiColumnBlankRow: False
    symbols:
      - name: p0_2
        range: cdim2tight!B2:E4
        rowDimension: 0
        columnDimension: 2
      - name: p0_3
        range: cdim2tight!B7:E10
        rowDimension: 0
        columnDimension: 3
      - name: p2_3
        range: cdim2tight!B13:F18
        rowDimension: 2
        columnDimension: 3
      - name: p2_3x
        range: cdim2tight!B21:F26
        rowDimension: 2
        columnDimension: 3
      - name: s2_3  # Works unexpectedly (row 46 as a totally blank row is interpreted as index name row, not as data):
        range: cdim2tight!B43
        rowDimension: 2
        columnDimension: 3
        type: set
        valueSubstitutions: { .nan: '' }
      - name: p0_2x
        range: cdim2tight!B29
        rowDimension: 0
        columnDimension: 2
      - name: p0_3x
        range: cdim2tight!B34
        rowDimension: 0
        columnDimension: 3
- PythonCode:
    code: |
      expected_p0_2 = [['j1', 'j1', 1.0], ['j2', 'j2', 2.0], ['j3', 'j3', 3.0]]
      expected_p0_3 = [['j1', 'j1', 'j1', 1.0], ['j2', 'j2', 'j2', 2.0], ['j3', 'j3', 'j3', 3.0]]
      expected_p2_3 = [['i1', 'i1', 'j1', 'j1', 'j1', 1.0], ['i2', 'i2', 'j2', 'j2', 'j2', 2.0], ['i3', 'i3', 'j3', 'j3', 'j3', 3.0]]
      expected_p2_3x = [['i2', 'i2', 'j2', 'j2', 'j2', 2.0], ['i3', 'i3', 'j3', 'j3', 'j3', 3.0]]
      expected_s2_3 = [['i2', 'i3', 'j1', 'j1', 'j1', ''], ['i2', 'i3', 'j2', 'j2', 'j2', '2.0'],
                       ['i2', 'i3', 'j3', 'j3', 'j3', ''], ['i2', 'i3', 'j4', 'j4', 'j4', ''],
                       ['i3', 'i4', 'j1', 'j1', 'j1', ''], ['i3', 'i4', 'j2', 'j2', 'j2', ''],
                       ['i3', 'i4', 'j3', 'j3', 'j3', '3.0'], ['i3', 'i4', 'j4', 'j4', 'j4', '']]

      data = connect.container.data["p0_2"].records.values.tolist()
      if data != expected_p0_2:
        raise Exception("Unexpected Data p0_2")
      data = connect.container.data["p0_3"].records.values.tolist()
      if data != expected_p0_3:
        raise Exception("Unexpected Data p0_3")
      data = connect.container.data["p2_3"].records.values.tolist()
      if data != expected_p2_3:
        raise Exception("Unexpected Data p2_3")
      data = connect.container.data["p2_3x"].records.values.tolist()
      if data != expected_p2_3x:
        raise Exception("Unexpected Data p2_3x")
      data = connect.container.data["p0_2x"].records.values.tolist()
      if data != expected_p0_2:
        raise Exception("Unexpected Data p0_2x")
      data = connect.container.data["p0_3x"].records.values.tolist()
      if data != expected_p0_3:
        raise Exception("Unexpected Data p0_3x")
      sym = connect.container.data["s2_3"]
      sym.records.sort_values(sym.records.columns[:-1].tolist(), inplace=True)
      data = sym.records.values.tolist()
      if data != expected_s2_3:
        raise Exception("Unexpected Data s2_3")
$offEmbeddedCode