gamsapi 52.5.0__cp312-cp312-win_amd64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (257) hide show
  1. gams/__init__.py +27 -0
  2. gams/_version.py +1 -0
  3. gams/connect/__init__.py +28 -0
  4. gams/connect/agents/__init__.py +24 -0
  5. gams/connect/agents/_excel/__init__.py +32 -0
  6. gams/connect/agents/_excel/excelagent.py +312 -0
  7. gams/connect/agents/_excel/workbook.py +155 -0
  8. gams/connect/agents/_sqlconnectors/__init__.py +42 -0
  9. gams/connect/agents/_sqlconnectors/_accesshandler.py +211 -0
  10. gams/connect/agents/_sqlconnectors/_databasehandler.py +250 -0
  11. gams/connect/agents/_sqlconnectors/_mysqlhandler.py +168 -0
  12. gams/connect/agents/_sqlconnectors/_postgreshandler.py +131 -0
  13. gams/connect/agents/_sqlconnectors/_pyodbchandler.py +112 -0
  14. gams/connect/agents/_sqlconnectors/_sqlalchemyhandler.py +74 -0
  15. gams/connect/agents/_sqlconnectors/_sqlitehandler.py +262 -0
  16. gams/connect/agents/_sqlconnectors/_sqlserverhandler.py +179 -0
  17. gams/connect/agents/concatenate.py +440 -0
  18. gams/connect/agents/connectagent.py +743 -0
  19. gams/connect/agents/csvreader.py +675 -0
  20. gams/connect/agents/csvwriter.py +151 -0
  21. gams/connect/agents/domainwriter.py +143 -0
  22. gams/connect/agents/excelreader.py +756 -0
  23. gams/connect/agents/excelwriter.py +467 -0
  24. gams/connect/agents/filter.py +223 -0
  25. gams/connect/agents/gamsreader.py +112 -0
  26. gams/connect/agents/gamswriter.py +239 -0
  27. gams/connect/agents/gdxreader.py +109 -0
  28. gams/connect/agents/gdxwriter.py +146 -0
  29. gams/connect/agents/labelmanipulator.py +303 -0
  30. gams/connect/agents/projection.py +539 -0
  31. gams/connect/agents/pythoncode.py +71 -0
  32. gams/connect/agents/rawcsvreader.py +248 -0
  33. gams/connect/agents/rawexcelreader.py +312 -0
  34. gams/connect/agents/schema/CSVReader.yaml +92 -0
  35. gams/connect/agents/schema/CSVWriter.yaml +44 -0
  36. gams/connect/agents/schema/Concatenate.yaml +52 -0
  37. gams/connect/agents/schema/DomainWriter.yaml +25 -0
  38. gams/connect/agents/schema/ExcelReader.yaml +121 -0
  39. gams/connect/agents/schema/ExcelWriter.yaml +78 -0
  40. gams/connect/agents/schema/Filter.yaml +74 -0
  41. gams/connect/agents/schema/GAMSReader.yaml +20 -0
  42. gams/connect/agents/schema/GAMSWriter.yaml +47 -0
  43. gams/connect/agents/schema/GDXReader.yaml +23 -0
  44. gams/connect/agents/schema/GDXWriter.yaml +32 -0
  45. gams/connect/agents/schema/LabelManipulator.yaml +99 -0
  46. gams/connect/agents/schema/Projection.yaml +24 -0
  47. gams/connect/agents/schema/PythonCode.yaml +6 -0
  48. gams/connect/agents/schema/RawCSVReader.yaml +34 -0
  49. gams/connect/agents/schema/RawExcelReader.yaml +42 -0
  50. gams/connect/agents/schema/SQLReader.yaml +75 -0
  51. gams/connect/agents/schema/SQLWriter.yaml +103 -0
  52. gams/connect/agents/sqlreader.py +301 -0
  53. gams/connect/agents/sqlwriter.py +276 -0
  54. gams/connect/connectdatabase.py +275 -0
  55. gams/connect/connectvalidator.py +93 -0
  56. gams/connect/errors.py +34 -0
  57. gams/control/__init__.py +136 -0
  58. gams/control/database.py +2231 -0
  59. gams/control/execution.py +1900 -0
  60. gams/control/options.py +2792 -0
  61. gams/control/workspace.py +1198 -0
  62. gams/core/__init__.py +24 -0
  63. gams/core/cfg/__init__.py +26 -0
  64. gams/core/cfg/_cfgmcc.cp312-win_amd64.pyd +0 -0
  65. gams/core/cfg/cfgmcc.py +519 -0
  66. gams/core/dct/__init__.py +26 -0
  67. gams/core/dct/_dctmcc.cp312-win_amd64.pyd +0 -0
  68. gams/core/dct/dctmcc.py +574 -0
  69. gams/core/embedded/__init__.py +26 -0
  70. gams/core/embedded/gamsemb.py +1024 -0
  71. gams/core/emp/__init__.py +24 -0
  72. gams/core/emp/emplexer.py +89 -0
  73. gams/core/emp/empyacc.py +281 -0
  74. gams/core/gdx/__init__.py +26 -0
  75. gams/core/gdx/_gdxcc.cp312-win_amd64.pyd +0 -0
  76. gams/core/gdx/gdxcc.py +866 -0
  77. gams/core/gev/__init__.py +26 -0
  78. gams/core/gev/_gevmcc.cp312-win_amd64.pyd +0 -0
  79. gams/core/gev/gevmcc.py +855 -0
  80. gams/core/gmd/__init__.py +26 -0
  81. gams/core/gmd/_gmdcc.cp312-win_amd64.pyd +0 -0
  82. gams/core/gmd/gmdcc.py +917 -0
  83. gams/core/gmo/__init__.py +26 -0
  84. gams/core/gmo/_gmomcc.cp312-win_amd64.pyd +0 -0
  85. gams/core/gmo/gmomcc.py +2046 -0
  86. gams/core/idx/__init__.py +26 -0
  87. gams/core/idx/_idxcc.cp312-win_amd64.pyd +0 -0
  88. gams/core/idx/idxcc.py +510 -0
  89. gams/core/numpy/__init__.py +29 -0
  90. gams/core/numpy/_gams2numpy.cp312-win_amd64.pyd +0 -0
  91. gams/core/numpy/gams2numpy.py +1048 -0
  92. gams/core/opt/__init__.py +26 -0
  93. gams/core/opt/_optcc.cp312-win_amd64.pyd +0 -0
  94. gams/core/opt/optcc.py +840 -0
  95. gams/engine/__init__.py +204 -0
  96. gams/engine/api/__init__.py +13 -0
  97. gams/engine/api/auth_api.py +7653 -0
  98. gams/engine/api/cleanup_api.py +751 -0
  99. gams/engine/api/default_api.py +887 -0
  100. gams/engine/api/hypercube_api.py +2629 -0
  101. gams/engine/api/jobs_api.py +5229 -0
  102. gams/engine/api/licenses_api.py +2220 -0
  103. gams/engine/api/namespaces_api.py +7783 -0
  104. gams/engine/api/usage_api.py +5627 -0
  105. gams/engine/api/users_api.py +5931 -0
  106. gams/engine/api_client.py +804 -0
  107. gams/engine/api_response.py +21 -0
  108. gams/engine/configuration.py +601 -0
  109. gams/engine/exceptions.py +216 -0
  110. gams/engine/models/__init__.py +86 -0
  111. gams/engine/models/bad_input.py +89 -0
  112. gams/engine/models/cleanable_job_result.py +104 -0
  113. gams/engine/models/cleanable_job_result_page.py +113 -0
  114. gams/engine/models/engine_license.py +107 -0
  115. gams/engine/models/files_not_found.py +93 -0
  116. gams/engine/models/forwarded_token_response.py +112 -0
  117. gams/engine/models/generic_key_value_pair.py +89 -0
  118. gams/engine/models/hypercube.py +160 -0
  119. gams/engine/models/hypercube_page.py +111 -0
  120. gams/engine/models/hypercube_summary.py +91 -0
  121. gams/engine/models/hypercube_token.py +97 -0
  122. gams/engine/models/identity_provider.py +107 -0
  123. gams/engine/models/identity_provider_ldap.py +121 -0
  124. gams/engine/models/identity_provider_oauth2.py +146 -0
  125. gams/engine/models/identity_provider_oauth2_scope.py +89 -0
  126. gams/engine/models/identity_provider_oauth2_with_secret.py +152 -0
  127. gams/engine/models/identity_provider_oidc.py +133 -0
  128. gams/engine/models/identity_provider_oidc_with_secret.py +143 -0
  129. gams/engine/models/inex.py +91 -0
  130. gams/engine/models/invitation.py +136 -0
  131. gams/engine/models/invitation_quota.py +106 -0
  132. gams/engine/models/invitation_token.py +87 -0
  133. gams/engine/models/job.py +165 -0
  134. gams/engine/models/job_no_text_entry.py +138 -0
  135. gams/engine/models/job_no_text_entry_page.py +111 -0
  136. gams/engine/models/license.py +91 -0
  137. gams/engine/models/log_piece.py +96 -0
  138. gams/engine/models/message.py +87 -0
  139. gams/engine/models/message_and_token.py +99 -0
  140. gams/engine/models/message_with_webhook_id.py +89 -0
  141. gams/engine/models/model_auth_token.py +87 -0
  142. gams/engine/models/model_configuration.py +125 -0
  143. gams/engine/models/model_default_instance.py +99 -0
  144. gams/engine/models/model_default_user_instance.py +98 -0
  145. gams/engine/models/model_hypercube_job.py +106 -0
  146. gams/engine/models/model_hypercube_usage.py +130 -0
  147. gams/engine/models/model_instance_info.py +116 -0
  148. gams/engine/models/model_instance_info_full.py +123 -0
  149. gams/engine/models/model_instance_pool_info.py +112 -0
  150. gams/engine/models/model_job_labels.py +179 -0
  151. gams/engine/models/model_job_usage.py +133 -0
  152. gams/engine/models/model_pool_usage.py +124 -0
  153. gams/engine/models/model_usage.py +115 -0
  154. gams/engine/models/model_user.py +96 -0
  155. gams/engine/models/model_userinstance_info.py +119 -0
  156. gams/engine/models/model_userinstancepool_info.py +95 -0
  157. gams/engine/models/model_version.py +91 -0
  158. gams/engine/models/models.py +120 -0
  159. gams/engine/models/namespace.py +104 -0
  160. gams/engine/models/namespace_quota.py +96 -0
  161. gams/engine/models/namespace_with_permission.py +96 -0
  162. gams/engine/models/not_found.py +91 -0
  163. gams/engine/models/password_policy.py +97 -0
  164. gams/engine/models/perm_and_username.py +89 -0
  165. gams/engine/models/quota.py +117 -0
  166. gams/engine/models/quota_exceeded.py +97 -0
  167. gams/engine/models/status_code_meaning.py +89 -0
  168. gams/engine/models/stream_entry.py +89 -0
  169. gams/engine/models/system_wide_license.py +92 -0
  170. gams/engine/models/text_entries.py +87 -0
  171. gams/engine/models/text_entry.py +101 -0
  172. gams/engine/models/time_span.py +95 -0
  173. gams/engine/models/time_span_pool_worker.py +99 -0
  174. gams/engine/models/token_forward_error.py +87 -0
  175. gams/engine/models/user.py +127 -0
  176. gams/engine/models/user_group_member.py +96 -0
  177. gams/engine/models/user_groups.py +108 -0
  178. gams/engine/models/vapid_info.py +87 -0
  179. gams/engine/models/webhook.py +138 -0
  180. gams/engine/models/webhook_parameterized_event.py +99 -0
  181. gams/engine/py.typed +0 -0
  182. gams/engine/rest.py +258 -0
  183. gams/magic/__init__.py +32 -0
  184. gams/magic/gams_magic.py +142 -0
  185. gams/magic/interactive.py +402 -0
  186. gams/tools/__init__.py +30 -0
  187. gams/tools/errors.py +34 -0
  188. gams/tools/toolcollection/__init__.py +24 -0
  189. gams/tools/toolcollection/alg/__init__.py +24 -0
  190. gams/tools/toolcollection/alg/rank.py +51 -0
  191. gams/tools/toolcollection/data/__init__.py +24 -0
  192. gams/tools/toolcollection/data/csvread.py +444 -0
  193. gams/tools/toolcollection/data/csvwrite.py +311 -0
  194. gams/tools/toolcollection/data/exceldump.py +47 -0
  195. gams/tools/toolcollection/data/sqlitewrite.py +276 -0
  196. gams/tools/toolcollection/gdxservice/__init__.py +24 -0
  197. gams/tools/toolcollection/gdxservice/gdxencoding.py +104 -0
  198. gams/tools/toolcollection/gdxservice/gdxrename.py +94 -0
  199. gams/tools/toolcollection/linalg/__init__.py +24 -0
  200. gams/tools/toolcollection/linalg/cholesky.py +57 -0
  201. gams/tools/toolcollection/linalg/eigenvalue.py +56 -0
  202. gams/tools/toolcollection/linalg/eigenvector.py +58 -0
  203. gams/tools/toolcollection/linalg/invert.py +55 -0
  204. gams/tools/toolcollection/linalg/ols.py +138 -0
  205. gams/tools/toolcollection/tooltemplate.py +321 -0
  206. gams/tools/toolcollection/win32/__init__.py +24 -0
  207. gams/tools/toolcollection/win32/excelmerge.py +93 -0
  208. gams/tools/toolcollection/win32/exceltalk.py +76 -0
  209. gams/tools/toolcollection/win32/msappavail.py +49 -0
  210. gams/tools/toolcollection/win32/shellexecute.py +54 -0
  211. gams/tools/tools.py +116 -0
  212. gams/transfer/__init__.py +35 -0
  213. gams/transfer/_abcs/__init__.py +37 -0
  214. gams/transfer/_abcs/container_abcs.py +433 -0
  215. gams/transfer/_internals/__init__.py +63 -0
  216. gams/transfer/_internals/algorithms.py +436 -0
  217. gams/transfer/_internals/casepreservingdict.py +124 -0
  218. gams/transfer/_internals/constants.py +270 -0
  219. gams/transfer/_internals/domainviolation.py +103 -0
  220. gams/transfer/_internals/specialvalues.py +172 -0
  221. gams/transfer/containers/__init__.py +26 -0
  222. gams/transfer/containers/_container.py +1794 -0
  223. gams/transfer/containers/_io/__init__.py +28 -0
  224. gams/transfer/containers/_io/containers.py +164 -0
  225. gams/transfer/containers/_io/gdx.py +1029 -0
  226. gams/transfer/containers/_io/gmd.py +872 -0
  227. gams/transfer/containers/_mixins/__init__.py +26 -0
  228. gams/transfer/containers/_mixins/ccc.py +1274 -0
  229. gams/transfer/syms/__init__.py +33 -0
  230. gams/transfer/syms/_methods/__init__.py +24 -0
  231. gams/transfer/syms/_methods/tables.py +120 -0
  232. gams/transfer/syms/_methods/toDict.py +115 -0
  233. gams/transfer/syms/_methods/toList.py +83 -0
  234. gams/transfer/syms/_methods/toValue.py +60 -0
  235. gams/transfer/syms/_mixins/__init__.py +32 -0
  236. gams/transfer/syms/_mixins/equals.py +626 -0
  237. gams/transfer/syms/_mixins/generateRecords.py +499 -0
  238. gams/transfer/syms/_mixins/pivot.py +313 -0
  239. gams/transfer/syms/_mixins/pve.py +627 -0
  240. gams/transfer/syms/_mixins/sa.py +27 -0
  241. gams/transfer/syms/_mixins/sapve.py +27 -0
  242. gams/transfer/syms/_mixins/saua.py +27 -0
  243. gams/transfer/syms/_mixins/sauapve.py +199 -0
  244. gams/transfer/syms/_mixins/spve.py +1528 -0
  245. gams/transfer/syms/_mixins/ve.py +936 -0
  246. gams/transfer/syms/container_syms/__init__.py +31 -0
  247. gams/transfer/syms/container_syms/_alias.py +984 -0
  248. gams/transfer/syms/container_syms/_equation.py +333 -0
  249. gams/transfer/syms/container_syms/_parameter.py +973 -0
  250. gams/transfer/syms/container_syms/_set.py +604 -0
  251. gams/transfer/syms/container_syms/_universe_alias.py +461 -0
  252. gams/transfer/syms/container_syms/_variable.py +321 -0
  253. gamsapi-52.5.0.dist-info/METADATA +150 -0
  254. gamsapi-52.5.0.dist-info/RECORD +257 -0
  255. gamsapi-52.5.0.dist-info/WHEEL +5 -0
  256. gamsapi-52.5.0.dist-info/licenses/LICENSE +22 -0
  257. gamsapi-52.5.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,1274 @@
1
+ #
2
+ # GAMS - General Algebraic Modeling System Python API
3
+ #
4
+ # Copyright (c) 2017-2026 GAMS Development Corp. <support@gams.com>
5
+ # Copyright (c) 2017-2026 GAMS Software GmbH <support@gams.com>
6
+ #
7
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ # of this software and associated documentation files (the "Software"), to deal
9
+ # in the Software without restriction, including without limitation the rights
10
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ # copies of the Software, and to permit persons to whom the Software is
12
+ # furnished to do so, subject to the following conditions:
13
+ #
14
+ # The above copyright notice and this permission notice shall be included in all
15
+ # copies or substantial portions of the Software.
16
+ #
17
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23
+ # SOFTWARE.
24
+ #
25
+
26
+ import os
27
+ import pathlib
28
+ from collections.abc import Iterable
29
+ import pandas as pd
30
+ from gams.control import GamsDatabase
31
+ from gams.core import gmd
32
+ from gams.transfer._internals import (
33
+ SourceType,
34
+ EQU_TYPE,
35
+ TRANSFER_TO_GAMS_VARIABLE_SUBTYPES,
36
+ TRANSFER_TO_GAMS_EQUATION_SUBTYPES,
37
+ )
38
+ import gams.transfer._abcs as abcs
39
+ from typing import Optional, Union, List, Dict, Sequence
40
+
41
+
42
+ class CCCMixin:
43
+ @property
44
+ def data(self) -> Dict[str, "abcs.AnyContainerSymbol"]:
45
+ return self._data
46
+
47
+ @data.setter
48
+ def data(self, data) -> None:
49
+ """Dictionary of symbols where keys are symbol names and values are symbol objects"""
50
+ self._data = data
51
+
52
+ def __len__(self):
53
+ return len(self.data)
54
+
55
+ def isValid(
56
+ self,
57
+ symbols: Optional[Union[str, List[str]]] = None,
58
+ verbose: bool = False,
59
+ force: bool = False,
60
+ ) -> bool:
61
+ """
62
+ Check the validity of symbols in the Container.
63
+
64
+ This method checks the validity of symbols in the Container to ensure that they are consistent and correctly defined. It can check the validity of specific symbols or all symbols in the Container.
65
+
66
+ Parameters
67
+ ----------
68
+ symbols : str | List[str], optional
69
+ A list of symbol names or a single symbol name to be checked for validity. If None, all symbols in the Container will be checked.
70
+
71
+ verbose : bool, by default False
72
+ A boolean flag indicating whether to raise an exception if an invalid symbol is found. If True, an exception is raised; if False, the method returns False for invalid symbols.
73
+
74
+ force : bool, by default False
75
+ A boolean flag indicating whether to force a recheck of the symbols' validity.
76
+
77
+ Returns
78
+ -------
79
+ bool
80
+ Returns True if specified symbols (or all symbols in the Container) are valid. If any symbol is invalid and verbose is False, it returns False. If verbose is True, an exception is raised for the first invalid symbol encountered.
81
+ """
82
+ if not isinstance(symbols, (str, list, type(None))):
83
+ raise TypeError("Argument 'symbols' must be type list or NoneType")
84
+
85
+ if symbols is None:
86
+ cache = True
87
+ symbols = list(self.data.keys())
88
+ else:
89
+ cache = False
90
+
91
+ if isinstance(symbols, str):
92
+ symbols = [symbols]
93
+
94
+ if isinstance(symbols, list):
95
+ if any(not isinstance(i, str) for i in symbols):
96
+ raise TypeError("Argument 'symbols' must contain only type str")
97
+
98
+ if not isinstance(verbose, bool):
99
+ raise ValueError("Argument 'verbose' must be type bool")
100
+
101
+ if not isinstance(force, bool):
102
+ raise ValueError("Argument 'force' must be type bool")
103
+
104
+ if force:
105
+ self._requires_state_check = True
106
+
107
+ if self._requires_state_check:
108
+ try:
109
+ self._assert_is_valid(symbols)
110
+
111
+ if not cache:
112
+ self._requires_state_check = True
113
+
114
+ return True
115
+ except Exception as err:
116
+ if verbose:
117
+ raise err
118
+ return False
119
+ else:
120
+ return True
121
+
122
+ def listSymbols(self, is_valid: Optional[bool] = None) -> List[str]:
123
+ """
124
+ Get a list of symbol names in the Container.
125
+
126
+ This method returns a list of symbol names that are stored in the Container. You can optionally filter the list based on the validity of the symbols.
127
+
128
+ Parameters
129
+ ----------
130
+ is_valid : bool, optional
131
+ An optional boolean flag used to filter the list of symbols. If None (default), all symbols in the Container are returned.
132
+ - If True, only valid symbols are included in the list.
133
+ - If False, only invalid symbols are included in the list.
134
+
135
+ Returns
136
+ -------
137
+ List[str]
138
+ A list of symbol names in the Container.
139
+
140
+ Raises
141
+ ------
142
+ TypeError
143
+ If the 'is_valid' argument is not of type bool or NoneType.
144
+
145
+ Examples
146
+ --------
147
+ >>> import gams.transfer as gt
148
+ >>> m = gt.Container()
149
+ >>> i = gt.Set(m, name="i", records=["seattle", "san-diego"])
150
+ >>> j = gt.Set(m, name="j", records=["new-york", "chicago", "topeka"])
151
+ >>> a = gt.Parameter(m, name="a", domain=[i], records=[["seattle", 350], ["san-diego", 600]])
152
+ >>> b = gt.Parameter(m, name="b", domain=[j], records=[["new-york", 325], ["chicago", 300], ["topeka", 275]])
153
+ >>> print(m.listSymbols())
154
+ ['i', 'j', 'a', 'b']
155
+ """
156
+ if not isinstance(is_valid, (bool, type(None))):
157
+ raise TypeError("Argument 'is_valid' must be type bool or NoneType")
158
+
159
+ if is_valid is True:
160
+ return [symname for symname, symobj in self if symobj.isValid()]
161
+ elif is_valid is False:
162
+ return [symname for symname, symobj in self if not symobj.isValid()]
163
+ else:
164
+ return [symname for symname, symobj in self]
165
+
166
+ def listParameters(self, is_valid: Optional[bool] = None) -> List[str]:
167
+ """
168
+ Get a list of parameter names in the Container.
169
+
170
+ This method returns a list of parameter names that are stored in the Container. You can optionally filter the list based on the validity of the parameters.
171
+
172
+ Parameters
173
+ ----------
174
+ is_valid : bool, optional
175
+ An optional boolean flag used to filter the list of parameters. If None (default), all parameters in the Container are returned.
176
+ - If True, only valid parameters are included in the list.
177
+ - If False, only invalid parameters are included in the list.
178
+
179
+ Returns
180
+ -------
181
+ List[str]
182
+ A list of parameter names in the Container, optionally filtered by validity.
183
+
184
+ Raises
185
+ ------
186
+ TypeError
187
+ If the 'is_valid' argument is not of type bool or NoneType.
188
+
189
+ Examples
190
+ --------
191
+ >>> import gams.transfer as gt
192
+ >>> m = gt.Container()
193
+ >>> i = gt.Set(m, name="i", records=["seattle", "san-diego"])
194
+ >>> j = gt.Set(m, name="j", records=["new-york", "chicago", "topeka"])
195
+ >>> a = gt.Parameter(m, name="a", domain=[i], records=[["seattle", 350], ["san-diego", 600]])
196
+ >>> b = gt.Parameter(m, name="b", domain=[j], records=[["new-york", 325], ["chicago", 300], ["topeka", 275]])
197
+ >>> print(m.listParameters())
198
+ ['a', 'b']
199
+
200
+ """
201
+ if not isinstance(is_valid, (bool, type(None))):
202
+ raise TypeError("Argument 'is_valid' must be type bool or NoneType")
203
+
204
+ return [
205
+ symobj.name
206
+ for symobj in self.getSymbols(self.listSymbols(is_valid))
207
+ if isinstance(symobj, abcs.ABCParameter)
208
+ ]
209
+
210
+ def listSets(self, is_valid: Optional[bool] = None) -> List[str]:
211
+ """
212
+ Get a list of set names in the Container.
213
+
214
+ This method returns a list of set names that are stored in the Container. You can optionally filter the list based on the validity of the sets.
215
+
216
+ Parameters
217
+ ----------
218
+ is_valid : bool, optional
219
+ An optional boolean flag used to filter the list of sets. If None (default), all sets in the Container are returned.
220
+ - If True, only valid sets are included in the list.
221
+ - If False, only invalid sets are included in the list.
222
+
223
+ Returns
224
+ -------
225
+ List[str]
226
+ A list of set names in the Container, optionally filtered by validity.
227
+
228
+ Raises
229
+ ------
230
+ TypeError
231
+ If the 'is_valid' argument is not of type bool or NoneType.
232
+
233
+ Examples
234
+ --------
235
+ >>> import gams.transfer as gt
236
+ >>> m = gt.Container()
237
+ >>> i = gt.Set(m, name="i", records=["seattle", "san-diego"])
238
+ >>> j = gt.Set(m, name="j", records=["new-york", "chicago", "topeka"])
239
+ >>> a = gt.Parameter(m, name="a", domain=[i], records=[["seattle", 350], ["san-diego", 600]])
240
+ >>> b = gt.Parameter(m, name="b", domain=[j], records=[["new-york", 325], ["chicago", 300], ["topeka", 275]])
241
+ >>> print(m.listSets())
242
+ ['i', 'j']
243
+
244
+ """
245
+ if not isinstance(is_valid, (bool, type(None))):
246
+ raise TypeError("Argument 'is_valid' must be type bool or NoneType")
247
+
248
+ return [
249
+ symobj.name
250
+ for symobj in self.getSymbols(self.listSymbols(is_valid))
251
+ if isinstance(symobj, abcs.ABCSet)
252
+ ]
253
+
254
+ def listAliases(self, is_valid: Optional[bool] = None) -> List[str]:
255
+ """
256
+ Get a list of alias names in the Container.
257
+
258
+ This method returns a list of alias names that are stored in the Container. You can optionally filter the list based on the validity of the aliases.
259
+
260
+ Parameters
261
+ ----------
262
+ is_valid : bool, optional
263
+ An optional boolean flag used to filter the list of aliases. If None (default), all aliases in the Container are returned.
264
+ - If True, only valid aliases are included in the list.
265
+ - If False, only invalid aliases are included in the list.
266
+
267
+ Returns
268
+ -------
269
+ List[str]
270
+ A list of alias names in the Container, optionally filtered by validity.
271
+
272
+ Raises
273
+ ------
274
+ TypeError
275
+ If the 'is_valid' argument is not of type bool or NoneType.
276
+
277
+ Examples
278
+ --------
279
+ >>> import gams.transfer as gt
280
+ >>> m = gt.Container()
281
+ >>> plants = gt.Set(m, name="plants", records=["seattle", "san-diego"])
282
+ >>> markets = gt.Set(m, name="markets", records=["new-york", "chicago", "topeka"])
283
+ >>> i = gt.Alias(m, name="i", alias_with=plants)
284
+ >>> j = gt.Alias(m, name="j", alias_with=markets)
285
+ >>> a = gt.Parameter(m, name="a", domain=[i], records=[["seattle", 350], ["san-diego", 600]])
286
+ >>> b = gt.Parameter(m, name="b", domain=[j], records=[["new-york", 325], ["chicago", 300], ["topeka", 275]])
287
+ >>> print(m.listAliases())
288
+ ['i', 'j']
289
+
290
+ """
291
+ if not isinstance(is_valid, (bool, type(None))):
292
+ raise TypeError("Argument 'is_valid' must be type bool or NoneType")
293
+
294
+ return [
295
+ symobj.name
296
+ for symobj in self.getSymbols(self.listSymbols(is_valid))
297
+ if isinstance(symobj, (abcs.ABCAlias, abcs.ABCUniverseAlias))
298
+ ]
299
+
300
+ def listVariables(
301
+ self,
302
+ is_valid: Optional[bool] = None,
303
+ types: Optional[Union[str, List[str]]] = None,
304
+ ) -> List[str]:
305
+ """
306
+ Get a list of variable names in the Container.
307
+
308
+ This method returns a list of variable names that are stored in the Container. You can optionally filter the list based on the validity and type of the variables.
309
+
310
+ Parameters
311
+ ----------
312
+ is_valid : bool, optional
313
+ An optional boolean flag used to filter the list of variables based on their validity.
314
+ - If True, only valid variables are included in the list.
315
+ - If False, only invalid variables are included in the list.
316
+ - If None (default), all variables are included in the list.
317
+
318
+ types : str | List[str], optional
319
+ An optional string or list of strings specifying the types of variables to include in the list.
320
+ - If None (default), all variable types are included in the list.
321
+ - If a string or list of strings is provided, only variables of the specified types are included in the list.
322
+
323
+ Returns
324
+ -------
325
+ List[str]
326
+ A list of variable names in the Container, optionally filtered by validity and type.
327
+
328
+ Raises
329
+ ------
330
+ TypeError
331
+ If the 'is_valid' argument is not of type bool or NoneType, or if the 'types' argument is not of type str, list, or NoneType.
332
+ ValueError
333
+ If the 'types' argument contains unrecognized variable types.
334
+
335
+ Examples
336
+ --------
337
+ >>> import gams.transfer as gt
338
+ >>> m = gt.Container()
339
+ >>> i = gt.Set(m, name="i", records=["seattle", "san-diego"])
340
+ >>> j = gt.Set(m, name="j", records=["new-york", "chicago", "topeka"])
341
+ >>> a = gt.Parameter(m, name="a", domain=[i], records=[["seattle", 350], ["san-diego", 600]])
342
+ >>> b = gt.Parameter(m, name="b", domain=[j], records=[["new-york", 325], ["chicago", 300], ["topeka", 275]])
343
+ >>> x = gt.Variable(m, name="x", domain=[i, j], type="positive")
344
+ >>> z = gt.Variable(m, name="z", type="free")
345
+ >>> print(m.listVariables())
346
+ ['x', 'z']
347
+ >>> print(m.listVariables(types="free"))
348
+ ['z']
349
+
350
+ """
351
+ if not isinstance(is_valid, (bool, type(None))):
352
+ raise TypeError("Argument 'is_valid' must be type bool or NoneType")
353
+
354
+ if not isinstance(types, (str, list, type(None))):
355
+ raise TypeError("Argument 'types' must be type str, list, or NoneType")
356
+
357
+ if types is None:
358
+ return [
359
+ symobj.name
360
+ for symobj in self.getSymbols(self.listSymbols(is_valid))
361
+ if isinstance(symobj, abcs.ABCVariable)
362
+ ]
363
+
364
+ else:
365
+ if isinstance(types, str):
366
+ types = [types]
367
+
368
+ # casefold to allow mixed case matching
369
+ types = [i.casefold() for i in types]
370
+
371
+ if any(i not in TRANSFER_TO_GAMS_VARIABLE_SUBTYPES.keys() for i in types):
372
+ raise ValueError(
373
+ "User input unrecognized variable type, "
374
+ f"variable types can only take: {list(TRANSFER_TO_GAMS_VARIABLE_SUBTYPES.keys())}"
375
+ )
376
+
377
+ return [
378
+ symobj.name
379
+ for symobj in self.getSymbols(self.listSymbols(is_valid))
380
+ if isinstance(symobj, abcs.ABCVariable) and symobj.type in types
381
+ ]
382
+
383
+ def listEquations(
384
+ self,
385
+ is_valid: Optional[bool] = None,
386
+ types: Optional[Union[str, List[str]]] = None,
387
+ ) -> List[str]:
388
+ """
389
+ Get a list of equation names in the Container.
390
+
391
+ This method returns a list of equation names that are stored in the Container. You can optionally filter the list based on the validity and type of the equations.
392
+
393
+ Parameters
394
+ ----------
395
+ is_valid : bool, optional
396
+ An optional boolean flag used to filter the list of equations based on their validity.
397
+ - If True, only valid equations are included in the list.
398
+ - If False, only invalid equations are included in the list.
399
+ - If None (default), all equations are included in the list.
400
+
401
+ types : str | List[str], optional
402
+ An optional string or list of strings specifying the types of equations to include in the list.
403
+ - If None (default), all equation types are included in the list.
404
+ - If a string or list of strings is provided, only equations of the specified types are included in the list.
405
+
406
+ Returns
407
+ -------
408
+ List[str]
409
+ A list of equation names in the Container, optionally filtered by validity and type.
410
+
411
+ Raises
412
+ ------
413
+ TypeError
414
+ If the 'is_valid' argument is not of type bool or NoneType, or if the 'types' argument is not of type str, list, or NoneType.
415
+ ValueError
416
+ If the 'types' argument contains unrecognized equation types.
417
+
418
+ Examples
419
+ --------
420
+ >>> import gams.transfer as gt
421
+ >>> m = gt.Container()
422
+ >>> i = gt.Set(m, name="i", records=["seattle", "san-diego"])
423
+ >>> j = gt.Set(m, name="j", records=["new-york", "chicago", "topeka"])
424
+ >>> a = gt.Parameter(m, name="a", domain=[i], records=[["seattle", 350], ["san-diego", 600]])
425
+ >>> b = gt.Parameter(m, name="b", domain=[j], records=[["new-york", 325], ["chicago", 300], ["topeka", 275]])
426
+ >>> x = gt.Variable(m, name="x", domain=[i, j], type="positive")
427
+ >>> z = gt.Variable(m, name="z", type="free")
428
+ >>> cost = gt.Equation(m, name="cost", type="eq")
429
+ >>> supply = gt.Equation(m, name="supply", type="leq", domain=[i])
430
+ >>> demand = gt.Equation(m, name="demand", type="geq", domain=[j])
431
+ >>> print(m.listEquations())
432
+ ['cost', 'supply', 'demand']
433
+ >>> print(m.listEquations(types="geq"))
434
+ ['demand']
435
+
436
+ """
437
+ if not isinstance(is_valid, (bool, type(None))):
438
+ raise TypeError("Argument 'is_valid' must be type bool or NoneType")
439
+
440
+ if not isinstance(types, (str, list, type(None))):
441
+ raise TypeError("Argument 'types' must be type str, list, or NoneType")
442
+
443
+ if types is None:
444
+ return [
445
+ symobj.name
446
+ for symobj in self.getSymbols(self.listSymbols(is_valid))
447
+ if isinstance(symobj, abcs.ABCEquation)
448
+ ]
449
+
450
+ else:
451
+ if isinstance(types, str):
452
+ types = [types]
453
+
454
+ # casefold to allow mixed case matching (and extended syntax)
455
+ types = [EQU_TYPE[i.casefold()] for i in types]
456
+
457
+ if any(i not in TRANSFER_TO_GAMS_EQUATION_SUBTYPES.keys() for i in types):
458
+ raise ValueError(
459
+ "User input unrecognized variable type, "
460
+ f"variable types can only take: {list(TRANSFER_TO_GAMS_EQUATION_SUBTYPES.keys())}"
461
+ )
462
+
463
+ return [
464
+ symobj.name
465
+ for symobj in self.getSymbols(self.listSymbols(is_valid))
466
+ if isinstance(symobj, abcs.ABCEquation) and symobj.type in types
467
+ ]
468
+
469
+ def read(
470
+ self,
471
+ load_from: Union["GamsDatabase", os.PathLike, str, "abcs.ABCContainer"],
472
+ symbols: Optional[Union[str, List[str]]] = None,
473
+ records: bool = True,
474
+ mode: Optional[str] = None,
475
+ encoding: Optional[str] = None,
476
+ ):
477
+ """
478
+ Read data into the Container from various sources.
479
+
480
+ This method reads data into the Container from different data sources, such as GDX files, GMD objects, or other Containers. It provides flexibility in reading and loading data into the Container.
481
+
482
+ Parameters
483
+ ----------
484
+ load_from : GamsDatabase | os.PathLike | str | abcs.ABCContainer
485
+ The data source to read from. It can be one of the following:
486
+ - A GamsDatabase instance to read data from a GAMS database.
487
+ - A path to a GDX file (str or os.PathLike) to read data from a GDX file.
488
+ - A GMD object (gmdHandle) to read data from a GMD object.
489
+ - Another Container instance to copy data from.
490
+
491
+ symbols : str | List[str], optional
492
+ An optional list of symbol names to read from the data source. If None (default), all symbols are read.
493
+ You can provide a single symbol name as a string or a list of symbol names as a list of strings.
494
+
495
+ records : bool, default=True
496
+ A boolean flag indicating whether to read symbol records (data values) from the data source.
497
+ - If True, symbol records are read.
498
+ - If False, symbol records are not read, only the symbol metadata is loaded.
499
+
500
+ mode : str, optional
501
+ An optional string specifying the read mode when reading data
502
+
503
+ encoding : str, optional
504
+ An optional string specifying the character encoding to use when reading data from GMD objects.
505
+ If None (default), the default system encoding is used.
506
+
507
+ Raises
508
+ ------
509
+ TypeError
510
+ - If the 'records' argument is not of type bool.
511
+ - if the 'symbols' argument is not of type str, list, or NoneType.
512
+ - if the 'mode' argument is not of type str.
513
+ - if the 'encoding' argument is not of type str or NoneType.
514
+
515
+ Exception
516
+ - If the 'load_from' argument is of an unsupported type.
517
+ - if the file specified by 'load_from' does not exist.
518
+ """
519
+ if not isinstance(records, bool):
520
+ raise TypeError("Argument 'records' must be type bool")
521
+
522
+ if not isinstance(symbols, (list, str, type(None))):
523
+ raise TypeError("Argument 'symbols' must be type str, list, or NoneType")
524
+
525
+ if isinstance(symbols, str):
526
+ symbols = [symbols]
527
+
528
+ if symbols is not None:
529
+ if any(not isinstance(i, str) for i in symbols):
530
+ raise Exception("Argument 'symbols' must contain only type str")
531
+
532
+ if mode is None:
533
+ mode = "category"
534
+
535
+ if not isinstance(mode, str):
536
+ raise TypeError("Argument 'mode' must be type str (`string` or `category`)")
537
+
538
+ if not isinstance(encoding, (str, type(None))):
539
+ raise TypeError("Argument 'encoding' must be type str or NoneType")
540
+
541
+ #
542
+ # figure out data source type
543
+ if isinstance(load_from, GamsDatabase):
544
+ source = SourceType.GMD
545
+ load_from = load_from._gmd
546
+
547
+ elif isinstance(load_from, (os.PathLike, str)):
548
+ fpath = pathlib.Path(load_from)
549
+
550
+ if not fpath.expanduser().exists():
551
+ raise Exception(
552
+ f"GDX file '{os.fspath(fpath.expanduser().resolve())}' does not exist, "
553
+ "check filename spelling or path specification"
554
+ )
555
+
556
+ if not os.fspath(fpath.expanduser().resolve()).casefold().endswith(".gdx"):
557
+ raise Exception(
558
+ "Unexpected file type passed to 'load_from' argument "
559
+ "-- expected file extension '.gdx'"
560
+ )
561
+
562
+ source = SourceType.GDX
563
+ load_from = os.fspath(fpath.expanduser().resolve())
564
+
565
+ elif isinstance(load_from, abcs.ABCContainer):
566
+ source = SourceType.CONTAINER
567
+
568
+ else:
569
+ # try GMD, if not, then mark as unknown
570
+ try:
571
+ ret = gmd.gmdInfo(load_from, gmd.GMD_NRSYMBOLSWITHALIAS)
572
+ assert ret[0] == 1
573
+ source = SourceType.GMD
574
+ except:
575
+ source = SourceType.UNKNOWN
576
+
577
+ #
578
+ # test for valid source
579
+ if source is SourceType.UNKNOWN:
580
+ raise TypeError(
581
+ "Argument 'load_from' expects "
582
+ "type str or PathLike (i.e., a path to a GDX file) "
583
+ ", a valid gmdHandle (or GamsDatabase instance) "
584
+ ", an instance of another Container "
585
+ ", User passed: "
586
+ f"'{type(load_from)}'."
587
+ )
588
+
589
+ #
590
+ # read different types
591
+ if source is SourceType.GDX:
592
+ self._gdx_read(load_from, symbols, records, mode, encoding)
593
+
594
+ elif source is SourceType.GMD:
595
+ self._gmd_read(load_from, symbols, records, mode, encoding)
596
+
597
+ elif source is SourceType.CONTAINER:
598
+ self._container_read(load_from, symbols, records)
599
+
600
+ def describeSets(
601
+ self, symbols: Optional[Union[str, List[str]]] = None
602
+ ) -> Union[pd.DataFrame, None]:
603
+ """
604
+ Generate a DataFrame describing sets within the Container.
605
+
606
+ This method creates a DataFrame that provides descriptive information about sets within the Container.
607
+ You can specify the sets to describe using the 'symbols' parameter. If 'symbols' is None (default), all sets are described.
608
+
609
+ Parameters
610
+ ----------
611
+ symbols : str | List[str], optional
612
+ An optional parameter specifying which sets to describe.
613
+
614
+ Returns
615
+ -------
616
+ DataFrame | None
617
+ A Pandas DataFrame containing descriptive information about the specified sets.
618
+ The DataFrame includes the following columns:
619
+ - 'name': The name of the set.
620
+ - 'is_singleton': Whether the set is a singleton set (True) or not (False).
621
+ - 'domain': The domain of the set.
622
+ - 'domain_type': The type of the set's domain.
623
+ - 'dimension': The dimension of the set.
624
+ - 'number_records': The number of records (size) of the set.
625
+ - 'sparsity': The sparsity of the set.
626
+
627
+ If 'symbols' includes alias sets, the DataFrame will also contain the following additional columns:
628
+ - 'is_alias': Whether the set is an alias set (True) or not (False).
629
+ - 'alias_with': The name of the set that the alias set is associated with (if it is an alias set).
630
+
631
+ The DataFrame is sorted by set name in ascending order.
632
+
633
+ Raises
634
+ ------
635
+ TypeError
636
+ If the 'symbols' argument is not of type str, list, or NoneType.
637
+ If 'symbols' contains elements that are not of type str.
638
+
639
+ Notes
640
+ -----
641
+ - This method generates a descriptive summary of sets within the Container, including their properties and characteristics.
642
+ - The 'symbols' parameter allows you to specify which sets to describe. If None (default), all sets are described.
643
+ - The resulting DataFrame provides insights into each set's attributes, such as dimensionality, size, and sparsity.
644
+ """
645
+ if not isinstance(symbols, (str, list, type(None))):
646
+ raise TypeError("Argument 'symbols' must be type str, list, or NoneType")
647
+
648
+ if symbols is None:
649
+ symbols = self.listSets()
650
+
651
+ if isinstance(symbols, str):
652
+ symbols = [symbols]
653
+
654
+ if any(not isinstance(i, str) for i in symbols):
655
+ raise TypeError("Argument 'symbols' must only contain type str")
656
+
657
+ # check for isValid
658
+ for symobj in self.getSymbols(symbols):
659
+ if not symobj.isValid():
660
+ raise Exception(
661
+ f"Cannot generate describe table because symbol `{symobj.name}` "
662
+ "is currently invalid. Use `<symbol>.isValid(verbose=True)` to debug."
663
+ )
664
+
665
+ dfs = []
666
+ cols = [
667
+ "name",
668
+ "is_singleton",
669
+ "domain",
670
+ "domain_type",
671
+ "dimension",
672
+ "number_records",
673
+ "sparsity",
674
+ ]
675
+
676
+ # find all sets and aliases
677
+ all_sets = self.listSets()
678
+ all_aliases = self.listAliases()
679
+ all_sets_aliases = all_sets + all_aliases
680
+
681
+ data = []
682
+ for i in symbols:
683
+ if i in all_sets_aliases:
684
+ data.append(
685
+ (
686
+ i,
687
+ self[i].is_singleton,
688
+ self[i].domain_names,
689
+ self[i].domain_type,
690
+ self[i].dimension,
691
+ self[i].number_records,
692
+ self[i].getSparsity(),
693
+ )
694
+ )
695
+
696
+ # create dataframe
697
+ if data != []:
698
+ df = pd.DataFrame(data, columns=cols)
699
+
700
+ if any(i in all_aliases for i in symbols):
701
+ df_is_alias = []
702
+ df_alias_with = []
703
+
704
+ for i in symbols:
705
+ if i in all_sets_aliases:
706
+ df_is_alias.append(
707
+ isinstance(self[i], (abcs.ABCAlias, abcs.ABCUniverseAlias))
708
+ )
709
+
710
+ if isinstance(self[i], abcs.ABCAlias):
711
+ df_alias_with.append(self[i].alias_with.name)
712
+ elif isinstance(self[i], abcs.ABCUniverseAlias):
713
+ df_alias_with.append(self[i].alias_with)
714
+ else:
715
+ df_alias_with.append(None)
716
+
717
+ # add in is_alias column
718
+ df.insert(2, "is_alias", pd.Series(df_is_alias, dtype=bool))
719
+ df.insert(3, "alias_with", pd.Series(df_alias_with, dtype=object))
720
+
721
+ return df.round(3).sort_values(by="name", ignore_index=True)
722
+ else:
723
+ return None
724
+
725
+ def describeAliases(
726
+ self, symbols: Optional[Union[str, List[str]]] = None
727
+ ) -> Union[pd.DataFrame, None]:
728
+ """
729
+ Generate a DataFrame describing alias symbols in the Container.
730
+
731
+ This method generates a DataFrame providing detailed information about alias symbols in the Container.
732
+
733
+ Parameters
734
+ ----------
735
+ symbols : str | List[str], optional
736
+ An optional parameter specifying the alias symbol names to describe. If None (default), Describe all alias symbols in the Container.
737
+
738
+ Returns
739
+ -------
740
+ DataFrame | None
741
+ A pandas DataFrame containing the description of alias symbols that match the specified symbol names.
742
+ If no matching alias symbols are found, None is returned.
743
+
744
+ Raises
745
+ ------
746
+ ValueError
747
+ - If the 'symbols' argument is not of type str, list, or NoneType.
748
+ - If an alias symbol name specified in 'symbols' does not exist in the Container.
749
+
750
+ Notes
751
+ -----
752
+ - This method provides a tabular summary of alias symbols, including information such as alias relationships, dimension, sparsity, etc.
753
+ - The 'symbols' parameter allows you to describe one or more alias symbols in the Container.
754
+ - If 'symbols' is None (default), the method describes all alias symbols in the Container.
755
+ - The method raises a ValueError if any alias symbol name specified in 'symbols' does not exist in the Container.
756
+ """
757
+ if not isinstance(symbols, (str, list, type(None))):
758
+ raise TypeError("Argument 'symbols' must be type str, list, or NoneType")
759
+
760
+ if symbols is None:
761
+ symbols = self.listAliases()
762
+
763
+ if isinstance(symbols, str):
764
+ symbols = [symbols]
765
+
766
+ if any(not isinstance(i, str) for i in symbols):
767
+ raise TypeError("Argument 'symbols' must only contain type str")
768
+
769
+ # check for isValid
770
+ for symobj in self.getSymbols(symbols):
771
+ if not symobj.isValid():
772
+ raise Exception(
773
+ f"Cannot generate describe table because symbol `{symobj.name}` "
774
+ "is currently invalid. Use `<symbol>.isValid(verbose=True)` to debug."
775
+ )
776
+
777
+ dfs = []
778
+ cols = [
779
+ "name",
780
+ "alias_with",
781
+ "is_singleton",
782
+ "domain",
783
+ "domain_type",
784
+ "dimension",
785
+ "number_records",
786
+ "sparsity",
787
+ ]
788
+
789
+ # find aliases
790
+ all_aliases = self.listAliases()
791
+
792
+ data = []
793
+ for i in symbols:
794
+ if i in all_aliases:
795
+ if isinstance(self[i], abcs.ABCAlias):
796
+ alias_name = self[i].alias_with.name
797
+ elif isinstance(self[i], abcs.ABCUniverseAlias):
798
+ alias_name = self[i].alias_with
799
+ else:
800
+ raise Exception("Encountered unknown symbol type")
801
+
802
+ data.append(
803
+ (
804
+ i,
805
+ alias_name,
806
+ self[i].is_singleton,
807
+ self[i].domain_names,
808
+ self[i].domain_type,
809
+ self[i].dimension,
810
+ self[i].number_records,
811
+ self[i].getSparsity(),
812
+ )
813
+ )
814
+
815
+ if data != []:
816
+ return (
817
+ pd.DataFrame(data, columns=cols)
818
+ .round(3)
819
+ .sort_values(by="name", ignore_index=True)
820
+ )
821
+ else:
822
+ return None
823
+
824
+ def describeParameters(
825
+ self, symbols: Optional[Union[str, List[str]]] = None
826
+ ) -> Union[pd.DataFrame, None]:
827
+ """
828
+ Generate a DataFrame describing parameter symbols in the Container.
829
+
830
+ This method generates a DataFrame providing detailed information about parameter symbols in the Container.
831
+
832
+ Parameters
833
+ ----------
834
+ symbols : str | List[str], optional
835
+ An optional parameter specifying the parameter symbol names to describe. If None (default), Describe all parameter symbols in the Container.
836
+
837
+ Returns
838
+ -------
839
+ DataFrame | None
840
+ A pandas DataFrame containing the description of parameter symbols that match the specified symbol names.
841
+ If no matching parameter symbols are found, None is returned.
842
+
843
+ Raises
844
+ ------
845
+ ValueError
846
+ - If the 'symbols' argument is not of type str, iterable, or NoneType.
847
+ - If a parameter symbol name specified in 'symbols' does not exist in the Container.
848
+
849
+ Notes
850
+ -----
851
+ - This method provides a tabular summary of parameter symbols, including information such as domain, dimension, sparsity, etc.
852
+ - The 'symbols' parameter allows you to describe one or more parameter symbols in the Container.
853
+ - If 'symbols' is None (default), the method describes all parameter symbols in the Container.
854
+ - The method raises a ValueError if any parameter symbol name specified in 'symbols' does not exist in the Container.
855
+ """
856
+ if not isinstance(symbols, (str, list, type(None))):
857
+ raise TypeError("Argument 'symbols' must be type str, list, or NoneType")
858
+
859
+ if symbols is None:
860
+ symbols = self.listParameters()
861
+
862
+ if isinstance(symbols, str):
863
+ symbols = [symbols]
864
+
865
+ if any(not isinstance(i, str) for i in symbols):
866
+ raise TypeError("Argument 'symbols' must only contain type str")
867
+
868
+ # check for isValid
869
+ for symobj in self.getSymbols(symbols):
870
+ if not symobj.isValid():
871
+ raise Exception(
872
+ f"Cannot generate describe table because symbol `{symobj.name}` "
873
+ "is currently invalid. Use `<symbol>.isValid(verbose=True)` to debug."
874
+ )
875
+
876
+ dfs = []
877
+ cols = [
878
+ "name",
879
+ "domain",
880
+ "domain_type",
881
+ "dimension",
882
+ "number_records",
883
+ "min",
884
+ "mean",
885
+ "max",
886
+ "where_min",
887
+ "where_max",
888
+ "sparsity",
889
+ ]
890
+
891
+ # find all parameters
892
+ all_parameters = self.listParameters()
893
+
894
+ data = []
895
+ for i in symbols:
896
+ if i in all_parameters:
897
+ data.append(
898
+ (
899
+ i,
900
+ self[i].domain_names,
901
+ self[i].domain_type,
902
+ self[i].dimension,
903
+ self[i].number_records,
904
+ self[i].getMinValue(),
905
+ self[i].getMeanValue(),
906
+ self[i].getMaxValue(),
907
+ self[i].whereMin(),
908
+ self[i].whereMax(),
909
+ self[i].getSparsity(),
910
+ )
911
+ )
912
+
913
+ if data != []:
914
+ return (
915
+ pd.DataFrame(data, columns=cols)
916
+ .round(3)
917
+ .sort_values(by="name", ignore_index=True)
918
+ )
919
+ else:
920
+ return None
921
+
922
+ def describeVariables(
923
+ self, symbols: Optional[Union[str, List[str]]] = None
924
+ ) -> Union[pd.DataFrame, None]:
925
+ """
926
+ Generate a DataFrame describing variable symbols in the Container.
927
+
928
+ This method generates a DataFrame providing detailed information about variable symbols in the Container.
929
+
930
+ Parameters
931
+ ----------
932
+ symbols : str | List[str], optional
933
+ An optional parameter specifying the variable symbol names to describe. If None (default), Describe all variable symbols in the Container.
934
+
935
+ Returns
936
+ -------
937
+ DataFrame | None
938
+ A pandas DataFrame containing the description of variable symbols that match the specified symbol names.
939
+ If no matching variable symbols are found, None is returned.
940
+
941
+ Raises
942
+ ------
943
+ ValueError
944
+ - If the 'symbols' argument is not of type str, iterable, or NoneType.
945
+ - If a variable symbol name specified in 'symbols' does not exist in the Container.
946
+
947
+ Notes
948
+ -----
949
+ - This method provides a tabular summary of variable symbols, including information such as type, domain, dimension, sparsity, etc.
950
+ - The 'symbols' parameter allows you to describe one or more variable symbols in the Container.
951
+ - If 'symbols' is None (default), the method describes all variable symbols in the Container.
952
+ - The method raises a ValueError if any variable symbol name specified in 'symbols' does not exist in the Container.
953
+ """
954
+ if not isinstance(symbols, (str, list, type(None))):
955
+ raise TypeError("Argument 'symbols' must be type str, list, or NoneType")
956
+
957
+ if symbols is None:
958
+ symbols = self.listVariables()
959
+
960
+ if isinstance(symbols, str):
961
+ symbols = [symbols]
962
+
963
+ if any(not isinstance(i, str) for i in symbols):
964
+ raise TypeError("Argument 'symbols' must only contain type str")
965
+
966
+ # check for isValid
967
+ for symobj in self.getSymbols(symbols):
968
+ if not symobj.isValid():
969
+ raise Exception(
970
+ f"Cannot generate describe table because symbol `{symobj.name}` "
971
+ "is currently invalid. Use `<symbol>.isValid(verbose=True)` to debug."
972
+ )
973
+
974
+ dfs = []
975
+ cols = [
976
+ "name",
977
+ "type",
978
+ "domain",
979
+ "domain_type",
980
+ "dimension",
981
+ "number_records",
982
+ "sparsity",
983
+ "min_level",
984
+ "mean_level",
985
+ "max_level",
986
+ "where_max_abs_level",
987
+ ]
988
+
989
+ # find all variables
990
+ all_variables = self.listVariables()
991
+
992
+ data = []
993
+ for i in symbols:
994
+ if i in all_variables:
995
+ data.append(
996
+ (
997
+ i,
998
+ self[i].type,
999
+ self[i].domain_names,
1000
+ self[i].domain_type,
1001
+ self[i].dimension,
1002
+ self[i].number_records,
1003
+ self[i].getSparsity(),
1004
+ self[i].getMinValue("level"),
1005
+ self[i].getMeanValue("level"),
1006
+ self[i].getMaxValue("level"),
1007
+ self[i].whereMaxAbs("level"),
1008
+ )
1009
+ )
1010
+ if data != []:
1011
+ return (
1012
+ pd.DataFrame(data, columns=cols)
1013
+ .round(3)
1014
+ .sort_values(by="name", ignore_index=True)
1015
+ )
1016
+ else:
1017
+ return None
1018
+
1019
+ def describeEquations(
1020
+ self, symbols: Optional[Union[str, List[str]]] = None
1021
+ ) -> Union[pd.DataFrame, None]:
1022
+ """
1023
+ Generate a DataFrame describing equation symbols in the Container.
1024
+
1025
+ This method generates a DataFrame providing detailed information about equation symbols in the Container.
1026
+
1027
+ Parameters
1028
+ ----------
1029
+ symbols : str | List[str], optional
1030
+ An optional parameter specifying the equation symbol names to describe. If None (default), Describe all equation symbols in the Container.
1031
+
1032
+ Returns
1033
+ -------
1034
+ DataFrame | None
1035
+ A pandas DataFrame containing the description of equation symbols that match the specified symbol names.
1036
+ If no matching equation symbols are found, None is returned.
1037
+
1038
+ Raises
1039
+ ------
1040
+ ValueError
1041
+ - If the 'symbols' argument is not of type str, iterable, or NoneType.
1042
+ - If an equation symbol name specified in 'symbols' does not exist in the Container.
1043
+
1044
+ Notes
1045
+ -----
1046
+ - This method provides a tabular summary of equation symbols, including information such as type, domain, dimension, sparsity, etc.
1047
+ - The 'symbols' parameter allows you to describe one or more equation symbols in the Container.
1048
+ - If 'symbols' is None (default), the method describes all equation symbols in the Container.
1049
+ - The method raises a ValueError if any equation symbol name specified in 'symbols' does not exist in the Container.
1050
+ """
1051
+ if not isinstance(symbols, (str, list, type(None))):
1052
+ raise TypeError("Argument 'symbols' must be type str, list, or NoneType")
1053
+
1054
+ if symbols is None:
1055
+ symbols = self.listEquations()
1056
+
1057
+ if isinstance(symbols, str):
1058
+ symbols = [symbols]
1059
+
1060
+ if any(not isinstance(i, str) for i in symbols):
1061
+ raise TypeError("Argument 'symbols' must only contain type str")
1062
+
1063
+ # check for isValid
1064
+ for symobj in self.getSymbols(symbols):
1065
+ if not symobj.isValid():
1066
+ raise Exception(
1067
+ f"Cannot generate describe table because symbol `{symobj.name}` "
1068
+ "is currently invalid. Use `<symbol>.isValid(verbose=True)` to debug."
1069
+ )
1070
+
1071
+ dfs = []
1072
+ cols = [
1073
+ "name",
1074
+ "type",
1075
+ "domain",
1076
+ "domain_type",
1077
+ "dimension",
1078
+ "number_records",
1079
+ "sparsity",
1080
+ "min_level",
1081
+ "mean_level",
1082
+ "max_level",
1083
+ "where_max_abs_level",
1084
+ ]
1085
+
1086
+ # find all equations
1087
+ all_equations = self.listEquations()
1088
+
1089
+ data = []
1090
+ for i in symbols:
1091
+ if i in all_equations:
1092
+ data.append(
1093
+ (
1094
+ i,
1095
+ self[i].type,
1096
+ self[i].domain_names,
1097
+ self[i].domain_type,
1098
+ self[i].dimension,
1099
+ self[i].number_records,
1100
+ self[i].getSparsity(),
1101
+ self[i].getMinValue("level"),
1102
+ self[i].getMeanValue("level"),
1103
+ self[i].getMaxValue("level"),
1104
+ self[i].whereMaxAbs("level"),
1105
+ )
1106
+ )
1107
+
1108
+ if data != []:
1109
+ return (
1110
+ pd.DataFrame(data, columns=cols)
1111
+ .round(3)
1112
+ .sort_values(by="name", ignore_index=True)
1113
+ )
1114
+ else:
1115
+ return None
1116
+
1117
+ def getSets(self, is_valid: Optional[bool] = None) -> List["abcs.ABCSet"]:
1118
+ """
1119
+ Retrieve set objects from the Container.
1120
+
1121
+ This method allows you to retrieve set objects from the Container based on their names.
1122
+
1123
+ Parameters
1124
+ ----------
1125
+ is_valid : bool, optional
1126
+ An optional boolean flag used to filter the list of sets. If None (default), all sets in the Container are returned.
1127
+ If True, only valid sets are included in the list.
1128
+ If False, only invalid sets are included in the list.
1129
+
1130
+ Returns
1131
+ -------
1132
+ List[ABCSet]
1133
+ A list of set objects that match the specified names.
1134
+ """
1135
+ return self.getSymbols(self.listSets(is_valid=is_valid))
1136
+
1137
+ def getAliases(self, is_valid: Optional[bool] = None) -> List["abcs.ABCAlias"]:
1138
+ """
1139
+ Retrieve alias objects from the Container.
1140
+
1141
+ This method allows you to retrieve alias objects from the Container based on their names.
1142
+
1143
+ Parameters
1144
+ ----------
1145
+ is_valid : bool, optional
1146
+ An optional boolean flag used to filter the list of aliases. If None (default), all aliases in the Container are returned.
1147
+ If True, only valid aliases are included in the list.
1148
+ If False, only invalid aliases are included in the list.
1149
+
1150
+ Returns
1151
+ -------
1152
+ List[ABCAlias]
1153
+ A list of alias objects that match the specified names.
1154
+ """
1155
+ return self.getSymbols(self.listAliases(is_valid=is_valid))
1156
+
1157
+ def getParameters(
1158
+ self, is_valid: Optional[bool] = None
1159
+ ) -> List["abcs.ABCParameter"]:
1160
+ """
1161
+ Retrieve parameter objects from the Container.
1162
+
1163
+ This method allows you to retrieve parameter objects from the Container based on their names.
1164
+
1165
+ Parameters
1166
+ ----------
1167
+ is_valid : bool, optional
1168
+ An optional boolean flag used to filter the list of parameters. If None (default), all parameters in the Container are returned.
1169
+ If True, only valid parameters are included in the list.
1170
+ If False, only invalid parameters are included in the list.
1171
+
1172
+ Returns
1173
+ -------
1174
+ List[ABCAlias]
1175
+ A list of parameter objects that match the specified names.
1176
+ """
1177
+ return self.getSymbols(self.listParameters(is_valid=is_valid))
1178
+
1179
+ def getVariables(
1180
+ self,
1181
+ is_valid: Optional[bool] = None,
1182
+ types: Optional[Union[str, List[str]]] = None,
1183
+ ) -> List["abcs.ABCVariable"]:
1184
+ """
1185
+ Retrieve variable objects from the Container.
1186
+
1187
+ This method allows you to retrieve variable objects from the Container based on their names.
1188
+
1189
+ Parameters
1190
+ ----------
1191
+ is_valid : bool, optional
1192
+ An optional boolean flag used to filter the list of variables. If None (default), all variables in the Container are returned.
1193
+ If True, only valid variables are included in the list.
1194
+ If False, only invalid variables are included in the list.
1195
+ types : str | List[str], optional
1196
+ An optional string or list of strings specifying the types of variables to include in the list.
1197
+ If None (default), all variable types are included in the list.
1198
+ If a string or list of strings is provided, only variables of the specified types are included in the list.
1199
+
1200
+ Returns
1201
+ -------
1202
+ List[ABCVariable]
1203
+ A list of variable objects that match the specified names.
1204
+ """
1205
+ return self.getSymbols(self.listVariables(is_valid=is_valid, types=types))
1206
+
1207
+ def getEquations(
1208
+ self,
1209
+ is_valid: Optional[bool] = None,
1210
+ types: Optional[Union[str, List[str]]] = None,
1211
+ ) -> List["abcs.ABCEquation"]:
1212
+ """
1213
+ Retrieve equation objects from the Container.
1214
+
1215
+ This method allows you to retrieve equation objects from the Container based on their names.
1216
+
1217
+ Parameters
1218
+ ----------
1219
+ is_valid : bool, optional
1220
+ An optional boolean flag used to filter the list of equations. If None (default), all equations in the Container are returned.
1221
+ If True, only valid equations are included in the list.
1222
+ If False, only invalid equations are included in the list.
1223
+ types : str | List[str], optional
1224
+ An optional string or list of strings specifying the types of equations to include in the list.
1225
+ If None (default), all equation types are included in the list.
1226
+ If a string or list of strings is provided, only equations of the specified types are included in the list.
1227
+
1228
+ Returns
1229
+ -------
1230
+ List[ABCEquation]
1231
+ A list of equation objects that match the specified names.
1232
+ """
1233
+ return self.getSymbols(self.listEquations(is_valid=is_valid, types=types))
1234
+
1235
+ def getSymbols(
1236
+ self, symbols: Optional[Union[str, Sequence[str]]] = None
1237
+ ) -> List["abcs.AnyContainerSymbol"]:
1238
+ """
1239
+ Retrieve symbol objects from the Container.
1240
+
1241
+ This method allows you to retrieve symbol objects from the Container based on their names.
1242
+
1243
+ Parameters
1244
+ ----------
1245
+ symbols : str | Sequence[str], optional
1246
+ An optional parameter specifying the symbol names to retrieve. If None (default), Retrieve all symbols stored in the Container.
1247
+
1248
+ Returns
1249
+ -------
1250
+ List[AnyContainerSymbol]
1251
+ A list of symbol objects that match the specified symbol names.
1252
+
1253
+ Raises
1254
+ ------
1255
+ ValueError
1256
+ - If the 'symbols' argument is not of type str, iterable, or NoneType.
1257
+ - If a symbol name specified in 'symbols' does not exist in the Container.
1258
+ """
1259
+ if symbols is None:
1260
+ return list(self.data.values())
1261
+
1262
+ if isinstance(symbols, str):
1263
+ symbols = [symbols]
1264
+
1265
+ if not isinstance(symbols, Iterable):
1266
+ raise ValueError("Argument 'symbols' must be type str or other iterable")
1267
+
1268
+ obj = []
1269
+ for symname in symbols:
1270
+ try:
1271
+ obj.append(self[symname])
1272
+ except KeyError as err:
1273
+ raise KeyError(f"Symbol `{symname}` does not appear in the Container")
1274
+ return obj