diff --git a/rhodium/decorators.py b/rhodium/decorators.py
index bd78d2b..4903008 100644
--- a/rhodium/decorators.py
+++ b/rhodium/decorators.py
@@ -17,17 +17,13 @@
# along with Rhodium. If not, see .
import random
import inspect
+from abc import ABCMeta
from .model import Constraint, Lever, Model, Parameter, Response, \
Uncertainty, CategoricalLever, IntegerLever, PermutationLever, \
SubsetLever, RealLever, UniformUncertainty, NormalUncertainty, \
- LogNormalUncertainty
+ LogNormalUncertainty, Direction
-MINIMIZE = Response.MINIMIZE
-MAXIMIZE = Response.MAXIMIZE
-INFO = Response.INFO
-IGNORE = Response.IGNORE
-
-class UnnamedObject:
+class UnnamedObject(metaclass=ABCMeta):
def __init__(self, constructor, *args, **kwargs):
self.constructor = constructor
@@ -89,22 +85,22 @@ def __new__(cls, *args, **kwargs):
class Minimize(Response):
def __init__(self, name, **kwargs):
- super().__init__(name, type=Response.MINIMIZE, **kwargs)
+ super().__init__(name, direction=Direction.MINIMIZE, **kwargs)
class Maximize(Response):
def __init__(self, name, **kwargs):
- super().__init__(name, type=Response.MAXIMIZE, **kwargs)
+ super().__init__(name, direction=Direction.MAXIMIZE, **kwargs)
class Info(Response):
def __init__(self, name, **kwargs):
- super().__init__(name, type=Response.INFO, **kwargs)
+ super().__init__(name, direction=Direction.INFO, **kwargs)
class Ignore(Response):
- def __init__(self, **kwargs):
- super().__init__("Ignored" + str(random.randint()), type=Response.IGNORE, **kwargs)
+ def __init__(self, name=None, **kwargs):
+ super().__init__("Ignored" + str(random.randint()) if name is None else name, direction=Direction.IGNORE, **kwargs)
class CallableModel(Model):
diff --git a/rhodium/model.py b/rhodium/model.py
index db0379c..3e57abf 100644
--- a/rhodium/model.py
+++ b/rhodium/model.py
@@ -67,11 +67,10 @@ class Direction(Enum):
class Response(NamedObject):
"""Defines a model response (i.e., output).
- Defines a model response (i.e., output) and its type. The type can be
- MINIMIZE, MAXIMIZE, or INFO. If MINIMIZE or MAXIMIZE, then the response
- may be used during optimization. If INFO, the default, the response is
- purely for informative purposes (e.g., for generating plots) but does not
- participate in optimization.
+ Defines a model response (i.e., output) and its direction. If MINIMIZE or
+ MAXIMIZE, then the response may be used during optimization. If INFO, the
+ default, the response is purely for informative purposes (e.g., for
+ generating plots) but does not participate in optimization.
"""
# These constants are deprecated. Use the Direction enum instead.
diff --git a/rhodium/test/decorators_test.py b/rhodium/test/decorators_test.py
new file mode 100644
index 0000000..e7f6c21
--- /dev/null
+++ b/rhodium/test/decorators_test.py
@@ -0,0 +1,42 @@
+# Copyright 2015-2024 David Hadka
+#
+# This file is part of Rhodium, a Python module for robust decision
+# making and exploratory modeling.
+#
+# Rhodium is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Rhodium is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Rhodium. If not, see .
+import unittest
+from ..model import Direction
+from ..decorators import Minimize, Maximize, Info, Ignore
+
+class TestResponses(unittest.TestCase):
+
+ def testMinimize(self):
+ r = Minimize("foo")
+ self.assertEqual("foo", r.name)
+ self.assertEqual(Direction.MINIMIZE, r.direction)
+
+ def testMaximize(self):
+ r = Maximize("foo")
+ self.assertEqual("foo", r.name)
+ self.assertEqual(Direction.MAXIMIZE, r.direction)
+
+ def testInfo(self):
+ r = Info("foo")
+ self.assertEqual("foo", r.name)
+ self.assertEqual(Direction.INFO, r.direction)
+
+ def testIgnore(self):
+ r = Ignore("foo")
+ self.assertEqual("foo", r.name)
+ self.assertEqual(Direction.IGNORE, r.direction)