def element_from_name(name): """Search for an element by its name Look up an element from a list of known elements by name. Parameters ---------- name : str Element name to look for, digits and spaces are removed before search Returns ------- matched_element : element.Element The matching element from the periodic table Raises ------ ElementError If no match is found """ if not isinstance(name, str): raise TypeError( f"`string` ({name}) must be a string. Provided {type(name).__name__}." ) name = name.lower() matched_element = name_dict.get(name) if matched_element is None: raise ElementError(f"No element with name {name}") return matched_element
def element_from_atomic_number(atomic_number): """Search for an element by its atomic number Look up an element from a list of known elements by atomic number. Parameters ---------- atomic_number : int Element atomic number Returns ------- matched_element : element.Element The matching element from the periodic table Raises ------ ElementError If no match is found """ if not isinstance(atomic_number, int): raise TypeError( f"`string` ({atomic_number}) must be an integer. Provided {type(atomic_number).__name__}." ) matched_element = atomic_dict.get(atomic_number) if matched_element is None: raise ElementError(f"No element with atomic number {atomic_number}") return matched_element
def element_from_symbol(symbol): """Search for an element by its symbol Look up an element from a list of known elements by symbol. Parameters ---------- symbol : str Element symbol Returns ------- matched_element : element.Element The matching element from the periodic table Raises ------ ElementError If no match is found """ if not isinstance(symbol, str): raise TypeError( f"`string` ({symbol}) must be a string. Provided {type(symbol).__name__}." ) symbol = symbol.capitalize() matched_element = symbol_dict.get(symbol) if matched_element is None: raise ElementError(f"No element with symbol {symbol}") return matched_element
def element_from_mass(mass, exact=True, duplicates="error"): """Search for an element by its mass Look up an element from a list of known elements by mass (amu). By default, requires that the element mass match exactly to the first digit after the decimal. Using `exact=False` will switch this behavior to return the element with the closest mass. Parameters ---------- mass : int, float Element mass in amu exact : bool, optional, default=True Require that the mass match to the first decimal. If False, the element with the closest mass will be returned duplicates : enum, optional, default="error" How to handle duplicate elements with the same mass. Error ("error"), return a tuple ("all"), or return None ("none") Returns ------- matched_element : element.Element or tuple of element.Element The matching element(s) from the periodic table """ if not isinstance(mass, (float, int)): raise TypeError("`mass` ({mass}) must be a float") if duplicates.lower() not in ["error", "all", "none"]: raise TypeError( "`duplicates` must be one of the following: `error`, `all`, `none`" ) mass = round(float(mass), 1) if exact: # Exact search mode matched_element = mass_dict.get(mass) else: # Closest match mode mass_closest = min(mass_dict.keys(), key=lambda k: abs(k - mass)) msg = "Closest mass to {}: {}".format(mass, mass_closest) warnings.warn(msg) matched_element = mass_dict.get(mass_closest) if matched_element is None: raise ElementError(f"No element with mass {mass}") if len(matched_element) == 1: matched_element = matched_element[0] else: if duplicates.lower() == "error": raise MultiMatchError( f"Multiple elements have mass {mass}: {matched_element}") elif duplicates.lower() == "all": matched_element = tuple(matched_element) elif duplicates.lower() == "none": matched_element = None return matched_element
def element_from_name(name): """Search for an element by its name Look up an element from a list of known elements by name. Return None if no match found. Parameters ---------- name : str Element name to look for, digits and spaces are removed before search Returns ------- matched_element : element.Element Return an element from the periodic table if the name is found, otherwise return None """ if not isinstance(name, str): raise TypeError("`name` ({name}) must be a string") name = name.lower() matched_element = name_dict.get(name) if matched_element is None: raise ElementError(f"No element with name {name}") return matched_element
def element_from_symbol(symbol): """Search for an element by its symbol Look up an element from a list of known elements by symbol. Return None if no match found. Parameters ---------- symbol : str Element symbol Returns ------- matched_element : element.Element Return an element from the periodic table if the symbol is found, otherwise return None """ if not isinstance(symbol, str): raise TypeError("`symbol` ({symbol}) must be a string") symbol = symbol.capitalize() matched_element = symbol_dict.get(symbol) if matched_element is None: raise ElementError(f"No element with symbol {symbol}") return matched_element
def element_from_atomic_number(atomic_number): """Search for an element by its atomic number Look up an element from a list of known elements by atomic number. Parameters ---------- atomic_number : int Element atomic number Returns ------- matched_element : element.Element Return an element from the periodic table if we find a match, """ if not isinstance(atomic_number, int): raise TypeError("`atomic_number` ({atomic_number}) must be an int") matched_element = atomic_dict.get(atomic_number) if matched_element is None: raise ElementError(f"No element with atomic number {atomic_number}") return matched_element
def infer_element_from_string(string): """Attempt to infer an element from a string First checks if the string matches a two-character element symbol. If not, checks if the string matches an element name. Parameters ---------- string : str String to attempt element inference from Returns ------- matched_element : element.Element The matching element from the periodic table Raises ------ ElementError If no match is found """ if not isinstance(string, str): raise TypeError( f"`string` ({string}) must be a string. Provided {type(string).__name__}" ) try: matched_element = element_from_symbol(string) except ElementError: try: matched_element = element_from_name(string) except ElementError: raise ElementError( f"Unable to match {string} with element name or symbol") return matched_element