diff --git a/astroplan/observer.py b/astroplan/observer.py index 34f07205..03f148dc 100644 --- a/astroplan/observer.py +++ b/astroplan/observer.py @@ -273,6 +273,85 @@ def __repr__(self): attributes_strings.append("{}={}".format(name, value)) return "<{}: {}>".format(class_name, ",\n ".join(attributes_strings)) + def _key(self): + """ + Generate a tuple of the attributes that determine uniqueness of + `~astroplan.Observer` objects. + + Returns + ------- + key : tuple + + Examples + -------- + + >>> from astroplan import Observer + >>> keck = Observer.at_site("Keck", timezone="US/Hawaii") + >>> keck._key() + ('Keck', None, None, None, , + , , + ) + """ + + return (self.name, + self.pressure, + self.temperature, + self.relative_humidity, + self.longitude, + self.latitude, + self.elevation, + self.timezone,) + + def __hash__(self): + """ + Hash the `~astroplan.Observer` object. + + Examples + -------- + + >>> from astroplan import Observer + >>> keck = Observer.at_site("Keck", timezone="US/Hawaii") + >>> hash(keck) + -3872382927731250571 + """ + + return hash(self._key()) + + def __eq__(self, other): + """ + Equality check for `~astroplan.Observer` objects. + + Examples + -------- + + >>> from astroplan import Observer + >>> keck = Observer.at_site("Keck", timezone="US/Hawaii") + >>> keck2 = Observer.at_site("Keck", timezone="US/Hawaii") + >>> keck == keck2 + True + """ + + if isinstance(other, Observer): + return self._key() == other._key() + else: + return NotImplemented + + def __ne__(self, other): + """ + Inequality check for `~astroplan.Observer` objects. + + Examples + -------- + + >>> from astroplan import Observer + >>> keck = Observer.at_site("Keck", timezone="US/Hawaii") + >>> kpno = Observer.at_site("KPNO", timezone="US/Arizona") + >>> keck != kpno + True + """ + + return not self.__eq__(other) + @classmethod def at_site(cls, site_name, **kwargs): """ diff --git a/astroplan/tests/test_observer.py b/astroplan/tests/test_observer.py index 33c8cc9a..c52f2f2f 100644 --- a/astroplan/tests/test_observer.py +++ b/astroplan/tests/test_observer.py @@ -1358,3 +1358,32 @@ def test_observer_lon_lat_el(): obs = Observer.at_site('Subaru') for attr in ['longitude', 'latitude', 'elevation']: assert hasattr(obs, attr) + + +def test_hash_observer(): + """Test that Observer objects are hashable.""" + obs1 = Observer.at_site('Subaru') + obs2 = Observer.at_site('Subaru') + assert hash(obs1) == hash(obs2) + + obs3 = Observer.at_site('Keck', timezone='US/Hawaii') + assert hash(obs1) != hash(obs3) + + obs4 = Observer.at_site('Keck', timezone='US/Hawaii') + assert hash(obs3) == hash(obs4) + + +def test_eq_observer(): + """Test that Observer objects are comparable.""" + obs1 = Observer.at_site('Subaru') + obs2 = Observer.at_site('Subaru') + assert obs1 == obs2 + + obs3 = Observer.at_site('Keck') + assert obs1 != obs3 + + obs4 = Observer.at_site('Subaru', timezone='US/Hawaii') + assert obs1 != obs4 + + obs5 = Observer.at_site('Subaru', timezone='US/Hawaii') + assert obs4 == obs5