Skip to content

Commit

Permalink
Fix bug with proton equality while continuing Particle.__init__ ref…
Browse files Browse the repository at this point in the history
…actoring (PlasmaPy#1366)

* Add failing test for proton equality bug

* Add failing test for Particle("H", Z=1, mass_numb=1)

* Add a hack to fix proton equality bug

* A hack to try to fix

This bug suggests that Particle.__init__ could use some friendly
refactoring.

* Add changelog entry

* More extract method pattern from Particle.__init__

* Create inputs dict in Particle

* Use Particle._inputs instead of arguments to methods

* More extract method

* Move method around

* Minor reorganizing

* More re-organizing

* Rename variable

* Use _inputs instead of arguments

* Finally proton equality bug

* Renaming and reorganization

* Simplify naming

* Simplify naming

* Use _inputs

* Minor changes

* Minor changes

* Minor changes

* Minor changes

* Minor changes

* Renaming variables and some minor reorganization

* Renaming variables and reorganization

* Slight change to test

* Slight change to test

* Slight changes to tests

* Add second changelog entry

* Update docstrings

* Remove Particle.__name__

* Remove unnecessary .keys() for dicts

* Remove unnecessary .keys() for dicts

* Change Particle._inputs to Particle.__inputs

* Rename dict containing data about special particles

* Remove delattr of Particle.__inputs

* Remove unnecessary .keys() for dicts

* Remove unnecessary use of .keys() in tests

* Remove unnecessary import

* Add docstring back for Particle.__init__

Adding this line back because it might be responsible for some
documentation test failures that started happening soon after.

* Add back Particle.__name__

* Remove docstring for Particle.__init__

* Revert Particle.__name__ line to pre-PR form

* Add comment about Particle.__name__

* Updates following code review

* Add comment about why protons are being treated specially
  • Loading branch information
namurphy authored Feb 24, 2022
1 parent a5636dd commit ba45c40
Show file tree
Hide file tree
Showing 13 changed files with 242 additions and 151 deletions.
2 changes: 2 additions & 0 deletions changelog/1366.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Fixed a bug with |Particle| where ``Particle("p+") == Particle("H", Z=1,
mass_numb=1)`` led to a |ParticleError|.
2 changes: 2 additions & 0 deletions changelog/1366.trivial.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Used the extract method refactoring pattern on the initialization of
|Particle| objects.
24 changes: 13 additions & 11 deletions plasmapy/particles/atomic.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,14 @@
from typing import Any, List, Optional, Union

from plasmapy.particles.decorators import particle_input
from plasmapy.particles.elements import _elements
from plasmapy.particles.elements import _data_about_elements
from plasmapy.particles.exceptions import (
InvalidElementError,
InvalidIsotopeError,
InvalidParticleError,
MissingParticleDataError,
)
from plasmapy.particles.isotopes import _isotopes
from plasmapy.particles.isotopes import _data_about_isotopes
from plasmapy.particles.particle_class import Particle
from plasmapy.particles.symbols import atomic_symbol
from plasmapy.utils.decorators.deprecation import deprecated
Expand Down Expand Up @@ -590,7 +590,7 @@ def known_isotopes(argument: Union[str, Integral] = None) -> List[str]:
def known_isotopes_for_element(argument):
element = atomic_symbol(argument)
isotopes = []
for isotope in _isotopes.keys():
for isotope in _data_about_isotopes:
if element + "-" in isotope and isotope[0 : len(element)] == element:
isotopes.append(isotope)
if element == "H":
Expand All @@ -616,7 +616,7 @@ def known_isotopes_for_element(argument):
raise InvalidParticleError("Invalid particle in known_isotopes.")
elif argument is None:
isotopes_list = []
for atomic_numb in range(1, len(_elements.keys()) + 1):
for atomic_numb in range(1, len(_data_about_elements) + 1):
isotopes_list += known_isotopes_for_element(atomic_numb)

return isotopes_list
Expand Down Expand Up @@ -700,11 +700,13 @@ def common_isotopes_for_element(
isotopes = known_isotopes(argument)

CommonIsotopes = [
isotope for isotope in isotopes if "abundance" in _isotopes[isotope].keys()
isotope
for isotope in isotopes
if "abundance" in _data_about_isotopes[isotope]
]

isotopic_abundances = [
_isotopes[isotope]["abundance"] for isotope in CommonIsotopes
_data_about_isotopes[isotope]["abundance"] for isotope in CommonIsotopes
]

sorted_isotopes = [
Expand Down Expand Up @@ -818,7 +820,7 @@ def stable_isotopes_for_element(
StableIsotopes = [
isotope
for isotope in KnownIsotopes
if _isotopes[isotope]["stable"] == stable_only
if _data_about_isotopes[isotope]["stable"] == stable_only
]
return StableIsotopes

Expand Down Expand Up @@ -962,7 +964,7 @@ def periodic_table_period(argument: Union[str, Integral]) -> Integral:
"integer representing its atomic number."
)
symbol = atomic_symbol(argument)
period = _elements[symbol]["period"]
period = _data_about_elements[symbol]["period"]
return period


Expand Down Expand Up @@ -1016,7 +1018,7 @@ def periodic_table_group(argument: Union[str, Integral]) -> Integral:
"symbol, or an integer representing its atomic number."
)
symbol = atomic_symbol(argument)
group = _elements[symbol]["group"]
group = _data_about_elements[symbol]["group"]
return group


Expand Down Expand Up @@ -1070,7 +1072,7 @@ def periodic_table_block(argument: Union[str, Integral]) -> str:
"symbol, or an integer representing its atomic number."
)
symbol = atomic_symbol(argument)
block = _elements[symbol]["block"]
block = _data_about_elements[symbol]["block"]
return block


Expand Down Expand Up @@ -1122,7 +1124,7 @@ def periodic_table_category(argument: Union[str, Integral]) -> str:
"symbol, or an integer representing its atomic number."
)
symbol = atomic_symbol(argument)
category = _elements[symbol]["category"]
category = _data_about_elements[symbol]["category"]
return category


Expand Down
6 changes: 3 additions & 3 deletions plasmapy/particles/elements.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,16 +45,16 @@ def _element_obj_hook(obj):
# json.dump(_Elements, f, default=plasma_default, indent=2)


_elements = json.loads(
_data_about_elements = json.loads(
pkgutil.get_data("plasmapy", "particles/data/elements.json"),
object_hook=_element_obj_hook,
)


_atomic_numbers_to_symbols = {
elemdict["atomic number"]: symb for (symb, elemdict) in _elements.items()
elemdict["atomic number"]: symb for (symb, elemdict) in _data_about_elements.items()
}

_element_names_to_symbols = {
elemdict["element name"]: symb for (symb, elemdict) in _elements.items()
elemdict["element name"]: symb for (symb, elemdict) in _data_about_elements.items()
}
2 changes: 1 addition & 1 deletion plasmapy/particles/isotopes.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ def _isotope_obj_hook(obj):


#: Dictionary of isotope data.
_isotopes = json.loads(
_data_about_isotopes = json.loads(
pkgutil.get_data("plasmapy", "particles/data/isotopes.json"),
object_hook=_isotope_obj_hook,
)
37 changes: 20 additions & 17 deletions plasmapy/particles/parsing.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,23 @@

from plasmapy.particles.elements import (
_atomic_numbers_to_symbols,
_data_about_elements,
_element_names_to_symbols,
_elements,
)
from plasmapy.particles.exceptions import (
InvalidElementError,
InvalidParticleError,
ParticleWarning,
)
from plasmapy.particles.isotopes import _isotopes
from plasmapy.particles.special_particles import _Particles, ParticleZoo
from plasmapy.particles.isotopes import _data_about_isotopes
from plasmapy.particles.special_particles import (
_data_about_special_particles,
ParticleZoo,
)
from plasmapy.utils import roman


def _create_alias_dicts(Particles: dict) -> (Dict[str, str], Dict[str, str]):
def _create_alias_dicts(particles: dict) -> (Dict[str, str], Dict[str, str]):
"""
Create dictionaries for case sensitive aliases and case
insensitive aliases of special particles and antiparticles.
Expand All @@ -42,8 +45,8 @@ def _create_alias_dicts(Particles: dict) -> (Dict[str, str], Dict[str, str]):
case_sensitive_aliases = {}
case_insensitive_aliases = {}

for symbol in Particles.keys():
name = Particles[symbol]["name"]
for symbol in particles:
name = particles[symbol]["name"]
case_insensitive_aliases[name.lower()] = symbol

case_sensitive_aliases_for_a_symbol = [
Expand Down Expand Up @@ -111,7 +114,9 @@ def _create_alias_dicts(Particles: dict) -> (Dict[str, str], Dict[str, str]):
return case_sensitive_aliases, case_insensitive_aliases


_case_sensitive_aliases, _case_insensitive_aliases = _create_alias_dicts(_Particles)
_case_sensitive_aliases, _case_insensitive_aliases = _create_alias_dicts(
_data_about_special_particles
)


def _dealias_particle_aliases(alias: Union[str, Integral]) -> str:
Expand All @@ -129,9 +134,9 @@ def _dealias_particle_aliases(alias: Union[str, Integral]) -> str:
or alias in _case_insensitive_aliases.values()
):
symbol = alias
elif alias in _case_sensitive_aliases.keys():
elif alias in _case_sensitive_aliases:
symbol = _case_sensitive_aliases[alias]
elif alias.lower() in _case_insensitive_aliases.keys():
elif alias.lower() in _case_insensitive_aliases:
symbol = _case_insensitive_aliases[alias.lower()]
else:
symbol = alias
Expand Down Expand Up @@ -269,7 +274,7 @@ def _atomic_number_to_symbol(atomic_numb: Integral):
`~plasmapy.particles.exceptions.InvalidParticleError` if the atomic number does
not represent a known element.
"""
if atomic_numb in _atomic_numbers_to_symbols.keys():
if atomic_numb in _atomic_numbers_to_symbols:
return _atomic_numbers_to_symbols[atomic_numb]
else:
raise InvalidParticleError(f"{atomic_numb} is not a valid atomic number.")
Expand Down Expand Up @@ -311,7 +316,7 @@ def _get_element(element_info: str) -> str:
Receive a `str` representing an element's symbol or
name, and returns a `str` representing the atomic symbol.
"""
if element_info.lower() in _element_names_to_symbols.keys():
if element_info.lower() in _element_names_to_symbols:
element = _element_names_to_symbols[element_info.lower()]
elif element_info in _atomic_numbers_to_symbols.values():
element = element_info
Expand Down Expand Up @@ -339,7 +344,7 @@ def _reconstruct_isotope_symbol(element: str, mass_numb: Integral) -> str:
elif isotope == "H-3":
isotope = "T"

if isotope not in _isotopes.keys():
if isotope not in _data_about_isotopes:
raise InvalidParticleError(
f"The string '{isotope}' does not correspond to "
f"a valid isotope."
Expand Down Expand Up @@ -440,10 +445,10 @@ def _reconstruct_ion_symbol(
Z = Z_from_arg

if isinstance(Z, Integral):
if Z > _elements[element]["atomic number"]:
if Z > _data_about_elements[element]["atomic number"]:
raise InvalidParticleError(
f"The charge number Z = {Z} cannot exceed the atomic number "
f"of {element}, which is {_elements[element]['atomic number']}."
f"of {element}, which is {_data_about_elements[element]['atomic number']}."
)
elif Z <= -3:
warnings.warn(
Expand All @@ -463,7 +468,7 @@ def _reconstruct_ion_symbol(
else:
symbol = element

nomenclature_dict = {
return {
"symbol": symbol,
"element": element,
"isotope": isotope,
Expand All @@ -472,8 +477,6 @@ def _reconstruct_ion_symbol(
"charge number": Z,
}

return nomenclature_dict


def _parse_and_check_molecule_input(argument: str, Z: Integral = None):
"""
Expand Down
Loading

0 comments on commit ba45c40

Please sign in to comment.