Skip to content

Commit

Permalink
finish ampl error handling
Browse files Browse the repository at this point in the history
  • Loading branch information
jurgen-lentz committed Oct 30, 2024
1 parent b175f55 commit f77f3c8
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 20 deletions.
68 changes: 56 additions & 12 deletions amplpy/ampl.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -455,13 +455,20 @@ cdef class AMPL:
Returns:
Current working directory.
"""
cdef campl.AMPL_ERRORINFO* errorinfo
cdef campl.AMPL_RETCODE rc
cdef char* workdir_c
if path is None:
PY_AMPL_CALL(campl.AMPL_Cd(self._c_ampl, &workdir_c))
errorinfo = campl.AMPL_Cd(self._c_ampl, &workdir_c)
else:
PY_AMPL_CALL(campl.AMPL_Cd2(self._c_ampl, path.encode('utf-8'), &workdir_c))
errorinfo = campl.AMPL_Cd2(self._c_ampl, path.encode('utf-8'), &workdir_c)
rc = campl.AMPL_ErrorInfoGetError(errorinfo)
if rc != campl.AMPL_OK:
campl.AMPL_StringFree(&workdir_c)
PY_AMPL_CALL(errorinfo)
workdir = str(workdir_c.decode('utf-8'))
campl.AMPL_StringFree(&workdir_c)

return workdir

def set_option(self, name, value):
Expand Down Expand Up @@ -503,13 +510,17 @@ cdef class AMPL:
Raises:
InvalidArgumet: if the option name is not valid.
"""
cdef campl.AMPL_ERRORINFO* errorinfo
cdef campl.AMPL_RETCODE rc
cdef bool_c exists
cdef int integer
cdef double dbl
cdef char* value_c

errorinfo = campl.AMPL_GetOption(self._c_ampl, name.encode('utf-8'), &exists, &value_c)
rc = campl.AMPL_ErrorInfoGetError(errorinfo)
if rc != campl.AMPL_OK:
campl.AMPL_StringFree(&value_c)
PY_AMPL_CALL(errorinfo)

PY_AMPL_CALL(campl.AMPL_GetOption(self._c_ampl, name.encode('utf-8'), &exists, &value_c))
value = value_c.decode('utf-8')
campl.AMPL_StringFree(&value_c)
if exists:
Expand All @@ -520,8 +531,6 @@ cdef class AMPL:
return float(value)
except ValueError:
return value
#raise InvalidArgument


def read(self, filename):
"""
Expand Down Expand Up @@ -566,10 +575,18 @@ cdef class AMPL:
Returns:
The value of the expression.
"""
cdef campl.AMPL_ERRORINFO* errorinfo
cdef campl.AMPL_RETCODE rc
cdef campl.AMPL_VARIANT* v
PY_AMPL_CALL(campl.AMPL_GetValue(self._c_ampl, scalar_expression.encode('utf-8'), &v))
errorinfo = campl.AMPL_GetValue(self._c_ampl, scalar_expression.encode('utf-8'), &v)
rc = campl.AMPL_ErrorInfoGetError(errorinfo)
if rc != campl.AMPL_OK:
campl.AMPL_VariantFree(&v)
PY_AMPL_CALL(errorinfo)

py_variant = to_py_variant(v)
campl.AMPL_VariantFree(&v)

return py_variant

def set_data(self, data, set_name=None):
Expand Down Expand Up @@ -734,8 +751,14 @@ cdef class AMPL:
"""
Get the the current objective. Returns `None` if no objective is set.
"""
cdef campl.AMPL_ERRORINFO* errorinfo
cdef campl.AMPL_RETCODE rc
cdef char* objname_c
PY_AMPL_CALL(campl.AMPL_GetCurrentObjective(self._c_ampl, &objname_c))
errorinfo = campl.AMPL_GetCurrentObjective(self._c_ampl, &objname_c)
rc = campl.AMPL_ErrorInfoGetError(errorinfo)
if rc != campl.AMPL_OK:
campl.AMPL_StringFree(&objname_c)
PY_AMPL_CALL(errorinfo)
objname = str(objname_c.decode('utf-8'))
campl.AMPL_StringFree(&objname_c)
if objname == "":
Expand Down Expand Up @@ -883,10 +906,17 @@ cdef class AMPL:
filename: Path to the file (Relative to the current working
directory or absolute).
"""
cdef campl.AMPL_ERRORINFO* errorinfo
cdef campl.AMPL_RETCODE rc
cdef char* output_c
PY_AMPL_CALL(campl.AMPL_Snapshot(self._c_ampl, filename.encode('utf-8'), 1, 0, 0, &output_c))
errorinfo = campl.AMPL_Snapshot(self._c_ampl, filename.encode('utf-8'), 1, 0, 0, &output_c)
rc = campl.AMPL_ErrorInfoGetError(errorinfo)
if rc != campl.AMPL_OK:
campl.AMPL_StringFree(&output_c)
PY_AMPL_CALL(errorinfo)
output = str(output_c.decode('utf-8'))
campl.AMPL_StringFree(&output_c)

return output

def export_data(self, filename=""):
Expand All @@ -897,10 +927,17 @@ cdef class AMPL:
filename: Path to the file (Relative to the current working
directory or absolute).
"""
cdef campl.AMPL_ERRORINFO* errorinfo
cdef campl.AMPL_RETCODE rc
cdef char* output_c
PY_AMPL_CALL(campl.AMPL_Snapshot(self._c_ampl, filename.encode('utf-8'), 0, 1, 0, &output_c))
errorinfo = campl.AMPL_Snapshot(self._c_ampl, filename.encode('utf-8'), 0, 1, 0, &output_c)
rc = campl.AMPL_ErrorInfoGetError(errorinfo)
if rc != campl.AMPL_OK:
campl.AMPL_StringFree(&output_c)
PY_AMPL_CALL(errorinfo)
output = str(output_c.decode('utf-8'))
campl.AMPL_StringFree(&output_c)

return output

def snapshot(self, filename="", model=True, data=True, options=True):
Expand All @@ -917,13 +954,20 @@ cdef class AMPL:
options: include options if set to ``True``.
"""
cdef campl.AMPL_ERRORINFO* errorinfo
cdef campl.AMPL_RETCODE rc
cdef int model_c = model
cdef int data_c = data
cdef int options_c = options
cdef char* output_c
PY_AMPL_CALL(campl.AMPL_Snapshot(self._c_ampl, filename.encode('utf-8'), model_c, data_c, options_c, &output_c))
errorinfo = campl.AMPL_Snapshot(self._c_ampl, filename.encode('utf-8'), model_c, data_c, options_c, &output_c)
rc = campl.AMPL_ErrorInfoGetError(errorinfo)
if rc != campl.AMPL_OK:
campl.AMPL_StringFree(&output_c)
PY_AMPL_CALL(errorinfo)
output = str(output_c.decode('utf-8'))
campl.AMPL_StringFree(&output_c)

return output

def write(self, filename, auxfiles=""):
Expand Down
6 changes: 3 additions & 3 deletions amplpy/dataframe.pxi
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ cdef class DataFrame(object):
The number of indices needed to access one row of this dataframe.
"""
cdef size_t num
campl.AMPL_DataFrameGetNumIndices(self._c_df, &num)
PY_AMPL_CALL(campl.AMPL_DataFrameGetNumIndices(self._c_df, &num))
return int(num)

def _add_row(self, *value):
Expand Down Expand Up @@ -264,7 +264,7 @@ cdef class DataFrame(object):
if values is None:
values = []
if size == 0:
campl.AMPL_DataFrameAddEmptyColumn(self._c_df, header.encode('utf-8'))
PY_AMPL_CALL(campl.AMPL_DataFrameAddEmptyColumn(self._c_df, header.encode('utf-8')))
else:
assert len(values) == self._get_num_rows()
if any(isinstance(value, str) for value in values):
Expand Down Expand Up @@ -296,7 +296,7 @@ cdef class DataFrame(object):
header: The header of the column.
"""
cdef size_t index
campl.AMPL_DataFrameGetColumnIndex(self._c_df, header.encode('utf-8'), &index)
PY_AMPL_CALL(campl.AMPL_DataFrameGetColumnIndex(self._c_df, header.encode('utf-8'), &index))
return Column.create(self._c_df, index)

def _set_column(self, header, values):
Expand Down
4 changes: 2 additions & 2 deletions amplpy/entity.pxi
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ cdef class Entity(object):
if self._index is not NULL:
indexarity = 0
else:
campl.AMPL_EntityGetIndexarity(self._c_ampl, self._name, &indexarity)
PY_AMPL_CALL(campl.AMPL_EntityGetIndexarity(self._c_ampl, self._name, &indexarity))
return indexarity

def is_scalar(self):
Expand All @@ -193,7 +193,7 @@ cdef class Entity(object):
Get the number of instances in this entity.
"""
cdef size_t size
campl.AMPL_EntityGetNumInstances(self._c_ampl, self._name, &size);
PY_AMPL_CALL(campl.AMPL_EntityGetNumInstances(self._c_ampl, self._name, &size))
return int(size)

def get_indexing_sets(self):
Expand Down
6 changes: 3 additions & 3 deletions amplpy/set.pxi
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ cdef class Set(Entity):
set.
"""
cdef size_t arity
campl.AMPL_SetGetArity(self._c_ampl, self._name, &arity)
PY_AMPL_CALL(campl.AMPL_SetGetArity(self._c_ampl, self._name, &arity))
return int(arity)

def get_values(self):
Expand All @@ -83,7 +83,7 @@ cdef class Set(Entity):
Get the number of tuples in this set. Valid only for non-indexed sets.
"""
cdef size_t size
campl.AMPL_SetInstanceGetSize(self._c_ampl, self._name, self._index, &size)
PY_AMPL_CALL(campl.AMPL_SetInstanceGetSize(self._c_ampl, self._name, self._index, &size))
return int(size)

def contains(self, t):
Expand Down Expand Up @@ -136,7 +136,7 @@ cdef class Set(Entity):
self[index].set_values(members)
elif isinstance(values, DataFrame):
df = values
campl.AMPL_SetInstanceSetValuesDataframe(self._c_ampl, self._name, self._index, df.get_ptr())
PY_AMPL_CALL(campl.AMPL_SetInstanceSetValuesDataframe(self._c_ampl, self._name, self._index, df.get_ptr()))
elif isinstance(values, Iterable):
dimen = self.arity()
if dimen == 1 and all(isinstance(value, str) for value in values):
Expand Down

0 comments on commit f77f3c8

Please sign in to comment.