From 62eed00d898ab88b2d3316b634be1d2cd7101ca6 Mon Sep 17 00:00:00 2001 From: Anthony Onwuli <30937913+AntObi@users.noreply.github.com> Date: Fri, 3 May 2024 17:29:31 +0100 Subject: [PATCH] Add `is_radioactive` property to Element class (#3804) * Add is_radioactive property * Add is_radioactive to test_attributes * Add radioactive to docstring of contains_element_type * Update len(ElementType) in test * test negative cases in TestElement.test_attributes --------- Co-authored-by: Janosh Riebesell --- pymatgen/core/composition.py | 2 +- pymatgen/core/periodic_table.py | 6 +++++ tests/core/test_periodic_table.py | 44 +++++++++++++++++-------------- 3 files changed, 31 insertions(+), 21 deletions(-) diff --git a/pymatgen/core/composition.py b/pymatgen/core/composition.py index f8040127b88..45a5fa1e055 100644 --- a/pymatgen/core/composition.py +++ b/pymatgen/core/composition.py @@ -508,7 +508,7 @@ def contains_element_type(self, category: str) -> bool: category (str): one of "noble_gas", "transition_metal", "post_transition_metal", "rare_earth_metal", "metal", "metalloid", "alkali", "alkaline", "halogen", "chalcogen", "lanthanoid", - "actinoid", "quadrupolar", "s-block", "p-block", "d-block", "f-block" + "actinoid", "radioactive", "quadrupolar", "s-block", "p-block", "d-block", "f-block" Returns: bool: True if any elements in Composition match category, otherwise False diff --git a/pymatgen/core/periodic_table.py b/pymatgen/core/periodic_table.py index 75384d983c7..01fef651391 100644 --- a/pymatgen/core/periodic_table.py +++ b/pymatgen/core/periodic_table.py @@ -738,6 +738,11 @@ def is_actinoid(self) -> bool: """True if element is a actinoid.""" return 88 < self.Z < 104 + @property + def is_radioactive(self) -> bool: + """True if element is radioactive.""" + return self.Z in (43, 61) or self.Z >= 84 + @property def is_quadrupolar(self) -> bool: """Check if this element can be quadrupolar.""" @@ -1512,6 +1517,7 @@ class ElementType(Enum): chalcogen = "chalcogen" # O, S, Se, Te, Po lanthanoid = "lanthanoid" # La-Lu actinoid = "actinoid" # Ac-Lr + radioactive = "radioactive" # Tc, Pm, Po-Lr quadrupolar = "quadrupolar" s_block = "s-block" p_block = "p-block" diff --git a/tests/core/test_periodic_table.py b/tests/core/test_periodic_table.py index 1d51acd0ef8..74aa0f8061e 100644 --- a/tests/core/test_periodic_table.py +++ b/tests/core/test_periodic_table.py @@ -227,21 +227,25 @@ def test_ground_state_term_symbol(self): assert Element(key).ground_state_term_symbol == val def test_attributes(self): - is_true = { - ("Xe", "Kr"): "is_noble_gas", - ("Fe", "Ni"): "is_transition_metal", - ("Li", "Cs"): "is_alkali", - ("Ca", "Mg"): "is_alkaline", - ("F", "Br", "I"): "is_halogen", - ("La",): "is_lanthanoid", - ("U", "Pu"): "is_actinoid", - ("Si", "Ge"): "is_metalloid", - ("O", "Te"): "is_chalcogen", + bool_attrs = { + ("Xe", "Kr"): ("is_noble_gas", True), + ("H", "Cl"): ("is_noble_gas", False), + ("Fe", "Ni"): ("is_transition_metal", True), + ("Li", "Cs"): ("is_alkali", True), + ("Ca", "Mg"): ("is_alkaline", True), + ("F", "Br", "I"): ("is_halogen", True), + ("La", "Ce", "Lu"): ("is_lanthanoid", True), + ("U", "Pu"): ("is_actinoid", True), + ("Si", "Ge"): ("is_metalloid", True), + ("O", "Te"): ("is_chalcogen", True), + ("N", "Sb", "Ta"): ("is_chalcogen", False), + ("Tc", "Po"): ("is_radioactive", True), + ("H", "Li", "Bi"): ("is_radioactive", False), } - for key, val in is_true.items(): - for sym in key: - assert getattr(Element(sym), val), f"{sym=} is false" + for elements, (attr, expected) in bool_attrs.items(): + for elem in elements: + assert getattr(Element(elem), attr) is expected, f"{elem=} {attr=}, {expected=}" keys = ( "atomic_mass", @@ -288,15 +292,15 @@ def test_attributes(self): # Test all elements up to Uranium for idx in range(1, 104): el = Element.from_Z(idx) - for key in keys: - key_str = key.capitalize().replace("_", " ") + for elements in keys: + key_str = elements.capitalize().replace("_", " ") if key_str in el.data and (not str(el.data[key_str]).startswith("no data")): - assert getattr(el, key) is not None - elif key == "long_name": + assert getattr(el, elements) is not None + elif elements == "long_name": assert el.long_name == el.data["Name"] - elif key == "iupac_ordering": + elif elements == "iupac_ordering": assert "IUPAC ordering" in el.data - assert getattr(el, key) is not None + assert getattr(el, elements) is not None if len(el.oxidation_states) > 0: assert max(el.oxidation_states) == el.max_oxidation_state @@ -607,4 +611,4 @@ def test_get_el_sp(): def test_element_type(): assert isinstance(ElementType.actinoid, Enum) assert isinstance(ElementType.metalloid, Enum) - assert len(ElementType) == 17 + assert len(ElementType) == 18