Repository: PlasmaPy/PlasmaPy

Issue:
collisions.py needs another review
The functionality in `plasmapy/formulary/collisions.py` went through an extensive review in PR #962.  However,  there are some inconsistencies between what is written in the docstrings and what is actually implemented in the associated function.  For example, the docstring for the `coupling_parameter` currently states

```restructuredtext
method : `str`, optional
        The method by which to compute the Coulomb logarithm.
        The default method is the classical straight-line Landau-Spitzer
        method (``"classical"`` or ``"ls"``). The other 6 supported methods
        are ``"ls_min_interp"``, ``"ls_full_interp"``, ``"ls_clamp_mininterp"``,
        ``"hls_min_interp"``, ``"hls_max_interp"``, and ``"hls_full_interp"``.
        Please refer to the docstring of `Coulomb_logarithm` for more
        information about these methods.
```

for the `method` keyword but the function only accepts values of `'classical'` and `'quantum'`.  Since so much was touched by PR #962, we need to read through each function and make sure the docstrings and contained functionality are consistent.

Discussion:
codecov[bot]: # [Codecov](https://codecov.io/gh/PlasmaPy/PlasmaPy/pull/1379?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PlasmaPy) Report
> Merging [#1379](https://codecov.io/gh/PlasmaPy/PlasmaPy/pull/1379?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PlasmaPy) (8b2e0bd) into [main](https://codecov.io/gh/PlasmaPy/PlasmaPy/commit/f31e2873d96466584f1af2acbf8341a342d2db83?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PlasmaPy) (f31e287) will **not change** coverage.
> The diff coverage is `n/a`.

> :exclamation: Current head 8b2e0bd differs from pull request most recent head e7f5654. Consider uploading reports for the commit e7f5654 to get more accurate results
[![Impacted file tree graph](https://codecov.io/gh/PlasmaPy/PlasmaPy/pull/1379/graphs/tree.svg?width=650&height=150&src=pr&token=LzZ5mnXVad&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PlasmaPy)](https://codecov.io/gh/PlasmaPy/PlasmaPy/pull/1379?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PlasmaPy)

```diff
@@           Coverage Diff           @@
##             main    #1379   +/-   ##
=======================================
  Coverage   97.09%   97.09%           
=======================================
  Files          75       75           
  Lines        7235     7235           
=======================================
  Hits         7025     7025           
  Misses        210      210           
```


| [Impacted Files](https://codecov.io/gh/PlasmaPy/PlasmaPy/pull/1379?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PlasmaPy) | Coverage Δ | |
|---|---|---|
| [plasmapy/formulary/collisions.py](https://codecov.io/gh/PlasmaPy/PlasmaPy/pull/1379/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PlasmaPy#diff-cGxhc21hcHkvZm9ybXVsYXJ5L2NvbGxpc2lvbnMucHk=) | `97.19% <ø> (ø)` | |

------

[Continue to review full report at Codecov](https://codecov.io/gh/PlasmaPy/PlasmaPy/pull/1379?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PlasmaPy).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PlasmaPy)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/PlasmaPy/PlasmaPy/pull/1379?src=pr&el=footer&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PlasmaPy). Last update [f31e287...e7f5654](https://codecov.io/gh/PlasmaPy/PlasmaPy/pull/1379?src=pr&el=lastupdated&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PlasmaPy). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PlasmaPy).


Patch:
diff --git a/changelog/1378.feature.rst b/changelog/1378.feature.rst
new file mode 100644
index 00000000..f6012d57
--- /dev/null
+++ b/changelog/1378.feature.rst
@@ -0,0 +1,4 @@
+Added the `~plasmapy.particles.particle_collections.ParticleList.is_category`
+method for |ParticleList| objects.  This method is analogous to the
+`~plasmapy.particles.particle_class.Particle.is_category` method for
+|Particle| objects.
diff --git a/changelog/1379.doc.rst b/changelog/1379.doc.rst
new file mode 100644
index 00000000..486c3e87
--- /dev/null
+++ b/changelog/1379.doc.rst
@@ -0,0 +1,2 @@
+Fixed the docstring of the `~plasmapy.formulary.collisions.coupling_parameter`
+function in :file:`plasmapy/formulary/collisions.py`\ .
diff --git a/plasmapy/formulary/collisions.py b/plasmapy/formulary/collisions.py
index bd2463df..703c4686 100644
--- a/plasmapy/formulary/collisions.py
+++ b/plasmapy/formulary/collisions.py
@@ -1922,15 +1922,10 @@ def coupling_parameter(
         :math:`μ` is the reduced mass.
 
     method : `str`, optional
-        The method by which to compute the Coulomb logarithm.  The
-        default method is the classical straight-line Landau-Spitzer
-        method (``"classical"`` or ``"ls"``). The other 6 supported
-        methods are ``"ls_min_interp"``, ``"ls_full_interp"``,
-        ``"ls_clamp_mininterp"``, ``"hls_min_interp"``,
-        ``"hls_max_interp"``, and ``"hls_full_interp"``.  Please refer
-        to the docstring of
-        `~plasmapy.formulary.collisions.Coulomb_logarithm` for more
-        information about these methods.
+        The method by which to compute the coupling parameter: either
+        ``"classical"`` or ``"quantum"``. The default method is ``"classical"``.
+        The Notes section of this docstring has more information about
+        these two methods.
 
     Returns
     -------
diff --git a/plasmapy/particles/particle_collections.py b/plasmapy/particles/particle_collections.py
index 6d9ac926..9ef6d43c 100644
--- a/plasmapy/particles/particle_collections.py
+++ b/plasmapy/particles/particle_collections.py
@@ -250,6 +250,46 @@ def insert(self, index, particle: ParticleLike):
             particle = Particle(particle)
         self.data.insert(index, particle)
 
+    def is_category(
+        self,
+        *category_tuple,
+        require: Union[str, Iterable[str]] = None,
+        any_of: Union[str, Iterable[str]] = None,
+        exclude: Union[str, Iterable[str]] = None,
+    ) -> List[bool]:
+        """
+        Determine element-wise if the particles in the |ParticleList|
+        meet categorization criteria.
+
+        Return a `list` in which each element will be `True` if the
+        corresponding particle is consistent with the categoziation
+        criteria, and `False` otherwise.
+
+        Please refer to the documentation of
+        `~plasmapy.particles.particle_class.Particle.is_category`
+        for information on the parameters and categories, as well as
+        more extensive examples.
+
+        Examples
+        --------
+        >>> particles = ParticleList(["proton", "electron", "tau neutrino"])
+        >>> particles.is_category("lepton")
+        [False, True, True]
+        >>> particles.is_category(require="lepton", exclude="neutrino")
+        [False, True, False]
+        >>> particles.is_category(any_of=["lepton", "charged"])
+        [True, True, True]
+        """
+        return [
+            particle.is_category(
+                *category_tuple,
+                require=require,
+                any_of=any_of,
+                exclude=exclude,
+            )
+            for particle in self
+        ]
+
     @property
     def charge_number(self) -> np.array:
         """


Test patch:
diff --git a/plasmapy/particles/tests/test_particle_collections.py b/plasmapy/particles/tests/test_particle_collections.py
index 26ca8331..c0b0b41d 100644
--- a/plasmapy/particles/tests/test_particle_collections.py
+++ b/plasmapy/particles/tests/test_particle_collections.py
@@ -327,6 +327,43 @@ def test_particle_multiplication(method, particle):
     assert particle_list == [particle, particle, particle]
 
 
+@pytest.mark.parametrize(
+    "particles, args, kwargs, expected",
+    [
+        [
+            ["electron", "proton", "neutron"],
+            ["lepton"],
+            {},
+            [True, False, False],
+        ],
+        [
+            ["electron", "proton", "neutron"],
+            [],
+            {"require": "lepton"},
+            [True, False, False],
+        ],
+        [
+            ["electron", "proton", "neutron"],
+            [],
+            {"exclude": "lepton"},
+            [False, True, True],
+        ],
+        [
+            ["electron", "proton", "neutron"],
+            [],
+            {"any_of": {"lepton", "charged"}},
+            [True, True, False],
+        ],
+    ],
+)
+def test_particle_list_is_category(particles, args, kwargs, expected):
+    """
+    Test that ``ParticleList.is_category()`` behaves as expected.
+    """
+    sample_list = ParticleList(particles)
+    assert sample_list.is_category(*args, **kwargs) == expected
+
+
 def test_mean_particle():
     """
     Test that ``ParticleList.average_particle()`` returns a particle with