class_docstr: Class for presenting outcome constraints composed of a linear
  scalarization of metrics.
  
  Attributes:
      metrics: List of metrics.
      weights: Weights for scalarization; default to 1.0 / len(metrics).
      op: Specifies whether metric should be greater or equal
          to, or less than or equal to, some bound.
      bound: The bound in the constraint.
      relative: [default ``True``] Whether the provided bound value is relative to
          some status-quo arm's metric value. If False, ``bound`` is interpreted as an
          absolute number, else ``bound`` specifies percent-difference from the
          observed metric value on the status-quo arm. That is, the bound's absolute
          value will be ``(1 + bound/100.0) * status_quo_metric_value``. This requires
          specification of a status-quo arm in ``Experiment``.
class_docstr_tok: ["Class","for","presenting","outcome","constraints","composed","of","a","linear","scalarization","of","metrics",".","Attributes",":","metrics",":","List","of","metrics",".","weights",":","Weights","for","scalarization",";","default","to","1.0","\/","len","(","metrics",")",".","op",":","Specifies","whether","metric","should","be","greater","or","equal","to",",","or","less","than","or","equal","to",",","some","bound",".","bound",":","The","bound","in","the","constraint",".","relative",":","[","default","``","True","``","]","Whether","the","provided","bound","value","is","relative","to","some","status-quo","arm","'s","metric","value",".","If","False",",","``","bound","``","is","interpreted","as","an","absolute","number",",","else","``","bound","``","specifies","percent-difference","from","the","observed","metric","value","on","the","status-quo","arm",".","That","is",",","the","bound","'s","absolute","value","will","be","``","(","1","+","bound\/100.0",")","*","status_quo_metric_value","``",".","This","requires","specification","of","a","status-quo","arm","in","``","Experiment","``","."]
code: def __init__(
      self,
      metrics: List[Metric],
      op: ComparisonOp,
      bound: float,
      relative: bool = True,
      weights: Optional[List[float]] = None,
  ) -> None:
      for metric in metrics:
          self._validate_metric_constraint(metric=metric, op=op)
  
      if weights is None:
          weights = [1.0 / len(metrics)] * len(metrics)
      elif len(weights) != len(metrics):
          raise ValueError(
              "Length of weights must equal length of metrics"
          )
      self._metrics = metrics
      self.weights = weights
      self._op = op
      self.bound = bound
      self.relative = relative
  
imports: from __future__ import annotations
  import logging
  from typing import Dict, Iterable, List, Optional, Tuple
  from ax.core.metric import Metric
  from ax.core.types import ComparisonOp
  from ax.utils.common.base import SortableBase
  from ax.utils.common.logger import get_logger
label_desc: Use image node_id 1 to create a new ScalarizedOutcomeConstraint object from inherited base classes: OutcomeConstraint with example: obj = ScalarizedOutcomeConstraint(metrics, op, bound, relative, weights)