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,444 @@
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
+ from gams.tools.toolcollection.tooltemplate import ToolTemplate
27
+ import os
28
+
29
+
30
+ class Csvread(ToolTemplate):
31
+
32
+ def __init__(self, system_directory, tool):
33
+ super().__init__(system_directory, tool)
34
+ self.title = "csvread: This tool writes data from a CSV file into a GAMS symbol."
35
+ self.add_posargdef("filename", "fnExist", "Specify a CSV file path.")
36
+ self.add_namedargdef(
37
+ "id=<string>",
38
+ "str",
39
+ "Specify a symbol name for the Connect database.",
40
+ )
41
+ self.add_namedargdef(
42
+ "useHeader=<boolean>",
43
+ "str",
44
+ "Specify the header used as the column names.",
45
+ argdefault="N",
46
+ )
47
+ self.add_namedargdef(
48
+ "autoCol=<string>",
49
+ "str",
50
+ "Generate automatic column names.",
51
+ argdefault=None,
52
+ )
53
+ self.add_namedargdef(
54
+ "autoRow=<string>", "str", "Generate automatic row labels.", argdefault=None
55
+ )
56
+ self.add_namedargdef(
57
+ "index=<string>",
58
+ "str",
59
+ "Specify columns to use as the row labels.",
60
+ argdefault=None,
61
+ )
62
+ self.add_namedargdef(
63
+ "values=<string>",
64
+ "str",
65
+ "Specify columns to get the values from.",
66
+ argdefault=None,
67
+ )
68
+ self.add_namedargdef(
69
+ "text=<string>",
70
+ "str",
71
+ "Specify columns to get the set element text from.",
72
+ argdefault=None,
73
+ )
74
+ self.add_namedargdef(
75
+ "quoting=<int>", "int", "Control field quoting behavior.", argdefault=0
76
+ )
77
+ self.add_namedargdef(
78
+ "fieldSep=<string>", "str", "Specify a field separator.", argdefault="comma"
79
+ )
80
+ self.add_namedargdef(
81
+ "decimalSep=<string>",
82
+ "str",
83
+ "Specify a decimal separator. ",
84
+ argdefault="period",
85
+ )
86
+ self.add_namedargdef(
87
+ "thousandsSep=<string>",
88
+ "str",
89
+ "Specify a thousands separator.",
90
+ argdefault=None,
91
+ )
92
+ self.add_namedargdef(
93
+ "gdxOut=<filename>",
94
+ "fnWriteable",
95
+ "Specify the name for the GDX file.",
96
+ argdefault=None,
97
+ shell_req=True,
98
+ )
99
+ self.add_namedargdef(
100
+ "checkDate=<boolean>",
101
+ "str",
102
+ "Write GDX file only if the CSV file is more recent than the GDX file.",
103
+ argdefault="N",
104
+ )
105
+ self.add_namedargdef(
106
+ "valueDim=<boolean>",
107
+ "str",
108
+ "Stacks the column names to index.",
109
+ argdefault="N",
110
+ ) # this is the stack option in CSVReader
111
+ self.add_namedargdef(
112
+ "argsFile=<filename>",
113
+ "fnExist",
114
+ "Specify the arguments file path.",
115
+ argdefault=None,
116
+ )
117
+ self.add_namedargdef(
118
+ "acceptBadUels=<boolean>",
119
+ "str",
120
+ "Indicate if bad UELs are accepted or result in an error return code.",
121
+ argdefault="N",
122
+ )
123
+ self.add_namedargdef(
124
+ "dimIds=<list>",
125
+ "str",
126
+ "Indicate which dimensions are written",
127
+ )
128
+
129
+ self._csvreader_params, self._other_params = {}, {}
130
+ self._params_mapper = {
131
+ "id": "name",
132
+ "trace": "trace",
133
+ "useheader": "header",
134
+ "autocol": "autoColumn",
135
+ "autorow": "autoRow",
136
+ "index": "indexColumns",
137
+ "values": "valueColumns",
138
+ "text": "textColumns", # textColumns has been removed. Instead use `valueColumns` and `type=set`. We update this later.
139
+ "quoting": "quoting",
140
+ "fieldsep": "fieldSeparator",
141
+ "decimalsep": "decimalSeparator",
142
+ "thousandssep": "thousandsSeparator",
143
+ "valuedim": "stack",
144
+ }
145
+
146
+ @staticmethod
147
+ def check_duplicate_in_named_args(tuple_list):
148
+ seen_elements = set()
149
+ duplicates = set()
150
+
151
+ for tup in tuple_list:
152
+ if tup[0] in seen_elements:
153
+ duplicates.add(tup[0])
154
+ else:
155
+ seen_elements.add(tup[0])
156
+
157
+ return ", ".join(duplicates)
158
+
159
+ def read_params_file(self):
160
+ """
161
+ Helper function to read a parameter file. Lines starting with * are ignored.
162
+ """
163
+ csvreader_params = {}
164
+ other_params = {}
165
+ with open(self.namedargs_val("argsFile"), "r") as file:
166
+ for line in file:
167
+ line = line.strip()
168
+ if line.startswith("*") or "=" not in line:
169
+ continue
170
+ key, value = map(str.strip, line.split("=", 1))
171
+ value = self.check_bool_args(key, value)
172
+ if key.lower() in self._params_mapper:
173
+ csvreader_params[self._params_mapper[key.lower()]] = value
174
+ else:
175
+ other_params[key.lower()] = value
176
+ self._csvreader_params.update(csvreader_params)
177
+ self._other_params.update(other_params)
178
+
179
+ def check_date(self, in_file, out_file, trace):
180
+ """
181
+ Helper function to check if CSV is older than GDX, which in turn would not create a new GDX.
182
+
183
+ Ignore the Exception if checkDate is set to True and gdx is not yet created.
184
+ """
185
+ try:
186
+ if os.path.getmtime(in_file) < os.path.getmtime(out_file) and trace > 0:
187
+ self._tools.print_log(
188
+ f"No new file written, >checkDate< is set to True."
189
+ )
190
+ exit(0)
191
+ except (
192
+ FileNotFoundError
193
+ ): # if checkDate is set to 'Y' and gdx file does not exist
194
+ pass
195
+
196
+ def check_bool_args(self, key, value):
197
+ """
198
+ Helper function to convert the argVal of a boolean type argument to Boolean True/False.
199
+ Returns the specified value in case the option is not a boolean type argument.
200
+
201
+ Raise Exception if the input is not y/n or Y/N.
202
+ """
203
+ if key.lower() in [
204
+ "checkdate",
205
+ "acceptbaduels",
206
+ "valuedim",
207
+ "useheader",
208
+ ]:
209
+ if value.lower() in ["y", "yes"]:
210
+ return True
211
+ elif value.lower() in ["n", "no"]:
212
+ return False
213
+ self.tool_error(f"Wrong flag, {key}: {value}", print_help=False)
214
+ return value
215
+
216
+ def generate_csv_params(self):
217
+ """
218
+ Helper function to add arguments in the CSVReader agent only if the options were specified.
219
+ """
220
+ csv_params_dict = {}
221
+ other_params = {}
222
+
223
+ if self.namedargs_val("argsFile") is not None:
224
+ self.read_params_file()
225
+
226
+ for ele in self.namedargs:
227
+ val = self.check_bool_args(ele, self.namedargs_val(ele))
228
+ if ele in self._params_mapper:
229
+ csv_params_dict[self._params_mapper[ele]] = val
230
+ else:
231
+ other_params[ele] = val
232
+ self._csvreader_params.update(csv_params_dict)
233
+ self._other_params.update(other_params)
234
+
235
+ def check_bad_uels(self, df):
236
+ """
237
+ Helper function to check if there are bad UELs present in any of the index columns.
238
+
239
+ returns:
240
+ bad_cols: List of columns containing bad UELs
241
+ """
242
+ columns = df.columns[:-1]
243
+ bad_cols = []
244
+ for col in columns:
245
+ lengths = df[col].apply(len).tolist()
246
+ if any(len >= 64 for len in lengths):
247
+ bad_cols.append(col)
248
+ return bad_cols
249
+
250
+ @staticmethod
251
+ def accept_bad_uels(df):
252
+ """
253
+ Helper function to utilize the `acceptBadUels` option as in CSV2GDX.
254
+
255
+ Converts every bad UEL, i.e., element longer than 63 to a defined label.
256
+ """
257
+ cols = df.columns[:-1]
258
+ for i, col in enumerate(cols):
259
+ df[col] = df[col].apply(
260
+ lambda x: (
261
+ f"Bad_Line_{df[df[col] == x].index[0]+1}_Dim_{i+1}"
262
+ if len(x) >= 64
263
+ else x
264
+ )
265
+ )
266
+
267
+ return df
268
+
269
+ def replace_dots_with_colons(self):
270
+ if (
271
+ "valueColumns" in self._csvreader_params
272
+ and ".." in self._csvreader_params["valueColumns"]
273
+ ):
274
+ self._csvreader_params["valueColumns"] = self._csvreader_params[
275
+ "valueColumns"
276
+ ].replace("..", ":")
277
+
278
+ if (
279
+ "indexColumns" in self._csvreader_params
280
+ and ".." in self._csvreader_params["indexColumns"]
281
+ ):
282
+ self._csvreader_params["indexColumns"] = self._csvreader_params[
283
+ "indexColumns"
284
+ ].replace("..", ":")
285
+
286
+ def set_default_sep_values(self, flag):
287
+ separators = {
288
+ "fieldSeparator": {"comma": ",", "semicolon": ";", "tab": "\t"},
289
+ "decimalSeparator": {"period": ".", "comma": ","},
290
+ }
291
+ default_sep = {"fieldSeparator": ",", "decimalSeparator": "."}
292
+
293
+ if flag in self._csvreader_params:
294
+ if separators[flag].get(self._csvreader_params[flag].lower()) is not None:
295
+ self._csvreader_params[flag] = separators[flag].get(
296
+ self._csvreader_params[flag].lower()
297
+ )
298
+ else:
299
+ self.tool_error(
300
+ f"Wrong {flag} input: {self._csvreader_params[flag]}",
301
+ print_help=False,
302
+ )
303
+ else:
304
+ self._csvreader_params[flag] = default_sep[flag]
305
+
306
+ @staticmethod
307
+ def map_special_values():
308
+ """
309
+ This function preserves the old mapping of special values in CSV2GDX.
310
+ """
311
+ from gams.transfer import SpecialValues as sv
312
+ from itertools import product
313
+
314
+ mapper = {
315
+ "": sv.NA,
316
+ "yes": 1.0,
317
+ "true": 1.0,
318
+ "no": 0.0,
319
+ "false": 0.0,
320
+ "none": 0.0,
321
+ "null": 0.0,
322
+ "eps": sv.EPS,
323
+ "n/a": sv.NA,
324
+ "inf": sv.POSINF,
325
+ "+inf": sv.POSINF,
326
+ "-inf": sv.NEGINF,
327
+ }
328
+ exhaustive_mapper = {}
329
+ for key, value in mapper.items():
330
+ case_permutations = map(
331
+ "".join, product(*((char.upper(), char.lower()) for char in key))
332
+ )
333
+ for perm in case_permutations:
334
+ exhaustive_mapper[perm] = value
335
+ return exhaustive_mapper
336
+
337
+ def create_dim_sets(self, m, sym_name, dim_list):
338
+ """
339
+ Method to add new Set symbols in the container.
340
+ """
341
+ for dim_name, dim_idx in zip(dim_list, range(m[sym_name].dimension)):
342
+ m.addSet(
343
+ name=dim_name, records=m[sym_name].getUELs(dim_idx, ignore_unused=True)
344
+ )
345
+
346
+ def execute(self):
347
+ if self.dohelp():
348
+ return
349
+
350
+ self.process_args()
351
+
352
+ check_dupe_opts = self.check_duplicate_in_named_args(self.namedargs_list)
353
+ if check_dupe_opts:
354
+ self.tool_error(f"Duplicate option: {check_dupe_opts}", print_help=False)
355
+
356
+ filename = self.posargs[0]
357
+
358
+ self.generate_csv_params()
359
+
360
+ try:
361
+ sym_name = self._csvreader_params["name"]
362
+ except KeyError:
363
+ self.tool_error("parameter >id< not set.")
364
+
365
+ trace = self._csvreader_params.get("trace", self.namedargs_val("trace"))
366
+ sym_type = "par"
367
+
368
+ if {"textColumns", "valueColumns"}.issubset(self._csvreader_params):
369
+ self.tool_error(
370
+ "Cannot set both text and values options at the same time.",
371
+ print_help=False,
372
+ )
373
+
374
+ if (
375
+ "textColumns" in self._csvreader_params
376
+ or "indexColumns" in self._csvreader_params
377
+ ) and ("valueColumns" not in self._csvreader_params):
378
+ sym_type = "set"
379
+ if "textColumns" in self._csvreader_params:
380
+ self._csvreader_params["valueColumns"] = self._csvreader_params.pop(
381
+ "textColumns"
382
+ )
383
+
384
+ if (
385
+ "valueColumns" not in self._csvreader_params
386
+ and "stack" in self._csvreader_params
387
+ ): # CSV2GDX ignores valuedim if values are not present
388
+ self._csvreader_params["stack"] = False
389
+
390
+ if self._other_params.get("checkdate", None):
391
+ self.check_date(
392
+ in_file=filename, out_file=self.namedargs["gdxout"], trace=trace
393
+ )
394
+
395
+ self.replace_dots_with_colons()
396
+ self.set_default_sep_values(flag="fieldSeparator")
397
+ self.set_default_sep_values(flag="decimalSeparator")
398
+
399
+ from gams.connect import ConnectDatabase
400
+
401
+ cdb = ConnectDatabase(self._tools._system_directory, ecdb=self._tools._ecdb)
402
+ m = cdb.container
403
+
404
+ csv_params = {
405
+ "file": filename,
406
+ "name": sym_name,
407
+ "trace": trace,
408
+ "header": self._csvreader_params.get("header", False),
409
+ "type": sym_type,
410
+ "valueSubstitutions": self.map_special_values(),
411
+ "readCSVArguments": {"skipinitialspace": True, "keep_default_na": False},
412
+ }
413
+
414
+ self._csvreader_params.update(csv_params)
415
+ try:
416
+ cdb.execute({"CSVReader": self._csvreader_params})
417
+ except Exception as e:
418
+ self.tool_error(f"{e.__class__.__name__} : {e}", print_help=False)
419
+
420
+ bad_uels = self.check_bad_uels(df=m[sym_name].records)
421
+ if bad_uels:
422
+ if self._other_params.get("acceptbaduels", None):
423
+ self.accept_bad_uels(df=m[sym_name].records)
424
+ self._tools.print_log(f"Bad Uels in col {bad_uels} were changed.")
425
+ else:
426
+ self.tool_error(
427
+ f"BadUels in col {bad_uels}, toggle option >acceptBadUels<."
428
+ )
429
+
430
+ dim_list = []
431
+ if self._other_params.get("dimids", None):
432
+ dim_list = list(self._other_params["dimids"].split(","))
433
+ if len(dim_list) > m[sym_name].dimension:
434
+ self.tool_error(
435
+ f"Specified more dimensions >{len(dim_list)}< than available >{m[sym_name].dimension}<",
436
+ print_help=False,
437
+ )
438
+ elif "gdxout" in self.namedargs:
439
+ dim_list = [f"Dim{i+1}" for i in range(m[sym_name].dimension)]
440
+
441
+ if dim_list:
442
+ self.create_dim_sets(m=m, sym_name=sym_name, dim_list=dim_list)
443
+
444
+ self.write_id_outputs(m, outputs=[sym_name] + dim_list)