def __eq__(self, other: "Base"): for field in self.__dict__.keys(): self_val = getattr(self, field) other_val = getattr(other, field) self_val = numpy_type_to_python_type(self_val) other_val = numpy_type_to_python_type(other_val) if type(self_val) != type(other_val): return False if field == "_experiment": # prevent infinite loop when checking equality of Trials equal = self_val.name == other_val.name elif isinstance(self_val, list): equal = same_elements(self_val, other_val) elif isinstance(self_val, np.ndarray): equal = np.array_equal(self_val, other_val) elif isinstance(self_val, datetime): equal = datetime_equals(self_val, other_val) elif isinstance(self_val, pd.DataFrame): equal = self_val.equals(other_val) else: equal = self_val == other_val if not equal: return False return True
def __eq__(self, other: "Base") -> bool: for field in self.__dict__.keys(): self_val = getattr(self, field) other_val = getattr(other, field) self_val = numpy_type_to_python_type(self_val) other_val = numpy_type_to_python_type(other_val) if type(self_val) != type(other_val): return False if field == "_experiment": # prevent infinite loop when checking equality of Trials equal = self_val is other_val is None or (self_val._name == other_val._name) elif field == "_model": # pragma: no cover (tested in modelbridge) # TODO[T52643706]: replace with per-`ModelBridge` method like # `equivalent_models`, to compare models more meaningfully. if not hasattr(self_val, "model"): equal = not hasattr(other_val, "model") else: # If model bridges have a `model` attribute, the types of the # values of those attributes should be equal if the model # bridge is the same. equal = isinstance(self_val.model, type(other_val.model)) elif isinstance(self_val, list): equal = same_elements(self_val, other_val) elif isinstance(self_val, dict): equal = sorted(self_val.keys()) == sorted(other_val.keys()) equal = equal and same_elements(list(self_val.values()), list(other_val.values())) elif isinstance(self_val, np.ndarray): equal = np.array_equal(self_val, other_val) elif isinstance(self_val, datetime): equal = datetime_equals(self_val, other_val) elif isinstance(self_val, float): equal = np.isclose(self_val, other_val) elif isinstance(self_val, pd.DataFrame): try: if self_val.empty and other_val.empty: equal = True else: pd.testing.assert_frame_equal( self_val.sort_index(axis=1), other_val.sort_index(axis=1), check_exact=False, ) equal = True except AssertionError: equal = False else: equal = self_val == other_val if not equal: return False return True
def fields_equal(self, other: "SQABase", field: str) -> bool: """Check if `field` on `self` is equal to `field` on `other`.""" self_val = getattr(self, field) other_val = getattr(other, field) if type(self_val) != type(other_val): return False if isinstance(self_val, list): return SQABase.list_equals(self_val, other_val) elif isinstance(self_val, SQABase): return self_val.equals(other_val) elif isinstance(self_val, datetime): return datetime_equals(self_val, other_val) else: return self_val == other_val
def update_field(self, other: "SQABase", field: str) -> None: """Update `field` on `self` to be equal to `field` on `other`.""" self_val = getattr(self, field) other_val = getattr(other, field) if isinstance(self_val, list) and isinstance(other_val, list): other_val = SQABase.list_update(self_val, other_val) elif isinstance(self_val, SQABase) and isinstance(other_val, SQABase): self_val.update(other_val) other_val = self_val elif isinstance(self_val, datetime) and isinstance( other_val, datetime): if datetime_equals(self_val, other_val): return elif self_val == other_val: return setattr(self, field, other_val)
def validate_experiment_metadata( cls, experiment: Experiment, existing_sqa_experiment: Optional[SQAExperiment], owners: Optional[List[str]] = None, ) -> None: """Validates required experiment metadata. Does *not* expect owners kwarg, present for use in subclasses. """ if owners: raise ValueError("Owners for experiment unexpectedly provided.") if existing_sqa_experiment is not None and not datetime_equals( existing_sqa_experiment.time_created, experiment.time_created): raise Exception( f"An experiment already exists with the name {experiment.name}." )
def fields_equal(self, other: SQABase, field: str) -> bool: """Check if `field` on `self` is equal to `field` on `other`.""" self_val = getattr(self, field) other_val = getattr(other, field) self_val = numpy_type_to_python_type(self_val) other_val = numpy_type_to_python_type(other_val) if type(self_val) != type(other_val): return False if isinstance(self_val, list): return SQABase.list_equals(self_val, other_val) elif isinstance(self_val, SQABase): return self_val.equals(other_val) elif isinstance(self_val, datetime): return datetime_equals(self_val, other_val) elif isinstance(self_val, float): return np.isclose(self_val, other_val) else: return self_val == other_val
def _save_experiment( experiment: Experiment, encoder: Encoder, overwrite: bool = False ) -> None: """Save experiment, using given Encoder instance. 1) Convert Ax object to SQLAlchemy object. 2) Determine if there is an existing experiment with that name in the DB. 3) If not, create a new one. 4) If so, update the old one. The update works by merging the new SQLAlchemy object into the existing SQLAlchemy object, and then letting SQLAlchemy handle the actual DB updates. """ # Convert user-facing class to SQA outside of session scope to avoid timeouts new_sqa_experiment = encoder.experiment_to_sqa(experiment) exp_sqa_class = encoder.config.class_to_sqa_class[Experiment] with session_scope() as session: existing_sqa_experiment = ( session.query(exp_sqa_class).filter_by(name=experiment.name).one_or_none() ) if existing_sqa_experiment is not None: if ( not datetime_equals( existing_sqa_experiment.time_created, new_sqa_experiment.time_created ) and overwrite is False ): raise Exception( "An experiment already exists with the name " f"{new_sqa_experiment.name}. To overwrite, specify " "`overwrite = True` when calling `save_experiment`." ) # Update the SQA object outside of session scope to avoid timeouts. # This object is detached from the session, but contains a database # identity marker, so when we do `session.add` below, SQA knows to # perform an update rather than an insert. existing_sqa_experiment.update(new_sqa_experiment) new_sqa_experiment = existing_sqa_experiment with session_scope() as session: session.add(new_sqa_experiment)
def __eq__(self, other: "AbandonedArm") -> bool: return (self.name == other.name and self.reason == other.reason and datetime_equals(self.time, other.time))
def testDatetimeEquals(self): now = datetime.now() self.assertTrue(datetime_equals(None, None)) self.assertFalse(datetime_equals(None, now)) self.assertTrue(datetime_equals(now, now))