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.
- gams/__init__.py +27 -0
- gams/_version.py +1 -0
- gams/connect/__init__.py +28 -0
- gams/connect/agents/__init__.py +24 -0
- gams/connect/agents/_excel/__init__.py +32 -0
- gams/connect/agents/_excel/excelagent.py +312 -0
- gams/connect/agents/_excel/workbook.py +155 -0
- gams/connect/agents/_sqlconnectors/__init__.py +42 -0
- gams/connect/agents/_sqlconnectors/_accesshandler.py +211 -0
- gams/connect/agents/_sqlconnectors/_databasehandler.py +250 -0
- gams/connect/agents/_sqlconnectors/_mysqlhandler.py +168 -0
- gams/connect/agents/_sqlconnectors/_postgreshandler.py +131 -0
- gams/connect/agents/_sqlconnectors/_pyodbchandler.py +112 -0
- gams/connect/agents/_sqlconnectors/_sqlalchemyhandler.py +74 -0
- gams/connect/agents/_sqlconnectors/_sqlitehandler.py +262 -0
- gams/connect/agents/_sqlconnectors/_sqlserverhandler.py +179 -0
- gams/connect/agents/concatenate.py +440 -0
- gams/connect/agents/connectagent.py +743 -0
- gams/connect/agents/csvreader.py +675 -0
- gams/connect/agents/csvwriter.py +151 -0
- gams/connect/agents/domainwriter.py +143 -0
- gams/connect/agents/excelreader.py +756 -0
- gams/connect/agents/excelwriter.py +467 -0
- gams/connect/agents/filter.py +223 -0
- gams/connect/agents/gamsreader.py +112 -0
- gams/connect/agents/gamswriter.py +239 -0
- gams/connect/agents/gdxreader.py +109 -0
- gams/connect/agents/gdxwriter.py +146 -0
- gams/connect/agents/labelmanipulator.py +303 -0
- gams/connect/agents/projection.py +539 -0
- gams/connect/agents/pythoncode.py +71 -0
- gams/connect/agents/rawcsvreader.py +248 -0
- gams/connect/agents/rawexcelreader.py +312 -0
- gams/connect/agents/schema/CSVReader.yaml +92 -0
- gams/connect/agents/schema/CSVWriter.yaml +44 -0
- gams/connect/agents/schema/Concatenate.yaml +52 -0
- gams/connect/agents/schema/DomainWriter.yaml +25 -0
- gams/connect/agents/schema/ExcelReader.yaml +121 -0
- gams/connect/agents/schema/ExcelWriter.yaml +78 -0
- gams/connect/agents/schema/Filter.yaml +74 -0
- gams/connect/agents/schema/GAMSReader.yaml +20 -0
- gams/connect/agents/schema/GAMSWriter.yaml +47 -0
- gams/connect/agents/schema/GDXReader.yaml +23 -0
- gams/connect/agents/schema/GDXWriter.yaml +32 -0
- gams/connect/agents/schema/LabelManipulator.yaml +99 -0
- gams/connect/agents/schema/Projection.yaml +24 -0
- gams/connect/agents/schema/PythonCode.yaml +6 -0
- gams/connect/agents/schema/RawCSVReader.yaml +34 -0
- gams/connect/agents/schema/RawExcelReader.yaml +42 -0
- gams/connect/agents/schema/SQLReader.yaml +75 -0
- gams/connect/agents/schema/SQLWriter.yaml +103 -0
- gams/connect/agents/sqlreader.py +301 -0
- gams/connect/agents/sqlwriter.py +276 -0
- gams/connect/connectdatabase.py +275 -0
- gams/connect/connectvalidator.py +93 -0
- gams/connect/errors.py +34 -0
- gams/control/__init__.py +136 -0
- gams/control/database.py +2231 -0
- gams/control/execution.py +1900 -0
- gams/control/options.py +2792 -0
- gams/control/workspace.py +1198 -0
- gams/core/__init__.py +24 -0
- gams/core/cfg/__init__.py +26 -0
- gams/core/cfg/_cfgmcc.cp312-win_amd64.pyd +0 -0
- gams/core/cfg/cfgmcc.py +519 -0
- gams/core/dct/__init__.py +26 -0
- gams/core/dct/_dctmcc.cp312-win_amd64.pyd +0 -0
- gams/core/dct/dctmcc.py +574 -0
- gams/core/embedded/__init__.py +26 -0
- gams/core/embedded/gamsemb.py +1024 -0
- gams/core/emp/__init__.py +24 -0
- gams/core/emp/emplexer.py +89 -0
- gams/core/emp/empyacc.py +281 -0
- gams/core/gdx/__init__.py +26 -0
- gams/core/gdx/_gdxcc.cp312-win_amd64.pyd +0 -0
- gams/core/gdx/gdxcc.py +866 -0
- gams/core/gev/__init__.py +26 -0
- gams/core/gev/_gevmcc.cp312-win_amd64.pyd +0 -0
- gams/core/gev/gevmcc.py +855 -0
- gams/core/gmd/__init__.py +26 -0
- gams/core/gmd/_gmdcc.cp312-win_amd64.pyd +0 -0
- gams/core/gmd/gmdcc.py +917 -0
- gams/core/gmo/__init__.py +26 -0
- gams/core/gmo/_gmomcc.cp312-win_amd64.pyd +0 -0
- gams/core/gmo/gmomcc.py +2046 -0
- gams/core/idx/__init__.py +26 -0
- gams/core/idx/_idxcc.cp312-win_amd64.pyd +0 -0
- gams/core/idx/idxcc.py +510 -0
- gams/core/numpy/__init__.py +29 -0
- gams/core/numpy/_gams2numpy.cp312-win_amd64.pyd +0 -0
- gams/core/numpy/gams2numpy.py +1048 -0
- gams/core/opt/__init__.py +26 -0
- gams/core/opt/_optcc.cp312-win_amd64.pyd +0 -0
- gams/core/opt/optcc.py +840 -0
- gams/engine/__init__.py +204 -0
- gams/engine/api/__init__.py +13 -0
- gams/engine/api/auth_api.py +7653 -0
- gams/engine/api/cleanup_api.py +751 -0
- gams/engine/api/default_api.py +887 -0
- gams/engine/api/hypercube_api.py +2629 -0
- gams/engine/api/jobs_api.py +5229 -0
- gams/engine/api/licenses_api.py +2220 -0
- gams/engine/api/namespaces_api.py +7783 -0
- gams/engine/api/usage_api.py +5627 -0
- gams/engine/api/users_api.py +5931 -0
- gams/engine/api_client.py +804 -0
- gams/engine/api_response.py +21 -0
- gams/engine/configuration.py +601 -0
- gams/engine/exceptions.py +216 -0
- gams/engine/models/__init__.py +86 -0
- gams/engine/models/bad_input.py +89 -0
- gams/engine/models/cleanable_job_result.py +104 -0
- gams/engine/models/cleanable_job_result_page.py +113 -0
- gams/engine/models/engine_license.py +107 -0
- gams/engine/models/files_not_found.py +93 -0
- gams/engine/models/forwarded_token_response.py +112 -0
- gams/engine/models/generic_key_value_pair.py +89 -0
- gams/engine/models/hypercube.py +160 -0
- gams/engine/models/hypercube_page.py +111 -0
- gams/engine/models/hypercube_summary.py +91 -0
- gams/engine/models/hypercube_token.py +97 -0
- gams/engine/models/identity_provider.py +107 -0
- gams/engine/models/identity_provider_ldap.py +121 -0
- gams/engine/models/identity_provider_oauth2.py +146 -0
- gams/engine/models/identity_provider_oauth2_scope.py +89 -0
- gams/engine/models/identity_provider_oauth2_with_secret.py +152 -0
- gams/engine/models/identity_provider_oidc.py +133 -0
- gams/engine/models/identity_provider_oidc_with_secret.py +143 -0
- gams/engine/models/inex.py +91 -0
- gams/engine/models/invitation.py +136 -0
- gams/engine/models/invitation_quota.py +106 -0
- gams/engine/models/invitation_token.py +87 -0
- gams/engine/models/job.py +165 -0
- gams/engine/models/job_no_text_entry.py +138 -0
- gams/engine/models/job_no_text_entry_page.py +111 -0
- gams/engine/models/license.py +91 -0
- gams/engine/models/log_piece.py +96 -0
- gams/engine/models/message.py +87 -0
- gams/engine/models/message_and_token.py +99 -0
- gams/engine/models/message_with_webhook_id.py +89 -0
- gams/engine/models/model_auth_token.py +87 -0
- gams/engine/models/model_configuration.py +125 -0
- gams/engine/models/model_default_instance.py +99 -0
- gams/engine/models/model_default_user_instance.py +98 -0
- gams/engine/models/model_hypercube_job.py +106 -0
- gams/engine/models/model_hypercube_usage.py +130 -0
- gams/engine/models/model_instance_info.py +116 -0
- gams/engine/models/model_instance_info_full.py +123 -0
- gams/engine/models/model_instance_pool_info.py +112 -0
- gams/engine/models/model_job_labels.py +179 -0
- gams/engine/models/model_job_usage.py +133 -0
- gams/engine/models/model_pool_usage.py +124 -0
- gams/engine/models/model_usage.py +115 -0
- gams/engine/models/model_user.py +96 -0
- gams/engine/models/model_userinstance_info.py +119 -0
- gams/engine/models/model_userinstancepool_info.py +95 -0
- gams/engine/models/model_version.py +91 -0
- gams/engine/models/models.py +120 -0
- gams/engine/models/namespace.py +104 -0
- gams/engine/models/namespace_quota.py +96 -0
- gams/engine/models/namespace_with_permission.py +96 -0
- gams/engine/models/not_found.py +91 -0
- gams/engine/models/password_policy.py +97 -0
- gams/engine/models/perm_and_username.py +89 -0
- gams/engine/models/quota.py +117 -0
- gams/engine/models/quota_exceeded.py +97 -0
- gams/engine/models/status_code_meaning.py +89 -0
- gams/engine/models/stream_entry.py +89 -0
- gams/engine/models/system_wide_license.py +92 -0
- gams/engine/models/text_entries.py +87 -0
- gams/engine/models/text_entry.py +101 -0
- gams/engine/models/time_span.py +95 -0
- gams/engine/models/time_span_pool_worker.py +99 -0
- gams/engine/models/token_forward_error.py +87 -0
- gams/engine/models/user.py +127 -0
- gams/engine/models/user_group_member.py +96 -0
- gams/engine/models/user_groups.py +108 -0
- gams/engine/models/vapid_info.py +87 -0
- gams/engine/models/webhook.py +138 -0
- gams/engine/models/webhook_parameterized_event.py +99 -0
- gams/engine/py.typed +0 -0
- gams/engine/rest.py +258 -0
- gams/magic/__init__.py +32 -0
- gams/magic/gams_magic.py +142 -0
- gams/magic/interactive.py +402 -0
- gams/tools/__init__.py +30 -0
- gams/tools/errors.py +34 -0
- gams/tools/toolcollection/__init__.py +24 -0
- gams/tools/toolcollection/alg/__init__.py +24 -0
- gams/tools/toolcollection/alg/rank.py +51 -0
- gams/tools/toolcollection/data/__init__.py +24 -0
- gams/tools/toolcollection/data/csvread.py +444 -0
- gams/tools/toolcollection/data/csvwrite.py +311 -0
- gams/tools/toolcollection/data/exceldump.py +47 -0
- gams/tools/toolcollection/data/sqlitewrite.py +276 -0
- gams/tools/toolcollection/gdxservice/__init__.py +24 -0
- gams/tools/toolcollection/gdxservice/gdxencoding.py +104 -0
- gams/tools/toolcollection/gdxservice/gdxrename.py +94 -0
- gams/tools/toolcollection/linalg/__init__.py +24 -0
- gams/tools/toolcollection/linalg/cholesky.py +57 -0
- gams/tools/toolcollection/linalg/eigenvalue.py +56 -0
- gams/tools/toolcollection/linalg/eigenvector.py +58 -0
- gams/tools/toolcollection/linalg/invert.py +55 -0
- gams/tools/toolcollection/linalg/ols.py +138 -0
- gams/tools/toolcollection/tooltemplate.py +321 -0
- gams/tools/toolcollection/win32/__init__.py +24 -0
- gams/tools/toolcollection/win32/excelmerge.py +93 -0
- gams/tools/toolcollection/win32/exceltalk.py +76 -0
- gams/tools/toolcollection/win32/msappavail.py +49 -0
- gams/tools/toolcollection/win32/shellexecute.py +54 -0
- gams/tools/tools.py +116 -0
- gams/transfer/__init__.py +35 -0
- gams/transfer/_abcs/__init__.py +37 -0
- gams/transfer/_abcs/container_abcs.py +433 -0
- gams/transfer/_internals/__init__.py +63 -0
- gams/transfer/_internals/algorithms.py +436 -0
- gams/transfer/_internals/casepreservingdict.py +124 -0
- gams/transfer/_internals/constants.py +270 -0
- gams/transfer/_internals/domainviolation.py +103 -0
- gams/transfer/_internals/specialvalues.py +172 -0
- gams/transfer/containers/__init__.py +26 -0
- gams/transfer/containers/_container.py +1794 -0
- gams/transfer/containers/_io/__init__.py +28 -0
- gams/transfer/containers/_io/containers.py +164 -0
- gams/transfer/containers/_io/gdx.py +1029 -0
- gams/transfer/containers/_io/gmd.py +872 -0
- gams/transfer/containers/_mixins/__init__.py +26 -0
- gams/transfer/containers/_mixins/ccc.py +1274 -0
- gams/transfer/syms/__init__.py +33 -0
- gams/transfer/syms/_methods/__init__.py +24 -0
- gams/transfer/syms/_methods/tables.py +120 -0
- gams/transfer/syms/_methods/toDict.py +115 -0
- gams/transfer/syms/_methods/toList.py +83 -0
- gams/transfer/syms/_methods/toValue.py +60 -0
- gams/transfer/syms/_mixins/__init__.py +32 -0
- gams/transfer/syms/_mixins/equals.py +626 -0
- gams/transfer/syms/_mixins/generateRecords.py +499 -0
- gams/transfer/syms/_mixins/pivot.py +313 -0
- gams/transfer/syms/_mixins/pve.py +627 -0
- gams/transfer/syms/_mixins/sa.py +27 -0
- gams/transfer/syms/_mixins/sapve.py +27 -0
- gams/transfer/syms/_mixins/saua.py +27 -0
- gams/transfer/syms/_mixins/sauapve.py +199 -0
- gams/transfer/syms/_mixins/spve.py +1528 -0
- gams/transfer/syms/_mixins/ve.py +936 -0
- gams/transfer/syms/container_syms/__init__.py +31 -0
- gams/transfer/syms/container_syms/_alias.py +984 -0
- gams/transfer/syms/container_syms/_equation.py +333 -0
- gams/transfer/syms/container_syms/_parameter.py +973 -0
- gams/transfer/syms/container_syms/_set.py +604 -0
- gams/transfer/syms/container_syms/_universe_alias.py +461 -0
- gams/transfer/syms/container_syms/_variable.py +321 -0
- gamsapi-52.5.0.dist-info/METADATA +150 -0
- gamsapi-52.5.0.dist-info/RECORD +257 -0
- gamsapi-52.5.0.dist-info/WHEEL +5 -0
- gamsapi-52.5.0.dist-info/licenses/LICENSE +22 -0
- 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)
|